mirror of
https://github.com/kiwix/kiwix-js-pwa.git
synced 2025-08-03 19:38:36 -04:00
318 lines
14 KiB
PowerShell
318 lines
14 KiB
PowerShell
# This script is intended to be run by Create-DraftRelease, and must be dot-sourced (run with `. ./Build-Electron.ps1` or `. /path/to/Build-Electron.ps1`)
|
|
# because it modifies variables needed in Create-DraftRelease
|
|
$base_dir = "$PSScriptRoot/../dist/bld/Electron/" -replace 'scripts/../', ''
|
|
if (!$skipsigning -and !$buildstorerelease) {
|
|
$Env:INPUT_SIGN = $true
|
|
if (!$Env:SIGNTOOL_PATH) {
|
|
# We need to use a newer version of singtool than that provided in electron-builder
|
|
$Env:SIGNTOOL_PATH = "C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe"
|
|
}
|
|
} else {
|
|
$Env:INPUT_SIGN = $false
|
|
$Env:ESIGNER_USERNASME = ""
|
|
$Env:ESIGNER_PASSWORD = ""
|
|
$Env:SIGNTOOL_PATH = ""
|
|
}
|
|
"`nSelected base_tag: $base_tag"
|
|
if ($electronbuild -eq "") {
|
|
""
|
|
$electronbuild_check = Read-Host "Do you want to build Electron packages on GitHub instead of locally? [Y/N]"
|
|
$electronbuild_check = -Not ( $electronbuild_check -imatch 'n' )
|
|
if ($electronbuild_check) {
|
|
"`nSelecting cloud build"
|
|
$electronbuild = 'cloud'
|
|
} else {
|
|
"`nSelecting local build"
|
|
$electronbuild = 'local'
|
|
}
|
|
}
|
|
$release_name = $release_tag_name
|
|
if ($original_release_tag_name) {
|
|
$release_name = $original_release_tag_name
|
|
}
|
|
if ($electronbuild -eq "cloud") {
|
|
$branch_name = &{ git branch --show-current }
|
|
"Setting the build branch to: $branch_name"
|
|
$release_uri = 'https://api.github.com/repos/kiwix/kiwix-js-pwa/actions/workflows/build-electron.yml/dispatches'
|
|
# Set up dispatch_params object - for API see https://docs.github.com/en/rest/reference/actions#create-a-workflow-dispatch-event
|
|
$dispatch_params = @{
|
|
Uri = $release_uri
|
|
Method = 'POST'
|
|
Headers = @{
|
|
'Authorization' = "token $github_token"
|
|
'Accept' = 'application/vnd.github.v3+json'
|
|
}
|
|
Body = @{
|
|
'ref' = $branch_name
|
|
'inputs' = @{
|
|
'target' = 'release'
|
|
'version' = $release_name
|
|
'sign' = 'true'
|
|
}
|
|
} | ConvertTo-Json
|
|
ContentType = "application/json"
|
|
}
|
|
|
|
$dispatch_f = ($dispatch_params | Format-List | Out-String);
|
|
"`nDispatch parameters:`n$dispatch_f"
|
|
|
|
# Post to the release server
|
|
if (-Not $dryrun) {
|
|
Invoke-RestMethod @dispatch_params
|
|
"`nCheck for any error message above. An empty dispatch is normal, and indicates that the command was accepted.`n"
|
|
} else {
|
|
"[DRYRUN]: Cloudbuild dispatched.`n"
|
|
}
|
|
}
|
|
# Package installer electron app for Windows
|
|
"`nChecking for installer package for Windows..."
|
|
$alt_tag = $text_tag -ireplace 'Windows', 'Electron'
|
|
$comp_electron_archive = $base_dir + "Kiwix-JS-Electron-$base_tag.zip"
|
|
$unpacked_folder = $base_dir + "win-ia32-unpacked"
|
|
$WinInstaller = $base_dir + "Kiwix JS $alt_tag Setup $numeric_tag-E.exe"
|
|
$winAppx = $base_dir + "Kiwix JS $alt_tag $numeric_tag-E.appx"
|
|
if ($alt_tag -imatch 'WikiMed|Wikivoyage') {
|
|
$comp_electron_archive = $base_dir + "$text_tag-by-Kiwix-$base_tag.zip"
|
|
$WinInstaller = $base_dir + "$alt_tag by Kiwix Setup $numeric_tag-E.exe"
|
|
$winAppx = $base_dir + "$alt_tag by Kiwix $numeric_tag-E.appx"
|
|
}
|
|
if ($electronbuild -eq "local") {
|
|
if (-Not $dryrun) {
|
|
if ($zim -imatch '^mdwiki_') {
|
|
# Rewrite the archive for Electron if it is an mdwiki type
|
|
(Get-Content ./dist/www/js/init.js) -replace '(mdwiki[^-]+)-app_', '$1_' | Set-Content -encoding 'utf8BOM' ./dist/www/js/init.js
|
|
# Delete the unneeded archive, so it doesn't get packaged
|
|
if (Test-Path ./dist/archives/mdwiki*-app*.zim) {
|
|
rm ./dist/archives/mdwiki*-app*.zim
|
|
}
|
|
}
|
|
} else {
|
|
"[DRYRUN]: Rewriting the archive for Electron if it is an mdwiki type"
|
|
"[DRYRUN]: In case we are in an mdwiki app, delete the unneeded archive, so it doesn't get packaged"
|
|
}
|
|
# Set the module type to one supported by Electron
|
|
# (Get-Content ./package.json) -replace '("type":\s+)"module"', '$1"commonjs"' | Set-Content ./package.json
|
|
"`nRewriting values in package.json for Electron appx build"
|
|
$package_json = Get-Content ./package.json
|
|
$package_json_obj = $package_json | ConvertFrom-Json
|
|
$PublisherIDs = (Get-Content ./PublisherIDs.json) | ConvertFrom-Json
|
|
# If we're not signing, we must be building for the Store, so we need to change publisher ID in the dist package.json
|
|
$package_json_name = $package_json_obj.name
|
|
# Get the correct publisher ID record
|
|
if ($skipsigning -or $buildstorerelease) {
|
|
"Using Microsoft publisher ID"
|
|
$PublisherIds_record = $PublisherIDs.$package_json_name.publishers.Microsoft
|
|
} else {
|
|
"Using Kiwix publisher ID"
|
|
$PublisherIds_record = $PublisherIDs.$package_json_name.publishers.Kiwix
|
|
}
|
|
# Set the publisher ID fields in package.json
|
|
$package_json_obj.build.appx.publisherDisplayName = $PublisherIds_record.publisherDisplayName
|
|
$package_json_obj.build.appx.identityName = $PublisherIds_record.identityName
|
|
$package_json_obj.build.appx.displayName = $PublisherIds_record.displayName
|
|
$package_json_obj.build.appx.publisher = $PublisherIds_record.publisher
|
|
# Write the modified package.json to the dist folder
|
|
$package_json = $package_json_obj | ConvertTo-Json -Depth 100
|
|
if (-Not $dryrun) {
|
|
$package_json | Set-Content ./dist/package.json
|
|
} else {
|
|
"[DRYRUN]: Writing the modified package.json to the dist folder"
|
|
}
|
|
|
|
}
|
|
if ($electronbuild -eq "local" -and (-not $portableonly)) {
|
|
if ($winonly -eq "appx") {
|
|
$WinInstaller = $winAppx
|
|
}
|
|
if (-Not (Test-Path $WinInstaller -PathType Leaf)) {
|
|
"`nNo existing Electron package found: building $WinInstaller..."
|
|
if (-Not $dryrun) {
|
|
echo "`nInstalling dependencies in dist..."
|
|
cd dist; npm install; cd ..
|
|
echo "`nBuilding Windows packages..."
|
|
if ($winonly -eq "appx") {
|
|
"[Only building the appx package because -winonly appx was specified]"
|
|
if ($skipsigning -or $buildstorerelease) {
|
|
"Building unsigned appx package..."
|
|
powershell.exe -Command "npx electron-builder build --config ../scripts/electronBuilder.cjs --win appx --publish never --projectDir dist"
|
|
} else {
|
|
# There is a bug in electron-builder that prevents discovery of the appx signing certificate if running in PS Core
|
|
# So we need to run the command in Windows PowerShell. See electron-userland/electron-builder#7729 and #8055
|
|
powershell.exe -Command "npx electron-builder --win appx --projectDir dist"
|
|
}
|
|
} else {
|
|
if ($skipsigning -or $buildstorerelease) {
|
|
powershell.exe -Command "npx electron-builder build --config ../scripts/electronBuilder.cjs --win --publish never --projectDir dist"
|
|
} else {
|
|
npm run dist-win
|
|
}
|
|
}
|
|
if (Test-Path $WinInstaller -PathType Leaf) {
|
|
Write-Host "Successfully built." -ForegroundColor Green
|
|
} else {
|
|
Write-Host "Oh no! The Windows Electron build failed!" -ForegroundColor Red
|
|
"Could not find $WinInstaller..."
|
|
}
|
|
}
|
|
} else {
|
|
Write-Host "Existing Electron package $winInstaller found." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
# Build appxbundle from appx
|
|
if ($electronbuild -eq "local" -and (-not $portableonly) -and $winAppx -and ($skipsigning -or $buildstorerelease) -and (Test-Path $winAppx -PathType Leaf)) {
|
|
"`nBuilding appxbundle from appx..."
|
|
$winAppxBundle = $winAppx + "bundle"
|
|
$appxBundleDir = $base_dir + "appxbundle"
|
|
if (-Not $dryrun) {
|
|
mkdir $appxBundleDir
|
|
mv $winAppx $appxBundleDir
|
|
& "C:\Program Files (x86)\Windows Kits\10\bin\x64\makeappx.exe" bundle /d $appxBundleDir /p $winAppxbundle
|
|
} else {
|
|
"[DRYRUN]: & 'C:\Program Files (x86)\Windows Kits\10\bin\x64\makeappx.exe' bundle /d $appxBundleDir /p $winAppxbundle"
|
|
}
|
|
}
|
|
# Build portable app if not in cloud
|
|
if (-Not (($electronbuild -eq 'cloud') -or $old_windows_support -or (Test-Path $comp_electron_archive -PathType Leaf) -or ($winonly -eq "appx"))) {
|
|
# Package portable electron app for Windows
|
|
"`nBuilding portable Electron app for Windows"
|
|
"Compressing release package for Electron..."
|
|
$foldername = "kiwix-js-pwa-win32-ia32"
|
|
$compressed_assets_dir = $base_dir + $foldername
|
|
# Find the executable filename in the folder
|
|
$executable = (ls "$unpacked_folder/*.exe") -replace '^.*[/\\]([^/\\]+)$', '$1'
|
|
"Processing executable: $executable"
|
|
# Rename the compressed assets folder
|
|
if (-Not $dryrun) {
|
|
if (Test-Path $compressed_assets_dir -PathType Container) {
|
|
rm -r $compressed_assets_dir
|
|
}
|
|
# PowerShell bug: you have to make the directory before you can cleanly copy another folder's contents into it!
|
|
mkdir $compressed_assets_dir
|
|
cp -r "$unpacked_folder\*" $compressed_assets_dir
|
|
}
|
|
"Creating launchers..."
|
|
$launcherStub = "$base_dir\Start Kiwix JS Electron"
|
|
# Batch file
|
|
$batch = '@cd "' + $foldername + '"' + "`r`n" + '@start "Kiwix JS Electron" "' + $executable + '"' + "`r`n"
|
|
if ($text_tag -match 'WikiMed|Wikivoyage') {
|
|
$launcherStub = "$base_dir\Start $text_tag by Kiwix"
|
|
$batch = '@cd "' + $foldername + '"' + "`r`n" + '@start "' + $text_tag + ' by Kiwix" "' + $executable + '"' + "`r`n"
|
|
}
|
|
if (-Not $dryrun) {
|
|
$batch > "$launcherStub.bat"
|
|
# Shortcut
|
|
$WshShell = New-Object -ComObject WScript.Shell
|
|
$Shortcut = $WshShell.CreateShortcut("$launcherStub.lnk")
|
|
$Shortcut.TargetPath = '%windir%\explorer.exe'
|
|
$Shortcut.Arguments = "$foldername\$executable"
|
|
$Shortcut.IconLocation = '%windir%\explorer.exe,12'
|
|
$Shortcut.Save()
|
|
} else {
|
|
"Would have written batch file:"
|
|
"$batch"
|
|
}
|
|
$AddAppPackage = $base_dir + "Start*Kiwix*.*"
|
|
"Compressing: $AddAppPackage, $compressed_assets_dir to $comp_electron_archive"
|
|
if (-Not $dryrun) { "$AddAppPackage", "$compressed_assets_dir" | Compress-Archive -DestinationPath $comp_electron_archive -Force }
|
|
}
|
|
if ($electronbuild -eq "local" -and (-not $portableonly) -and (-not $winonly)) {
|
|
# Package Electron app for Linux
|
|
"`nChecking for Electron packages for Linux..."
|
|
$LinuxBasePackage = $base_dir + "Kiwix JS $alt_tag-$numeric_tag-E"
|
|
if ($alt_tag -imatch 'Wikivoyage|WikiMed') {
|
|
$LinuxBasePackage = $base_dir + "$alt_tag by Kiwix-$numeric_tag-E"
|
|
}
|
|
$DebBasePackage = $base_dir + $package_name + "_$numeric_tag-E"
|
|
$RPMBasePackage = $base_dir + $package_name + "-$numeric_tag-E"
|
|
$AppImageArchives = @("$LinuxBasePackage.AppImage", ($LinuxBasePackage + "-i386.AppImage"),
|
|
("$DebBasePackage" + "_i386.deb"), ("$DebBasePackage" + "_amd64.deb"))
|
|
if ($alt_tag -notmatch 'WikiMed|Wikivoyage') {
|
|
$RPMArchives = @("$RPMBasePackage.x86_64.rpm", "$RPMBasePackage.i686.rpm");
|
|
$AppImageArchives += $RPMArchives
|
|
}
|
|
|
|
"Processing $AppImageArchives"
|
|
$run_dist_linux = $false
|
|
foreach ($AppImageArchive in $AppImageArchives) {
|
|
if (-Not (Test-Path $AppImageArchive -PathType Leaf)) {
|
|
"No packages found: building $AppImageArchive..."
|
|
$repo_dir = ($PSScriptRoot -replace '[\\/]scripts[\\/]*$', '')
|
|
# Although you can build with an electron builder docker image, on Windows it is easier to build with Windows Subsystem for Linux
|
|
# Below are commands for using docker, for info
|
|
# Ensure docker is running, or, to start it programmatically, you might need to run below commands as admin:
|
|
# net stop com.docker.service
|
|
# taskkill /IM "Docker Desktop.exe" /F
|
|
# net start com.docker.service
|
|
# runas /noprofile /user:Administrator "net stop com.docker.service; taskkill /IM 'Docker Desktop.exe' /F; net start com.docker.service"
|
|
# "Using docker command:"
|
|
# "docker run -v $repo_dir\:/project -w /project electronuserland/builder npm run dist-linux"
|
|
"Will use electron-builder in wsl"
|
|
$run_dist_linux = $true
|
|
} else {
|
|
"Linux Electron package $AppImageArchive is available"
|
|
}
|
|
}
|
|
if (-not $dryrun -and $run_dist_linux) {
|
|
# docker run -v $repo_dir\:/project -w /project electronuserland/builder npm run dist-linux
|
|
cd $repo_dir
|
|
rm -r $base_dir/linux-unpacked
|
|
rm -r $base_dir/linux-ia32-unpacked
|
|
wsl bash -ic "echo 'Installing dependencies in dist...' && cd dist && npm install && cd .. && echo 'Building Linux packages...' && npm run dist-linux"
|
|
# Alternatively build with docker
|
|
# docker $build_command
|
|
}
|
|
}
|
|
if ($electronbuild -eq "local" -and !$dryrun) {
|
|
# Set the module type back to native modules
|
|
# (Get-Content ./package.json) -replace '("type":\s+)"commonjs"', '$1"module"' | Set-Content ./package.json
|
|
}
|
|
if ($old_windows_support -and ($electronbuild -eq 'local')) {
|
|
"`nSupport for XP and Vista was requested."
|
|
"Searching for archives..."
|
|
$nwjs_base = "$PSScriptRoot/../dist"
|
|
"NWJS base directory: " + $nwjs_base
|
|
$nwjs_archives_path = "$nwjs_base/bld/nwjs/kiwix_js_windows*$numeric_tag" + "N-win-ia32.zip"
|
|
"NWJS archives path: " + $nwjs_archives_path
|
|
$nwjs_archives = dir $nwjs_archives_path
|
|
if (-Not ($nwjs_archives.count -eq 2)) {
|
|
"`nBuilding portable 32bit NWJS archives to add to Electron release for XP and Vista..."
|
|
"Updating Build-NWJS script with required tags..."
|
|
del "$PSScriptRoot/../dist/package.json"
|
|
cp "$PSScriptRoot/../package.json.nwjs" "$nwjs_base/package.json"
|
|
$nw_json = Get-Content -Raw "$nwjs_base/package.json"
|
|
$script_body = Get-Content -Raw ("$PSScriptRoot/Build-NWJS.ps1")
|
|
$json_nwVersion = ''
|
|
if ($nw_json -match '"build":\s*\{[^"]*"nwVersion":\s*"([^"]+)') {
|
|
$json_nwVersion = $matches[1]
|
|
}
|
|
if ($json_nwVersion) {
|
|
"Updating Build-NWJS with NWJS version from package.json: $json_nwVersion"
|
|
$script_body = $script_body -ireplace '(\$version10\s*=\s*")[^"]+', "`${1}$json_nwVersion"
|
|
}
|
|
$script_body = $script_body -ireplace '(appBuild\s*=\s*")[^"]+', ("`${1}$numeric_tag" + "N")
|
|
$script_body = $script_body -replace '\s+$', "`n"
|
|
if ($dryrun) {
|
|
"[DRYRUN] would have written:`n"
|
|
$script_body
|
|
} else {
|
|
Set-Content "$PSScriptRoot/Build-NWJS.ps1" $script_body
|
|
}
|
|
if (-Not $dryrun) {
|
|
"`nBuilding..."
|
|
& $PSScriptRoot/Build-NWJS.ps1 -only32bit
|
|
} else {
|
|
"Build command: $PSScriptRoot/Build-NWJS.ps1 -only32bit"
|
|
}
|
|
"Verifying build..."
|
|
$nwjs_archives = dir $nwjs_archives_path
|
|
if ($nwjs_archives.count -eq 2) {
|
|
"NWJS packages were correclty built."
|
|
$found = $true
|
|
} else {
|
|
"Oh no! The NWJS package build failed."
|
|
}
|
|
} else {
|
|
"NWJS packages found."
|
|
$found = $true
|
|
}
|
|
} |