mirror of
https://github.com/mileswolfallen2/gelectron.git
synced 2026-09-08 12:43:16 +00:00
Add native installers (DMG/EXE/AppImage) to releases
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
; Gelectron Windows installer (NSIS)
|
||||
;
|
||||
; Build with makensis from a staging directory containing:
|
||||
; gelectron.exe
|
||||
; compat\*.js
|
||||
;
|
||||
; makensis /DVERSION=0.1.1 /DARCH=x64 Gelectron.nsi
|
||||
;
|
||||
; Installs to $PROGRAMFILES64\Gelectron, adds it to the machine PATH, creates
|
||||
; Start Menu + Add/Remove Programs entries, and writes an uninstaller.
|
||||
|
||||
!include "MUI2.nsh"
|
||||
!include "WordFunc.nsh"
|
||||
|
||||
!ifndef VERSION
|
||||
!define VERSION "0.0.0"
|
||||
!endif
|
||||
!ifndef ARCH
|
||||
!define ARCH "x64"
|
||||
!endif
|
||||
|
||||
!define APPNAME "Gelectron"
|
||||
!define COMPANY "gelectron"
|
||||
!define ENV_KEY 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
|
||||
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
|
||||
|
||||
Name "${APPNAME}"
|
||||
OutFile "Gelectron-${VERSION}-${ARCH}.exe"
|
||||
InstallDir "$PROGRAMFILES64\${APPNAME}"
|
||||
InstallDirRegKey HKLM "Software\${APPNAME}" "InstallDir"
|
||||
RequestExecutionLevel admin
|
||||
|
||||
; ── Modern UI ──────────────────────────────────────────────────────────────
|
||||
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
; ── Install section ─────────────────────────────────────────────────────────
|
||||
|
||||
Section "Install"
|
||||
SetShellVarContext all
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
File "gelectron.exe"
|
||||
File /r "compat"
|
||||
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
CreateDirectory "$SMPROGRAMS\${APPNAME}"
|
||||
CreateShortcut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\gelectron.exe"
|
||||
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${APPNAME}"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${VERSION}"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${COMPANY}"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\gelectron.exe"
|
||||
|
||||
; Add $INSTDIR to the machine PATH (add-if-not-present via WordFunc)
|
||||
ReadRegStr $0 ${ENV_KEY} "Path"
|
||||
${WordAdd} $0 ";" "+$INSTDIR" $1
|
||||
WriteRegExpandStr ${ENV_KEY} "Path" $1
|
||||
SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment"
|
||||
SectionEnd
|
||||
|
||||
; ── Uninstall section ───────────────────────────────────────────────────────
|
||||
|
||||
Section "Uninstall"
|
||||
SetShellVarContext all
|
||||
; Remove $INSTDIR from the machine PATH
|
||||
ReadRegStr $0 ${ENV_KEY} "Path"
|
||||
${WordAdd} $0 ";" "-$INSTDIR" $1
|
||||
WriteRegExpandStr ${ENV_KEY} "Path" $1
|
||||
SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment"
|
||||
|
||||
Delete "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk"
|
||||
RMDir "$SMPROGRAMS\${APPNAME}"
|
||||
|
||||
DeleteRegKey HKLM "${UNINST_KEY}"
|
||||
DeleteRegKey HKLM "Software\${APPNAME}"
|
||||
|
||||
RMDir /r "$INSTDIR"
|
||||
SectionEnd
|
||||
Executable
+142
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build the Linux AppImage: bundles the gelectron binary, the compat layer
|
||||
# and a Node.js runtime into a single self-contained, downloadable AppImage.
|
||||
#
|
||||
# Gelectron-<version>-x86_64.AppImage
|
||||
#
|
||||
# Requires: the gelectron binary (built against webkit2gtk-4.1), compat layer,
|
||||
# and network access (downloads Node.js + appimagetool).
|
||||
#
|
||||
# Usage:
|
||||
# scripts/pkg/make-appimage.sh -v VERSION [--binary PATH] [--compat DIR] [-o DIR]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
NODE_VERSION="20.18.1"
|
||||
|
||||
VERSION=""
|
||||
BINARY=""
|
||||
COMPAT="$REPO_DIR/src/electron"
|
||||
OUT_DIR="$REPO_DIR/dist"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Linux AppImage builder
|
||||
|
||||
Usage:
|
||||
scripts/pkg/make-appimage.sh -v VERSION [--binary PATH] [--compat DIR] [-o DIR]
|
||||
|
||||
Options:
|
||||
-v, --version VER Version string (e.g. 0.1.1)
|
||||
-b, --binary PATH Path to the gelectron binary
|
||||
-c, --compat DIR Path to the compat layer (default: <repo>/src/electron)
|
||||
-o, --out DIR Output directory (default: <repo>/dist)
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-v|--version) VERSION="${2:-}"; shift 2 ;;
|
||||
-b|--binary) BINARY="${2:-}"; shift 2 ;;
|
||||
-c|--compat) COMPAT="${2:-}"; shift 2 ;;
|
||||
-o|--out) OUT_DIR="${2:-}"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "error: unknown option: $1" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
VERSION="${VERSION#v}"
|
||||
[[ -n "$VERSION" ]] || { echo "error: --version required" >&2; exit 1; }
|
||||
if [[ -z "$BINARY" ]]; then
|
||||
BINARY="$REPO_DIR/target/release/gelectron"
|
||||
fi
|
||||
[[ -f "$BINARY" ]] || { echo "error: binary not found: $BINARY" >&2; exit 1; }
|
||||
[[ -d "$COMPAT" ]] || { echo "error: compat dir not found: $COMPAT" >&2; exit 1; }
|
||||
|
||||
log() { echo "==> $*"; }
|
||||
|
||||
STAGE="$(mktemp -d "${TMPDIR:-/tmp}/gelectron-appimage.XXXXXX")"
|
||||
trap 'rm -rf "$STAGE"' EXIT
|
||||
|
||||
APPDIR="$STAGE/Gelectron.AppDir"
|
||||
mkdir -p "$APPDIR/usr/bin"
|
||||
|
||||
# ── Binaries ────────────────────────────────────────────────────────────────
|
||||
|
||||
log "Staging binary..."
|
||||
install -m 755 "$BINARY" "$APPDIR/usr/bin/gelectron"
|
||||
|
||||
log "Staging compat layer (usr/bin/compat, resolved next to the binary)..."
|
||||
mkdir -p "$APPDIR/usr/bin/compat"
|
||||
install -m 644 "$COMPAT"/*.js "$APPDIR/usr/bin/compat/"
|
||||
|
||||
# Node.js runtime (gelectron's Node mode requires node on PATH)
|
||||
NODE_DIR="$STAGE/node"
|
||||
if [[ ! -d "$NODE_DIR" ]]; then
|
||||
log "Downloading Node.js v$NODE_VERSION..."
|
||||
mkdir -p "$NODE_DIR"
|
||||
NODE_ARCHIVE="$STAGE/node.tar.xz"
|
||||
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" -o "$NODE_ARCHIVE"
|
||||
tar -xJf "$NODE_ARCHIVE" -C "$NODE_DIR"
|
||||
fi
|
||||
install -m 755 "$NODE_DIR"/node-v${NODE_VERSION}-linux-x64/bin/node "$APPDIR/usr/bin/node"
|
||||
install -m 644 "$NODE_DIR"/node-v${NODE_VERSION}-linux-x64/lib/libnode.so* "$APPDIR/usr/lib/" 2>/dev/null || true
|
||||
|
||||
mkdir -p "$APPDIR/usr/lib"
|
||||
cp "$NODE_DIR"/node-v${NODE_VERSION}-linux-x64/lib/libnode.so* "$APPDIR/usr/lib/" 2>/dev/null || true
|
||||
|
||||
# ── AppImage metadata ───────────────────────────────────────────────────────
|
||||
|
||||
cat > "$APPDIR/AppRun" <<'EOF'
|
||||
#!/bin/sh
|
||||
SELF="$(dirname "$(readlink -f "$0")")"
|
||||
export PATH="$SELF/usr/bin:$PATH"
|
||||
export LD_LIBRARY_PATH="$SELF/usr/lib:${LD_LIBRARY_PATH:-}"
|
||||
export GELECTRON_NATIVE=1
|
||||
exec "$SELF/usr/bin/gelectron" "$@"
|
||||
EOF
|
||||
chmod +x "$APPDIR/AppRun"
|
||||
|
||||
cat > "$APPDIR/gelectron.desktop" <<EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Gelectron
|
||||
Comment=Firefox-engine alternative to Electron, powered by Servo
|
||||
Exec=gelectron
|
||||
Icon=gelectron
|
||||
Terminal=false
|
||||
Categories=Development;
|
||||
EOF
|
||||
|
||||
if [[ -f "$REPO_DIR/logo.png" ]]; then
|
||||
install -m 644 "$REPO_DIR/logo.png" "$APPDIR/gelectron.png"
|
||||
fi
|
||||
|
||||
# ── appimagetool ────────────────────────────────────────────────────────────
|
||||
|
||||
TOOL="$STAGE/appimagetool"
|
||||
if [[ ! -f "$TOOL" ]]; then
|
||||
log "Downloading appimagetool..."
|
||||
curl -fsSL "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" -o "$TOOL"
|
||||
fi
|
||||
chmod +x "$TOOL"
|
||||
|
||||
# ── Build ───────────────────────────────────────────────────────────────────
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
APPIMAGE_NAME="Gelectron-$VERSION-x86_64.AppImage"
|
||||
APPIMAGE_PATH="$OUT_DIR/$APPIMAGE_NAME"
|
||||
|
||||
export VERSION="$VERSION"
|
||||
export ARCH="x86_64"
|
||||
# Run appimagetool without FUSE (Ubuntu 24.04+ runners don't ship libfuse2)
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
log "Creating $APPIMAGE_NAME ..."
|
||||
"$TOOL" "$APPDIR" "$APPIMAGE_PATH" >/dev/null
|
||||
|
||||
echo
|
||||
log "Created installer: $APPIMAGE_PATH"
|
||||
sha256sum "$APPIMAGE_PATH" 2>/dev/null || shasum -a 256 "$APPIMAGE_PATH" 2>/dev/null || true
|
||||
Executable
+114
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build the macOS installer: a .pkg (installs the gelectron runtime +
|
||||
# compat layer to /usr/local/bin) wrapped in a .dmg for distribution.
|
||||
#
|
||||
# Gelectron-<version>-<arch>.dmg
|
||||
# └── Install gelectron.pkg (double-click, runs macOS Installer as root)
|
||||
#
|
||||
# Requires macOS (pkgbuild + hdiutil). Ad-hoc signing only — no Developer ID
|
||||
# certificate, so first launch shows a Gatekeeper warning on other machines.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
VERSION=""
|
||||
ARCH=""
|
||||
BINARY=""
|
||||
COMPAT="$REPO_DIR/src/electron"
|
||||
OUT_DIR="$REPO_DIR/dist"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
macOS installer builder (pkg inside DMG)
|
||||
|
||||
Usage:
|
||||
scripts/pkg/make-dmg.sh -v VERSION -a ARCH [--binary PATH] [--compat DIR] [-o DIR]
|
||||
|
||||
Options:
|
||||
-v, --version VER Version string (e.g. 0.1.1)
|
||||
-a, --arch A arm64 | x64
|
||||
-b, --binary PATH Path to the gelectron binary
|
||||
-c, --compat DIR Path to the compat layer (default: <repo>/src/electron)
|
||||
-o, --out DIR Output directory (default: <repo>/dist)
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-v|--version) VERSION="${2:-}"; shift 2 ;;
|
||||
-a|--arch) ARCH="${2:-}"; shift 2 ;;
|
||||
-b|--binary) BINARY="${2:-}"; shift 2 ;;
|
||||
-c|--compat) COMPAT="${2:-}"; shift 2 ;;
|
||||
-o|--out) OUT_DIR="${2:-}"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "error: unknown option: $1" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "$VERSION" ]] || { echo "error: --version required" >&2; exit 1; }
|
||||
VERSION="${VERSION#v}"
|
||||
[[ -n "$ARCH" ]] || { echo "error: --arch required" >&2; exit 1; }
|
||||
case "$ARCH" in arm64|x64) ;; *) echo "error: unsupported arch: $ARCH" >&2; exit 1 ;; esac
|
||||
|
||||
if [[ -z "$BINARY" ]]; then
|
||||
BINARY="$REPO_DIR/target/release/gelectron"
|
||||
fi
|
||||
[[ -f "$BINARY" ]] || { echo "error: binary not found: $BINARY" >&2; exit 1; }
|
||||
[[ -d "$COMPAT" ]] || { echo "error: compat dir not found: $COMPAT" >&2; exit 1; }
|
||||
|
||||
log() { echo "==> $*"; }
|
||||
|
||||
STAGE="$(mktemp -d "${TMPDIR:-/tmp}/gelectron-dmg.XXXXXX")"
|
||||
trap 'rm -rf "$STAGE"' EXIT
|
||||
|
||||
# ── Payload root (what pkgbuild installs into /usr/local/bin) ─────────────
|
||||
|
||||
PAYLOAD="$STAGE/gelectron"
|
||||
mkdir -p "$PAYLOAD"
|
||||
|
||||
log "Staging payload..."
|
||||
install -m 755 "$BINARY" "$PAYLOAD/gelectron"
|
||||
mkdir -p "$PAYLOAD/compat"
|
||||
install -m 644 "$COMPAT"/*.js "$PAYLOAD/compat/"
|
||||
|
||||
if command -v codesign >/dev/null 2>&1; then
|
||||
log "Ad-hoc signing binary..."
|
||||
codesign --force --sign - "$PAYLOAD/gelectron" 2>/dev/null || echo " (warning: codesign failed)"
|
||||
fi
|
||||
|
||||
# ── Component package ───────────────────────────────────────────────────────
|
||||
|
||||
PKG="$STAGE/Install gelectron.pkg"
|
||||
log "Building package (installs to /usr/local/bin)..."
|
||||
pkgbuild \
|
||||
--root "$PAYLOAD" \
|
||||
--identifier "com.gelectron.runtime.$ARCH" \
|
||||
--version "$VERSION" \
|
||||
--ownership recommended \
|
||||
--install-location /usr/local/bin \
|
||||
"$PKG"
|
||||
|
||||
# ── DMG ────────────────────────────────────────────────────────────────────
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
DMG_NAME="Gelectron-$VERSION-$ARCH.dmg"
|
||||
DMG_PATH="$OUT_DIR/$DMG_NAME"
|
||||
|
||||
DMG_STAGE="$STAGE/dmg"
|
||||
mkdir -p "$DMG_STAGE"
|
||||
cp "$PKG" "$DMG_STAGE/"
|
||||
|
||||
log "Creating $DMG_NAME ..."
|
||||
hdiutil create \
|
||||
-volname "Gelectron $VERSION" \
|
||||
-srcfolder "$DMG_STAGE" \
|
||||
-format UDZO \
|
||||
-ov \
|
||||
"$DMG_PATH" >/dev/null
|
||||
|
||||
echo
|
||||
log "Created installer: $DMG_PATH"
|
||||
shasum -a 256 "$DMG_PATH"
|
||||
@@ -0,0 +1,58 @@
|
||||
# Gelectron Windows installer builder (NSIS)
|
||||
#
|
||||
# Stages the payload and compiles the installer EXE with makensis:
|
||||
# Gelectron-<version>-<arch>.exe
|
||||
#
|
||||
# Usage:
|
||||
# powershell -File scripts/pkg/make-exe.ps1 `
|
||||
# -Bin target\release\gelectron.exe `
|
||||
# -Compat src\electron `
|
||||
# -Version 0.1.1 -Arch x64 -Out dist
|
||||
#
|
||||
# Requires makensis on PATH (install via: choco install nsis -y)
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Bin,
|
||||
[Parameter(Mandatory = $true)][string]$Compat,
|
||||
[Parameter(Mandatory = $true)][string]$Version,
|
||||
[string]$Arch = "x64",
|
||||
[string]$Out = "dist",
|
||||
[string]$NsiPath = "scripts/pkg/gelectron.nsi"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
if (-not (Get-Command makensis -ErrorAction SilentlyContinue)) {
|
||||
throw "makensis not found. Install NSIS first (choco install nsis -y)."
|
||||
}
|
||||
|
||||
$RealityVersion = $Version.TrimStart("v")
|
||||
|
||||
$Stage = Join-Path $env:TEMP ("gelectron-nsis-" + [Guid]::NewGuid().ToString("N"))
|
||||
New-Item -ItemType Directory -Path $Stage -Force | Out-Null
|
||||
try {
|
||||
Copy-Item $Bin (Join-Path $Stage "gelectron.exe") -Force
|
||||
Copy-Item -Recurse -Force $Compat (Join-Path $Stage "compat")
|
||||
Copy-Item $NsiPath (Join-Path $Stage "gelectron.nsi") -Force
|
||||
|
||||
Write-Host "==> Compiling installer (makensis)..."
|
||||
Push-Location $Stage
|
||||
try {
|
||||
& makensis "-DVERSION=$RealityVersion" "-DARCH=$Arch" gelectron.nsi
|
||||
if ($LASTEXITCODE -ne 0) { throw "makensis failed with exit code $LASTEXITCODE" }
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$Installer = Get-ChildItem $Stage -Filter "Gelectron-*.exe" | Select-Object -First 1
|
||||
if (-not $Installer) { throw "makensis produced no installer" }
|
||||
|
||||
New-Item -ItemType Directory -Path $Out -Force | Out-Null
|
||||
Copy-Item $Installer.FullName (Join-Path $Out $Installer.Name) -Force
|
||||
Write-Host ""
|
||||
Write-Host "==> Created installer: $(Join-Path $Out $Installer.Name)"
|
||||
}
|
||||
finally {
|
||||
Remove-Item -Recurse -Force $Stage -ErrorAction SilentlyContinue
|
||||
}
|
||||
Reference in New Issue
Block a user