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-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 LDFLAGS="-lwinpthread ${LDFLAGS:-}" rm -rf build dist mkdir -p dist meson setup build \ --prefix=/ \ -Dtext-frontend=true \ -Ddbus=disabled \ -Dwith-upd=false \ -Dwith-perl=false \ -Dc_link_args=-lwinpthread \ -Dcpp_link_args=-lwinpthread - 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 # show where stuff actually landed (helps debugging packaging) find dist -maxdepth 6 -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 # Find installed EXEs and plugin DLLs mapfile -t targets < <(find dist -type f \( -iname 'zoitechat*.exe' -o -ipath '*/plugins/*.dll' \) || true) if [ "${#targets[@]}" -eq 0 ]; then echo "No installed binaries/plugins found under dist/ (skipping dep harvest)" exit 0 fi # Prefer the directory that contains zoitechat.exe; otherwise fallback to dist/bin mainexe="$(printf '%s\n' "${targets[@]}" | sed 's|\\|/|g' | grep -iE '/zoitechat\.exe$' | head -n1 || true)" if [ -n "$mainexe" ]; then bindir="$(dirname "$mainexe")" else bindir="dist/bin" mkdir -p "$bindir" fi echo "Using bindir: $bindir" printf '%s\n' "${targets[@]}" for f in "${targets[@]}"; do while IFS= read -r dll; do [ -n "$dll" ] || continue cp -n "$dll" "$bindir/" || true done < <( ntldd -R "$f" 2>/dev/null \ | tr '\\' '/' \ | awk '{print $1}' \ | grep -E '^/clangarm64/(bin|lib)/.*\.dll$' \ || true ) done - name: Install Inno Setup (real ISCC, not the Chocolatey shim) shell: pwsh run: | $ErrorActionPreference = "Stop" function Find-Iscc { $candidates = @( "$env:ProgramFiles(x86)\Inno Setup 6\ISCC.exe", "$env:ProgramFiles\Inno Setup 6\ISCC.exe" ) foreach ($p in $candidates) { if (Test-Path $p) { return $p } } return $null } $iscc = Find-Iscc if (-not $iscc) { if (Get-Command winget -ErrorAction SilentlyContinue) { winget install --id JRSoftware.InnoSetup -e --accept-package-agreements --accept-source-agreements } $iscc = Find-Iscc } if (-not $iscc) { if (Get-Command choco.exe -ErrorAction SilentlyContinue) { choco install innosetup -y --no-progress } $iscc = Find-Iscc } if (-not $iscc) { throw "ISCC.exe not found after install attempts. Checked Program Files Inno Setup paths." } Write-Host "Using ISCC:" $iscc & $iscc /? "ISCC=$iscc" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - name: Build ARM64 installer shell: pwsh run: | $ErrorActionPreference = "Stop" if (-not (Test-Path "installer\zoitechat-arm64.iss")) { throw "Missing installer\zoitechat-arm64.iss in repo" } & "$env:ISCC" "installer\zoitechat-arm64.iss" - uses: actions/upload-artifact@v4 with: name: zoitechat-windows-arm64-installer path: installer\Output\ZoiteChat-ARM64-Setup.exe