ci(windows): sign exe and installer with Azure Trusted Signing

Sign the bare .exe before the MSI is built (so the packed copy carries
the signature) and the linked .msi afterwards, via
azure/artifact-signing-action with SHA256 digests and Microsoft's
RFC3161 timestamp server. Credentials come from the AZURE_* repository
secrets.

Also fix the MSI version fallback: workflow_dispatch runs use the
branch name as ref_name, which is not a valid numeric ProductVersion,
so candle failed on any non-tag run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mojtaba Karimi 2026-06-04 12:54:40 +02:00
commit 3163a5ee75

View file

@ -78,6 +78,24 @@ jobs:
- name: Build
run: cargo build --release
- name: Sign executable (Azure Trusted Signing)
# Sign the bare .exe *before* the MSI is built so the copy packed
# into the installer carries the signature too. AZURE_CLIENT_SECRET
# authenticates the App Registration; the remaining AZURE_* secrets
# select the Trusted Signing account / certificate profile.
uses: azure/artifact-signing-action@v2
with:
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
endpoint: ${{ secrets.AZURE_ENDPOINT }}
signing-account-name: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
certificate-profile-name: ${{ secrets.AZURE_CERTIFICATE_PROFILE_NAME }}
files: ${{ github.workspace }}\target\release\OpenCADStudio.exe
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Convert SVG icon to ICO
shell: pwsh
run: |
@ -93,7 +111,10 @@ jobs:
shell: pwsh
run: |
$version = "${{ github.ref_name }}" -replace '^v', ''
if (-not $version) { $version = "0.0.0" }
# workflow_dispatch runs use the branch name as ref_name, which
# is not a valid MSI ProductVersion — fall back to 0.0.0 so test
# builds still produce an installer.
if ($version -notmatch '^\d+(\.\d+){0,3}$') { $version = "0.0.0" }
# WiX Toolset 3.x is pre-installed on windows-latest; $env:WIX
# points to the install root. candle compiles .wxs → .wixobj
# and light links it into the final .msi.
@ -120,6 +141,22 @@ jobs:
& $light $wixObj -out $msiPath
if ($LASTEXITCODE -ne 0) { throw "light failed" }
- name: Sign MSI installer (Azure Trusted Signing)
# The installer itself must be signed separately — light produces a
# fresh, unsigned .msi even though the .exe inside is already signed.
uses: azure/artifact-signing-action@v2
with:
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
endpoint: ${{ secrets.AZURE_ENDPOINT }}
signing-account-name: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }}
certificate-profile-name: ${{ secrets.AZURE_CERTIFICATE_PROFILE_NAME }}
files: ${{ github.workspace }}\OpenCADStudio.msi
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Upload artifacts to release
if: github.event_name == 'release'
shell: pwsh