Build Electron and NWJS packages #1198
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Workflow to build Electron and (if not a packaged app) NWJS packages | |
name: Build Electron and NWJS packages | |
on: | |
schedule: | |
# Nightly run at 03:39 UTC | |
- cron: '39 03 * * *' | |
workflow_dispatch: | |
inputs: | |
version: | |
description: Specific version to build like v9.9.9 (if empty, builds version in package.json) | |
required: false | |
default: '' | |
target: | |
type: choice | |
description: Do you wish to build for "release", "nightly", or "artefacts" for testing? Artefacts will appear under the workflow run. | |
required: false | |
options: | |
- release | |
- nightly | |
- artefacts | |
default: 'artefacts' | |
env: | |
INPUT_VERSION: ${{ github.event.inputs.version }} | |
INPUT_TARGET: ${{ github.event.inputs.target }} | |
CRON_LAUNCHED: ${{ github.event.schedule }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
CSC_LINK: ${{ secrets.CSC_LINK }} | |
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} | |
SSH_KEY: ${{ secrets.SSH_KEY }} | |
REF_NAME: ${{ github.ref_name }} | |
jobs: | |
Release_Linux: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-node@v4 | |
- name: Install dependencies | |
run: npm install | |
- name: Rewrite app version number and file name | |
run: | | |
chmod +x ./scripts/rewrite_app_version_number.sh | |
./scripts/rewrite_app_version_number.sh | |
# Replace -app in archive name for Electron apps | |
sed -i -E 's/(mdwiki[^-]+)-app_/\1_/g' ./www/js/init.js | |
- name: Build production code | |
run: npm run build-min | |
- name: Download archive if needed | |
run: | | |
echo "Changing to the dist directory" | |
cd dist && pwd | |
# Get archive name | |
packagedFile=$(grep -m1 'params\[.packagedFile' www/js/init.js | sed -E "s/^.+'([^']+\.zim)'.+/\1/") | |
# If packagedFile doesn't match a zim file, we don't need to download anything, so exit | |
if [[ ! $packagedFile =~ \.zim$ ]]; then | |
echo -e "\nNo zim file to download.\n" | |
exit 0 | |
fi | |
# If file doesn't exist in FS, download it | |
if [ ! -f "archives/$packagedFile" ]; then | |
# Generalize the name if cron_launched and download it | |
echo -e "\nDownloading https://download.kiwix.org/zim/$packagedFile" | |
if [[ $CRON_LAUNCHED = true ]]; then | |
packagedFileGeneric=$(sed -E 's/_[0-9-]+(\.zim)/\1/' <<<"$packagedFile") | |
wget -nv "https://download.kiwix.org/zim/$packagedFileGeneric" -O "archives/$packagedFile" | |
else | |
flavour=$(sed -E 's/^([^_]+)_.+$/\1/' <<<"$packagedFile") | |
if [[ $flavour = "mdwiki" ]]; then | |
flavour='other' | |
fi | |
wget -nv "https://mirror.download.kiwix.org/zim/$flavour/$packagedFile" -O "archives/$packagedFile" | |
fi | |
fi | |
ls archives | |
if [ -f "archives/$packagedFile" ]; then | |
echo -e "\nFile $packagedFile now available in 'archives'.\n" | |
else | |
echo -e "\nError! We could not obtain the requested archive $packagedFile!\n" | |
exit 1 | |
fi | |
- name: Build and publish 64bit | |
env: | |
USE_HARD_LINKS: false | |
run: | | |
# echo "Setting the module type to one supported by Electron in ./package.json" | |
# sed -i -E 's/("type":\s+)"module"/\1"commonjs"/' ./package.json | |
echo "Installing dependencies in dist" | |
cd dist && npm install && cd .. | |
echo "Building 64bit packages for ref_name=$REF_NAME..." | |
if [[ $REF_NAME = "main" ]]; then | |
npx electron-builder --linux AppImage:x64 AppImage:arm64 deb:x64 rpm:x64 --projectDir dist | |
else | |
npx electron-builder --linux AppImage:x64 AppImage:arm64 deb:x64 --projectDir dist | |
fi | |
- name: Build and pulblish 32bit | |
env: | |
USE_HARD_LINKS: false | |
run: | | |
echo "Changing Electron version to latest that supports 32bit Linux (18.3.15) in ./dist/package.json" | |
sed -i -E 's/("electron":\s")[^"]+/\118.3.15/' ./dist/package.json | |
echo "Installing dependencies in dist" | |
cd dist && npm install && cd .. | |
echo "Building 32bit packages for ref_name=$REF_NAME..." | |
if [[ $REF_NAME = "main" ]]; then | |
npx electron-builder --linux AppImage:ia32 deb:ia32 rpm:ia32 --projectDir dist | |
else | |
npx electron-builder --linux AppImage:ia32 --projectDir dist | |
fi | |
- name: Upload packages to Kiwix | |
if: github.ref_name == 'main' && github.event.inputs.target != 'artefacts' | |
run: | | |
echo "$SSH_KEY" > ./scripts/ssh_key | |
chmod 600 ./scripts/ssh_key | |
chmod +x ./scripts/publish_linux_packages_to_kiwix.sh | |
./scripts/publish_linux_packages_to_kiwix.sh | |
- name: Archive build artefacts | |
if: github.event.inputs.target == 'artefacts' | |
uses: actions/upload-artifact@v4 | |
with: | |
name: kiwix-js-electron_linux | |
path: | | |
dist/bld/Electron/*.AppImage | |
dist/bld/Electron/*.deb | |
dist/bld/Electron/*.rpm | |
Release_Windows: | |
runs-on: windows-latest | |
env: | |
SIGNTOOL_PATH: "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.22000.0\\x64\\signtool.exe" | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-node@v4 | |
- name: Install dependencies | |
run: npm install | |
- name: Rewrite app version number and file name | |
run: | | |
$INPUT_VERSION = $Env:INPUT_VERSION | |
$INPUT_TARGET = $Env:INPUT_TARGET | |
$CRON_LAUNCHED = $Env:CRON_LAUNCHED | |
./scripts/Rewrite-AppVersion.ps1 | |
# Replace -app in archive name for Electron apps | |
(Get-Content ./www/js/init.js) -replace '(mdwiki[^-]+)-app_', '$1_' | Set-Content -encoding 'utf8BOM' ./www/js/init.js | |
- name: Build production code | |
run: npm run build-min | |
- name: Download archive if needed | |
run: | | |
echo "Changing to the dist directory" | |
cd dist && pwd | |
$packagedFile = (Select-String 'packagedFile' "www\js\init.js" -List) -ireplace "^.+'([^']+\.zim)'.+", '$1' | |
# If packagedFile doesn't match a zim file, we don't need to download anything, so exit | |
if ($packagedFile -and ! ($packagedFile -match '\.zim$')) { | |
Write-Host "`nNo zim file to download.`n" | |
exit 0 | |
} | |
if ($packagedFile -and ! (Test-Path "archives\$packagedFile" -PathType Leaf)) { | |
# File not in archives, so generalize the name (if nightly) and download it | |
Write-Host "`nDownloading https://download.kiwix.org/zim/$packagedFile" | |
if ($CRON_LAUNCHED) { | |
$packagedFileGeneric = $packagedFile -replace '_[0-9-]+(\.zim)', '$1' | |
Invoke-WebRequest "https://download.kiwix.org/zim/$packagedFileGeneric" -OutFile "archives\$packagedFile" | |
} else { | |
$flavour = $packagedFile -replace '^([^_]+)_.+$', '$1' | |
if ($flavour -eq 'mdwiki') { | |
$flavour = 'other' | |
} | |
Invoke-WebRequest "https://mirror.download.kiwix.org/zim/$flavour/$packagedFile" -OutFile "archives\$packagedFile" | |
} | |
} | |
ls archives | |
if ($packagedFile -and (Test-Path "archives\$packagedFile" -PathType Leaf)) { | |
Write-Host "`nFile $packagedFile now available in 'archives'.`n" -ForegroundColor Green | |
} else { | |
Write-Host "`nError! We could not obtain the requested archive $packagedFile!`n" -ForegroundColor Red | |
exit 1 | |
} | |
- name: Run electron builder for Win 7/8/8.1 | |
shell: pwsh | |
run: | | |
$GITHUB_TOKEN = $Env:GITHUB_TOKEN | |
$INPUT_VERSION = $Env:INPUT_VERSION | |
$INPUT_TARGET = $Env:INPUT_TARGET | |
$CRON_LAUNCHED = $Env:CRON_LAUNCHED | |
if (-not ($Env:CRON_LAUNCHED -or ($Env:INPUT_TARGET -eq 'nightly'))) { | |
$INPUT_VERSION_E = $INPUT_VERSION -replace '^v([0-9.]+).*', '$1-E' | |
} else { | |
$INPUT_VERSION_E = $INPUT_VERSION -replace '^v', '' | |
} | |
./scripts/Rewrite-DraftReleaseTag.ps1 | |
$ORIGINAL_ELECTRON_VERSION = (Get-Content ./package.json | sls '"electron":') -replace '.*"electron"\s*:\s*"(.*)".*', '$1' | |
echo "ORIGINAL_ELECTRON_VERSION=$ORIGINAL_ELECTRON_VERSION" | Out-File $Env:GITHUB_ENV -Encoding utf8 -Append | |
echo "Setting the Electron version to the latest supporting Windows 7/8/8.1 (=22.3.25)" | |
(Get-Content ./package.json) -replace '("electron":\s+)"[\d.]+[\w\d-.]*?"', '$1"22.3.25"' | Set-Content ./package.json | |
echo "Installing dependencies in root and dist" | |
npm install && cd dist && npm install && cd .. | |
echo "Installed Electron version:$(npx electron --version)" | |
echo "Building Windows 7+ 32bit NSIS package..." | |
npm run dist-win-nsis | |
echo "Renaming Windows 7+ executable" | |
$files = @("Kiwix JS Electron", "WikiMed by Kiwix", "Wikivoyage by Kiwix") | |
foreach ($file in $files) { | |
mv "dist/bld/Electron/$file Setup*.exe" "dist/bld/Electron/$file Win7 Setup $INPUT_VERSION_E.exe" | |
mv "dist/bld/Electron/$file Setup*.exe.blockmap" "dist/bld/Electron/$file Win7 Setup $INPUT_VERSION_E.exe.blockmap" | |
} | |
ls ./dist/bld/Electron/ | |
# DEV: We did not use electron-builder to publish because we needed to change the filenames, so we need to publish to GitHub here | |
if ($INPUT_TARGET -ne 'artefacts') { | |
& ./scripts/Publish-ElectronPackages.ps1 -githubonly | |
} | |
./scripts/Rewrite-DraftReleaseTag.ps1 | |
- name: Run electron builder for Win 10/11 | |
shell: pwsh | |
run: | | |
$GITHUB_TOKEN = $Env:GITHUB_TOKEN | |
$INPUT_VERSION = $Env:INPUT_VERSION | |
$INPUT_TARGET = $Env:INPUT_TARGET | |
$CRON_LAUNCHED = $Env:CRON_LAUNCHED | |
$ORIGINAL_ELECTRON_VERSION = $Env:ORIGINAL_ELECTRON_VERSION | |
echo "Restoring original Electron version: $ORIGINAL_ELECTRON_VERSION" | |
(Get-Content ./package.json) -replace '("electron":\s+)"[\d.]+[\w\d-.]*?"', ('$1"' + $ORIGINAL_ELECTRON_VERSION + '"') | Set-Content ./package.json | |
./scripts/Rewrite-DraftReleaseTag.ps1 | |
# Set the module type to one supported by Electron | |
# (Get-Content ./package.json) -replace '("type":\s+)"module"', '$1"commonjs"' | Set-Content ./package.json | |
echo "Installing dependencies in root and dist" | |
npm install && cd dist && npm install && cd .. | |
echo "Installed Electron version:$(npx electron --version)" | |
echo "Building Windows packages..." | |
npm run publish | |
./scripts/Rewrite-DraftReleaseTag.ps1 | |
- name: Build portable Electron app | |
run: | | |
if (-not ($Env:CRON_LAUNCHED -or ($Env:INPUT_TARGET -eq 'nightly'))) { | |
$GITHUB_TOKEN = $Env:GITHUB_TOKEN | |
$INPUT_VERSION_E = $Env:INPUT_VERSION -replace '^(v[0-9.]+).*', '$1E' | |
if ($Env:INPUT_VERSION -match '-Wiki[\w]+') { | |
$INPUT_VERSION_E += $matches[0] | |
} | |
# To ensure there is enough disk space, we can delete the archive that is no longer needed | |
rm -r dist/archives | |
./scripts/Create-DraftRelease -buildonly -tag_name $INPUT_VERSION_E -portableonly -nobundle -wingetprompt N -nobranchcheck | |
} | |
- name: Publish packages | |
if: github.event.inputs.target != 'artefacts' | |
run: | | |
$SSH_KEY = $Env:SSH_KEY | |
echo "$SSH_KEY" > .\scripts\ssh_key | |
$GITHUB_TOKEN = $Env:GITHUB_TOKEN | |
$INPUT_VERSION = $Env:INPUT_VERSION | |
$INPUT_TARGET = $Env:INPUT_TARGET | |
$CRON_LAUNCHED = $Env:CRON_LAUNCHED | |
if ($Env:REF_NAME -eq "main") { | |
./scripts/Publish-ElectronPackages.ps1 -portableonly | |
} else { | |
./scripts/Publish-ElectronPackages.ps1 -portableonly -githubonly | |
} | |
- name: Archive build artefacts | |
if: github.event.inputs.target == 'artefacts' | |
uses: actions/upload-artifact@v4 | |
with: | |
name: kiwix-js-electron_windows | |
path: | | |
dist/bld/Electron/*.exe | |
dist/bld/Electron/*.appx | |
dist/bld/Electron/*.zip | |
dist/bld/Electron/nsis-web/*.exe | |
dist/bld/Electron/nsis-web/*.nsis.7z | |
Release_NWJS: | |
if: github.ref_name == 'main' | |
runs-on: windows-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-node@v4 | |
- name: Install dependencies | |
run: npm install | |
- name: Build production code | |
run: npm run build-min | |
- name: Select NWJS app | |
run: | | |
ren package.json package.json.electron | |
ren package.json.nwjs package.json | |
- name: Rewrite app version number | |
run: | | |
$INPUT_VERSION = $Env:INPUT_VERSION | |
$INPUT_TARGET = $Env:INPUT_TARGET | |
$CRON_LAUNCHED = $Env:CRON_LAUNCHED | |
./scripts/Rewrite-AppVersion.ps1 | |
cp package.json dist/package.json | |
- name: Download archive if needed | |
run: | | |
echo "Changing to the dist directory" | |
cd dist && pwd | |
$packagedFile = (Select-String 'packagedFile' "www\js\init.js" -List) -ireplace "^.+'([^']+\.zim)'.+", '$1' | |
# If packagedFile doesn't match a zim file, we don't need to download anything, so exit | |
if ($packagedFile -and ! ($packagedFile -match '\.zim$')) { | |
Write-Host "`nNo zim file to download.`n" | |
exit 0 | |
} | |
if ($packagedFile -and ! (Test-Path "archives\$packagedFile" -PathType Leaf)) { | |
# File not in archives, so generalize the name (if nightly) and download it | |
Write-Host "`nDownloading https://download.kiwix.org/zim/$packagedFile" | |
if ($CRON_LAUNCHED) { | |
$packagedFileGeneric = $packagedFile -replace '_[0-9-]+(\.zim)', '$1' | |
Invoke-WebRequest "https://download.kiwix.org/zim/$packagedFileGeneric" -OutFile "archives\$packagedFile" | |
} else { | |
$flavour = $packagedFile -replace '^([^_]+)_.+$', '$1' | |
if ($flavour -eq 'mdwiki') { | |
$flavour = 'other' | |
} | |
Invoke-WebRequest "https://mirror.download.kiwix.org/zim/$flavour/$packagedFile" -OutFile "archives\$packagedFile" | |
} | |
} | |
ls archives | |
if ($packagedFile -and (Test-Path "archives\$packagedFile" -PathType Leaf)) { | |
Write-Host "`nFile $packagedFile now available in 'archives'.`n" -ForegroundColor Green | |
} else { | |
Write-Host "`nError! We could not obtain the requested archive $packagedFile!`n" -ForegroundColor Red | |
exit 1 | |
} | |
- name: Build NWJS app | |
run: ./scripts/Build-NWJS.ps1 -only32bit | |
- name: Publish | |
if: github.event.inputs.target != 'artefacts' | |
run: | | |
$SSH_KEY = $Env:SSH_KEY | |
echo "$SSH_KEY" > .\scripts\ssh_key | |
$GITHUB_TOKEN = $Env:GITHUB_TOKEN | |
$INPUT_VERSION = $Env:INPUT_VERSION | |
$INPUT_TARGET = $Env:INPUT_TARGET | |
$CRON_LAUNCHED = $Env:CRON_LAUNCHED | |
./scripts/Publish-ElectronPackages.ps1 | |
- name: Archive build artefacts | |
if: github.event.inputs.target == 'artefacts' | |
uses: actions/upload-artifact@v4 | |
with: | |
name: kiwix-js-nwjs_windows | |
path: dist/bld/nwjs/*.zip |