Follow-up to #187 (Windows arm64 build + installer, added in #188). The arm64 build works; only Velopack's code-signing step fails on the arm64 runner. Tracking the remaining work here so #187's build can ship for real.
Current state (works)
- The
win-arm64 release leg builds natively on the windows-11-arm runner:
- ✅ AOT TUI (
win-arm64/wp.dll → apphost) — also gated in PR CI (aot-publish (win-arm64))
- ✅ MAUI/WinUI3 GUI (
win-arm64/WinPrint.dll)
- The leg is
experimental: true (continue-on-error) in release.yml, so it cannot block a release — x64/macOS/Linux ship normally; the arm64 Setup.exe is simply absent until this is fixed.
The failure
Pack with Velopack → [FTL] Signing command failed. Specify --verbose argument to print signing command. with empty output. With --verbose, the command is:
...\vpk\1.1.1\vendor\signing\signtool.exe sign /fd SHA256 /tr http://timestamp.acs.microsoft.com /v /debug /td SHA256 /dlib Azure.CodeSigning.Dlib.dll /dmdf azure-trusted-signing.json <files...>
i.e. Velopack invokes its bundled x64 signtool.exe + Azure.CodeSigning.Dlib.dll, which fails on the arm64 host and writes nothing to stdout/stderr (so the real error is invisible without further probing). Same Azure Trusted Signing setup signs win-x64 fine every release, so it's specific to the arm64 runner / x64-signtool interplay. Related upstream: velopack/velopack#85.
Tried, did NOT fix it
- Added
vpk --verbose — prints the command but signtool's own output is empty.
- Installed the x64 .NET 8 runtime on the arm64 runner (
-Architecture x64 -Runtime dotnet -Channel 8.0 -InstallDir "$env:ProgramFiles\dotnet\x64") per Velopack's note that the x64 signtool/dlib need the x64 runtime — no change, identical empty-output failure. (So it isn't simply a missing x64 runtime.)
Recommended fix: cross-sign on the x64 runner
Build arm64 where it must be native, but pack + sign on the x64 runner where Velopack's bundled x64 signtool is proven:
- In the
win-arm64 (arm64-runner) leg, upload the artifacts/publish/win-arm64 directory as an artifact (currently only the velopack output is uploaded, which never gets produced).
- Add a job on
windows-latest (x64) that needs the arm64 build, downloads that publish dir, does the Azure OIDC login + metadata, runs vpk pack --runtime win-arm64 --packDir <downloaded> --channel win-arm64 ... --azureTrustedSignFile artifacts/azure-trusted-signing.json, and uploads the result. (Velopack supports cross-compiling/packing: https://docs.velopack.io/packaging/cross-compiling)
Alternative fix: arm64-native signtool via vpk --signTemplate
Keep everything on the arm64 runner but bypass Velopack's bundled x64 signtool:
- Use the arm64
signtool.exe from the Windows SDK (...\Windows Kits\10\bin\<ver>\arm64\signtool.exe).
- Use the arm64
Azure.CodeSigning.Dlib.dll from the Microsoft.Trusted.Signing.Client NuGet (bin/arm64/...).
- Pass
vpk pack ... --signTemplate '"<arm64 signtool>" sign /fd SHA256 /tr http://timestamp.acs.microsoft.com /td SHA256 /dlib "<arm64 dlib>" /dmdf "<json>" "{{file}}"' instead of --azureTrustedSignFile.
How to iterate (can't be tested locally — no Windows/arm64)
release.yml's publish/winget/brew are gated to tag pushes, so a workflow_dispatch from develop runs ONLY the build+sign matrix as a safe dry-run (no release, no tap, no winget; Azure OIDC federated creds match develop):
gh workflow run release.yml --ref develop
- Inspect the
Package win-arm64 → Pack with Velopack step.
Acceptance criteria
- A release produces a signed
Kindel.WinPrint-win-arm64-Setup.exe.
- Remove the
experimental: true flag from the win-arm64 matrix leg so it ships first-class.
- Add the arm64 installer to the winget manifest (regex already widened to
win-(x64|arm64)).
Notes / cleanup
- The non-working x64-runtime install step and the temporary
--verbose were reverted from release.yml when parking this; re-add --verbose while debugging.
- Keep the
publish tag-guard (enables the safe dispatch dry-run) and the experimental flag (keeps releases unblocked) until this is done.
Dry-run evidence: failing runs 28295536229 (v2.8.8 release leg), 28299089065 + 28299484579 (develop dispatches).
Follow-up to #187 (Windows arm64 build + installer, added in #188). The arm64 build works; only Velopack's code-signing step fails on the arm64 runner. Tracking the remaining work here so #187's build can ship for real.
Current state (works)
win-arm64release leg builds natively on thewindows-11-armrunner:win-arm64/wp.dll→ apphost) — also gated in PR CI (aot-publish (win-arm64))win-arm64/WinPrint.dll)experimental: true(continue-on-error) inrelease.yml, so it cannot block a release — x64/macOS/Linux ship normally; the arm64Setup.exeis simply absent until this is fixed.The failure
Pack with Velopack→[FTL] Signing command failed. Specify --verbose argument to print signing command.with empty output. With--verbose, the command is:i.e. Velopack invokes its bundled x64
signtool.exe+Azure.CodeSigning.Dlib.dll, which fails on the arm64 host and writes nothing to stdout/stderr (so the real error is invisible without further probing). Same Azure Trusted Signing setup signswin-x64fine every release, so it's specific to the arm64 runner / x64-signtool interplay. Related upstream: velopack/velopack#85.Tried, did NOT fix it
vpk --verbose— prints the command but signtool's own output is empty.-Architecture x64 -Runtime dotnet -Channel 8.0 -InstallDir "$env:ProgramFiles\dotnet\x64") per Velopack's note that the x64 signtool/dlib need the x64 runtime — no change, identical empty-output failure. (So it isn't simply a missing x64 runtime.)Recommended fix: cross-sign on the x64 runner
Build arm64 where it must be native, but pack + sign on the x64 runner where Velopack's bundled x64 signtool is proven:
win-arm64(arm64-runner) leg, upload theartifacts/publish/win-arm64directory as an artifact (currently only the velopack output is uploaded, which never gets produced).windows-latest(x64) thatneedsthe arm64 build, downloads that publish dir, does the Azure OIDC login + metadata, runsvpk pack --runtime win-arm64 --packDir <downloaded> --channel win-arm64 ... --azureTrustedSignFile artifacts/azure-trusted-signing.json, and uploads the result. (Velopack supports cross-compiling/packing: https://docs.velopack.io/packaging/cross-compiling)Alternative fix: arm64-native signtool via
vpk --signTemplateKeep everything on the arm64 runner but bypass Velopack's bundled x64 signtool:
signtool.exefrom the Windows SDK (...\Windows Kits\10\bin\<ver>\arm64\signtool.exe).Azure.CodeSigning.Dlib.dllfrom theMicrosoft.Trusted.Signing.ClientNuGet (bin/arm64/...).vpk pack ... --signTemplate '"<arm64 signtool>" sign /fd SHA256 /tr http://timestamp.acs.microsoft.com /td SHA256 /dlib "<arm64 dlib>" /dmdf "<json>" "{{file}}"'instead of--azureTrustedSignFile.How to iterate (can't be tested locally — no Windows/arm64)
release.yml'spublish/winget/breware gated to tag pushes, so aworkflow_dispatchfrom develop runs ONLY the build+sign matrix as a safe dry-run (no release, no tap, no winget; Azure OIDC federated creds matchdevelop):gh workflow run release.yml --ref developPackage win-arm64→Pack with Velopackstep.Acceptance criteria
Kindel.WinPrint-win-arm64-Setup.exe.experimental: trueflag from thewin-arm64matrix leg so it ships first-class.win-(x64|arm64)).Notes / cleanup
--verbosewere reverted fromrelease.ymlwhen parking this; re-add--verbosewhile debugging.publishtag-guard (enables the safe dispatch dry-run) and theexperimentalflag (keeps releases unblocked) until this is done.Dry-run evidence: failing runs 28295536229 (v2.8.8 release leg), 28299089065 + 28299484579 (develop dispatches).