From 6a2c3b06c8f421fbacef22c7308fd376b2060e1f Mon Sep 17 00:00:00 2001 From: James Maes Date: Sat, 10 Oct 2026 15:23:32 -0500 Subject: [PATCH] ci(release-velopack): sign only unsigned binaries, drive vpk signing through a wrapper, verify before packaging The first real `sign: true` run (gclo v1.0.2-beta.2) hit the signing action's 300 s default timeout: the step signed every exe/dll under publish, ~285 files in a self-contained publish, 239 of which already carried Microsoft/.NET signatures. A step now selects the binaries without a valid signature and passes them through the action's `files` input (third-party signatures are preserved, nothing is signed twice), with `timeout: 1800`. vpk's built-in `--azureTrustedSignFile` path hung for over ten minutes on nine files in local testing; vpk now calls a `--signTemplate` wrapper that uses the SignTool and Artifact Signing client the signing step installed, with the Azure CLI login, and skips already-signed files. A verification step runs `signtool verify /pa /all` on Setup.exe and every exe/dll in the portable zip before anything is drafted. Reproduced locally end to end with gclo's publish output and the live kof22signing account: 48 of 287 files signed in 192 s, vpk pack with the wrapper in 36 s, Setup.exe/Update.exe/app signed and timestamped, 0 unsigned libraries left. Closes #26 Co-Authored-By: Claude Fable 5.1 Signed-off-by: James Maes --- .github/workflows/release-velopack.yml | 75 ++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release-velopack.yml b/.github/workflows/release-velopack.yml index 41fed39..52ba0fe 100644 --- a/.github/workflows/release-velopack.yml +++ b/.github/workflows/release-velopack.yml @@ -336,9 +336,29 @@ jobs: tenant-id: ${{ vars.AZURE_TENANT_ID }} subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }} - # Signs the app's own executables and DLLs (and the CLI) before packing, so the - # binaries inside the installer, the portable zip, and the update packages are - # all signed (K22-REL-05). + # Signs the executables and DLLs under publish that carry no valid signature + # yet (the app's own binaries and unsigned third-party ones), so the binaries + # inside the installer, the portable zip and the update packages are all + # signed (K22-REL-05). Already-signed files (the .NET runtime, Windows App SDK) + # keep their publisher's signature and are not re-signed: a self-contained + # publish holds ~300 of them at ~2 s each, which is how the first real run + # (gclo v1.0.2-beta.2, #26) hit the signing action's 300 s default timeout. + - name: Select the binaries to sign + if: inputs.sign + id: sign-list + shell: pwsh + env: + K22_MAIN_EXE: ${{ inputs.main-exe }} + K22_CLI_PROJECT: ${{ inputs.cli-project }} + run: | + $all = Get-ChildItem publish -Recurse -Include *.exe, *.dll + $unsigned = @($all | Where-Object { (Get-AuthenticodeSignature -LiteralPath $_.FullName).Status -ne 'Valid' }) + $names = $unsigned | ForEach-Object { $_.Name } + if ($names -notcontains $env:K22_MAIN_EXE) { throw "publish/app/$env:K22_MAIN_EXE is missing or already signed by someone else." } + if ($env:K22_CLI_PROJECT -and -not ($unsigned | Where-Object { $_.Extension -eq '.exe' -and $_.FullName -like '*\publish\cli\*' })) { throw 'publish/cli has no unsigned exe to sign.' } + Write-Output "Signing $($unsigned.Count) of $($all.Count) binaries; $($all.Count - $unsigned.Count) already carry a valid signature." + "files<.json, plus a releases..json feed trimmed to this build's # packages (the local feed may also list the downloaded baseline). -- 2.54.0