mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-10 07:50:19 +00:00
Updated Windows ARM64 build workflow to include Python and CFFI installation, modified paths for Inno Setup, and added error handling for missing files.
321 lines
11 KiB
YAML
321 lines
11 KiB
YAML
name: Windows ARM64 Installer (MSYS2 + Inno Setup)
|
|
|
|
on:
|
|
push:
|
|
branches: [master]
|
|
pull_request:
|
|
branches: [master]
|
|
|
|
jobs:
|
|
windows_arm64_installer:
|
|
runs-on: windows-11-arm
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: msys2/setup-msys2@v2
|
|
with:
|
|
msystem: CLANGARM64
|
|
update: true
|
|
install: >-
|
|
git
|
|
mingw-w64-clang-aarch64-toolchain
|
|
mingw-w64-clang-aarch64-meson
|
|
mingw-w64-clang-aarch64-ninja
|
|
mingw-w64-clang-aarch64-pkgconf
|
|
mingw-w64-clang-aarch64-gettext-tools
|
|
mingw-w64-clang-aarch64-libxml2
|
|
mingw-w64-clang-aarch64-winpthreads
|
|
mingw-w64-clang-aarch64-python
|
|
mingw-w64-clang-aarch64-python-cffi
|
|
mingw-w64-clang-aarch64-gtk2
|
|
mingw-w64-clang-aarch64-gtk-update-icon-cache
|
|
mingw-w64-clang-aarch64-luajit
|
|
mingw-w64-clang-aarch64-desktop-file-utils
|
|
mingw-w64-clang-aarch64-ntldd
|
|
|
|
- name: Configure
|
|
shell: msys2 {0}
|
|
run: |
|
|
set -euxo pipefail
|
|
export PATH="/clangarm64/bin:$PATH"
|
|
|
|
export MSGFMT="/clangarm64/bin/msgfmt"
|
|
export GETTEXTDATADIR="/clangarm64/share/gettext"
|
|
|
|
# Defensive: ensure python + cffi exist even if the setup action had a bad day
|
|
pacman -S --noconfirm --needed mingw-w64-clang-aarch64-python mingw-w64-clang-aarch64-python-cffi
|
|
|
|
rm -rf build dist
|
|
mkdir -p dist
|
|
|
|
meson setup build \
|
|
--prefix=/ \
|
|
--bindir=bin \
|
|
--libdir=lib \
|
|
--datadir=share \
|
|
-Dtext-frontend=true \
|
|
-Ddbus=disabled \
|
|
-Dwith-upd=false \
|
|
-Dwith-perl=false \
|
|
-Dc_link_args="-pthread -lwinpthread" \
|
|
-Dcpp_link_args="-pthread -lwinpthread"
|
|
|
|
/clangarm64/bin/python.exe -c "import sys, cffi; print('python:', sys.version); print('cffi:', cffi.__version__)"
|
|
|
|
# Export app version from Meson for the Inno script defines
|
|
APPVER="$(meson introspect build --projectinfo | /clangarm64/bin/python.exe -c 'import json,sys; print(json.load(sys.stdin)[\"version\"])')"
|
|
echo "APPVER=$APPVER" >> "$GITHUB_ENV"
|
|
echo "Meson APPVER=$APPVER"
|
|
|
|
- name: Build
|
|
shell: msys2 {0}
|
|
run: |
|
|
set -euxo pipefail
|
|
export PATH="/clangarm64/bin:$PATH"
|
|
ninja -C build
|
|
|
|
- name: Test
|
|
shell: msys2 {0}
|
|
run: |
|
|
set -euxo pipefail
|
|
export PATH="/clangarm64/bin:$PATH"
|
|
ninja -C build test || true
|
|
|
|
- name: Stage install
|
|
shell: msys2 {0}
|
|
run: |
|
|
set -euxo pipefail
|
|
export PATH="/clangarm64/bin:$PATH"
|
|
|
|
DESTDIR="$PWD/dist" ninja -C build install
|
|
|
|
echo "Installed files (debug):"
|
|
find dist -maxdepth 8 -type f \( -iname 'zoitechat*.exe' -o -iname '*.dll' \) -print || true
|
|
|
|
- name: Harvest runtime DLL dependencies
|
|
shell: msys2 {0}
|
|
run: |
|
|
set -euxo pipefail
|
|
export PATH="/clangarm64/bin:$PATH"
|
|
shopt -s nullglob
|
|
|
|
mapfile -t targets < <(find dist -type f \( -iname 'zoitechat*.exe' -o -ipath '*/plugins/*.dll' \) 2>/dev/null || true)
|
|
|
|
if [ "${#targets[@]}" -eq 0 ]; then
|
|
echo "No installed binaries/plugins found under dist/ (skipping dep harvest)"
|
|
exit 0
|
|
fi
|
|
|
|
mainexe="$(printf '%s\n' "${targets[@]}" | grep -iE '/zoitechat\.exe$' | head -n1 || true)"
|
|
if [ -z "$mainexe" ]; then
|
|
echo "zoitechat.exe not found under dist/; skipping dep harvest"
|
|
exit 0
|
|
fi
|
|
|
|
bindir="$(dirname "$mainexe")"
|
|
echo "Using bindir: $bindir"
|
|
|
|
for f in "${targets[@]}"; do
|
|
deps="$(ntldd -R "$f" 2>/dev/null || true)"
|
|
[ -n "$deps" ] || continue
|
|
|
|
while IFS= read -r dll; do
|
|
[ -n "$dll" ] || continue
|
|
cp -n "$dll" "$bindir/" || true
|
|
done < <(
|
|
printf '%s\n' "$deps" \
|
|
| tr '\\' '/' \
|
|
| awk '{print $1}' \
|
|
| grep -E '^/clangarm64/(bin|lib)/.*\.dll$' \
|
|
|| true
|
|
)
|
|
done
|
|
|
|
- name: Prepare Inno Setup source tree (win32/rel)
|
|
shell: msys2 {0}
|
|
run: |
|
|
set -euxo pipefail
|
|
export PATH="/clangarm64/bin:$PATH"
|
|
|
|
rm -rf win32/rel
|
|
mkdir -p win32/rel
|
|
|
|
app_exe="$(find dist -type f -iname 'zoitechat.exe' | head -n1 || true)"
|
|
if [ -z "$app_exe" ]; then
|
|
echo "zoitechat.exe not found under dist/; cannot build installer."
|
|
find dist -maxdepth 8 -type f -print || true
|
|
exit 1
|
|
fi
|
|
|
|
bin_dir="$(dirname "$app_exe")"
|
|
install_root="$(cd "$bin_dir/.." && pwd)"
|
|
|
|
echo "app_exe: $app_exe"
|
|
echo "install_root: $install_root"
|
|
|
|
cp -a "$install_root/." win32/rel/
|
|
|
|
echo "win32/rel contents (debug):"
|
|
find win32/rel -maxdepth 5 -type f \( -iname 'zoitechat*.exe' -o -iname '*.dll' \) -print || true
|
|
|
|
- name: Install Inno Setup (find real ISCC.exe)
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
if (-not (Get-Command choco.exe -ErrorAction SilentlyContinue)) {
|
|
Write-Host "Chocolatey not found; installing..."
|
|
Set-ExecutionPolicy Bypass -Scope Process -Force
|
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
|
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
|
}
|
|
|
|
choco install innosetup -y --force --no-progress | Out-Host
|
|
|
|
$candidates = @()
|
|
|
|
$pf = ${env:ProgramFiles}
|
|
$pfx86 = ${env:ProgramFiles(x86)}
|
|
if ($pf) { $candidates += (Join-Path $pf "Inno Setup 6\ISCC.exe") }
|
|
if ($pfx86) { $candidates += (Join-Path $pfx86 "Inno Setup 6\ISCC.exe") }
|
|
|
|
$chocoRoot = ${env:ChocolateyInstall}
|
|
if ($chocoRoot -and (Test-Path $chocoRoot)) {
|
|
$candidates += (Join-Path $chocoRoot "lib\innosetup\tools\ISCC.exe")
|
|
$candidates += (Get-ChildItem -Path (Join-Path $chocoRoot "lib\innosetup") -Recurse -Filter "ISCC.exe" -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.FullName -notmatch '\\chocolatey\\bin\\' } |
|
|
Select-Object -ExpandProperty FullName -First 10)
|
|
}
|
|
|
|
$regKeys = @(
|
|
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1",
|
|
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1"
|
|
)
|
|
foreach ($k in $regKeys) {
|
|
try {
|
|
$loc = (Get-ItemProperty -Path $k -ErrorAction Stop).InstallLocation
|
|
if ($loc) { $candidates += (Join-Path $loc "ISCC.exe") }
|
|
} catch {}
|
|
}
|
|
|
|
$iscc = $candidates | Where-Object { $_ -and (Test-Path $_) } | Select-Object -First 1
|
|
if (-not $iscc) {
|
|
Write-Host "Checked candidates:"
|
|
$candidates | ForEach-Object { Write-Host " - $_" }
|
|
throw "ISCC.exe not found after install attempts."
|
|
}
|
|
|
|
Write-Host "Using ISCC:" $iscc
|
|
(Get-Item $iscc).VersionInfo | Select-Object ProductVersion, FileVersion | Format-List | Out-Host
|
|
|
|
"ISCC_PATH=$iscc" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
|
|
- name: Patch ARM64 .iss for CI (disable missing idp.iss)
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$issIn = "win32\installer\zoitechat-arm64.iss"
|
|
if (-not (Test-Path $issIn)) {
|
|
throw "Missing: $issIn"
|
|
}
|
|
|
|
$projectDir = (Resolve-Path "win32\installer").Path
|
|
# double trailing backslash avoids Windows arg-quoting weirdness, and still works as a path
|
|
$projectDirArg = ($projectDir.TrimEnd('\') + "\\")
|
|
"PROJECTDIR=$projectDirArg" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
|
|
$text = Get-Content $issIn -Raw
|
|
|
|
# Comment out the IDP include (it isn't present on the runner; and IDP plugin support on ARM64 is not reliable)
|
|
$text = [regex]::Replace($text, '^\s*#include\s+<idp\.iss>\s*$', '; CI: idp.iss disabled for ARM64 builds', 'Multiline')
|
|
|
|
if ($text -notmatch '; CI: IDP STUBS') {
|
|
$stub = @"
|
|
; CI: IDP STUBS (no-op on ARM64 CI)
|
|
procedure idpDownloadAfter(PageID: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure idpClearFiles;
|
|
begin
|
|
end;
|
|
|
|
procedure idpAddFile(const Url, DestFile: string);
|
|
begin
|
|
end;
|
|
|
|
procedure idpAddFileComp(const Url, DestFile: string; const Components: string);
|
|
begin
|
|
end;
|
|
|
|
procedure idpAddFileSize(const Url, DestFile: string; const Size: Int64);
|
|
begin
|
|
end;
|
|
|
|
procedure idpAddFileSizeComp(const Url, DestFile: string; const Size: Int64; const Components: string);
|
|
begin
|
|
end;
|
|
|
|
function idpDownloadFiles: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
"@
|
|
|
|
# Inject stubs immediately after the [Code] header (so [Setup] stays first)
|
|
$text = [regex]::Replace($text, '(\[Code\]\s*\r?\n)', "`$1$stub", 'Singleline')
|
|
}
|
|
|
|
$issOut = "win32\installer\zoitechat-arm64.ci.iss"
|
|
Set-Content -Path $issOut -Value $text -Encoding UTF8
|
|
Write-Host "Wrote patched CI script: $issOut"
|
|
|
|
- name: Build ARM64 installer
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$iscc = $env:ISCC_PATH
|
|
if (-not $iscc -or -not (Test-Path $iscc)) {
|
|
throw "ISCC_PATH missing or invalid."
|
|
}
|
|
|
|
$iss = "win32\installer\zoitechat-arm64.ci.iss"
|
|
if (-not (Test-Path $iss)) {
|
|
throw "Patched CI script missing: $iss"
|
|
}
|
|
|
|
if (-not $env:APPVER) {
|
|
throw "APPVER missing (Meson version export failed)."
|
|
}
|
|
if (-not $env:PROJECTDIR) {
|
|
throw "PROJECTDIR missing."
|
|
}
|
|
|
|
& $iscc "/DAPPARCH=arm64" "/DAPPVER=$env:APPVER" "/DPROJECTDIR=$env:PROJECTDIR" $iss | Out-Host
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "ISCC failed with exit code $LASTEXITCODE"
|
|
}
|
|
|
|
$exe = Get-ChildItem -Path "win32" -Recurse -Filter "*.exe" |
|
|
Where-Object { $_.Name -match 'Setup' -or $_.Name -match 'Installer' } |
|
|
Sort-Object LastWriteTime -Descending |
|
|
Select-Object -First 1
|
|
|
|
if (-not $exe) {
|
|
Write-Host "win32 tree (debug):"
|
|
Get-ChildItem -Path "win32" -Recurse -Depth 4 | Select-Object FullName | Out-Host
|
|
throw "Installer exe not found under win32/"
|
|
}
|
|
|
|
Write-Host "Installer built:" $exe.FullName
|
|
"INSTALLER_EXE=$($exe.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: zoitechat-windows-arm64-installer
|
|
path: ${{ env.INSTALLER_EXE }}
|