Some checks failed
windows-msi / full-msi-unsigned (push) Has been cancelled
windows-msi-sign.yml.example; gofpdf register when EmbedBrandFonts and fonts present.
164 lines
7.8 KiB
YAML
164 lines
7.8 KiB
YAML
# Unsigned full elevated MSI (Product-Full.wxs + build-full-msi.ps1).
|
|
# Artifact is NOT Authenticode-signed. Sign step is commented; secret names only.
|
|
# See platform/windows/wix/CI-SIGN-NOTARY.md and platform/windows/wix/DUAL-SHIP.md § CI artifact.
|
|
name: windows-msi
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
paths:
|
|
- "platform/windows/**"
|
|
- "cmd/**"
|
|
- "internal/**"
|
|
- "go.mod"
|
|
- "go.sum"
|
|
- ".github/workflows/windows-msi.yml"
|
|
pull_request:
|
|
paths:
|
|
- "platform/windows/**"
|
|
- "cmd/**"
|
|
- "internal/**"
|
|
- "go.mod"
|
|
- "go.sum"
|
|
- ".github/workflows/windows-msi.yml"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
full-msi-unsigned:
|
|
runs-on: windows-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Install WiX Toolset v3
|
|
shell: pwsh
|
|
run: |
|
|
choco install wixtoolset --version 3.14.1 -y --no-progress
|
|
$wixBin = "${env:ProgramFiles(x86)}\WiX Toolset v3.14\bin"
|
|
if (-not (Test-Path -LiteralPath (Join-Path $wixBin "candle.exe"))) {
|
|
# Fallback: any WiX v3.* bin on Program Files
|
|
$found = Get-ChildItem -Path "${env:ProgramFiles(x86)}" -Filter "candle.exe" -Recurse -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.FullName -match 'WiX Toolset' } |
|
|
Select-Object -First 1
|
|
if ($found) { $wixBin = $found.Directory.FullName }
|
|
}
|
|
if (-not (Test-Path -LiteralPath (Join-Path $wixBin "candle.exe"))) {
|
|
Write-Error "WiX candle.exe not found after install. Full MSI job requires WiX v3."
|
|
}
|
|
"WIX_BIN=$wixBin" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
"PATH=$wixBin;$env:PATH" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
Write-Host "WiX bin: $wixBin"
|
|
& (Join-Path $wixBin "candle.exe") -?
|
|
|
|
- name: Build full MSI (unsigned)
|
|
shell: pwsh
|
|
run: |
|
|
$candle = Get-Command candle -ErrorAction SilentlyContinue
|
|
$light = Get-Command light -ErrorAction SilentlyContinue
|
|
if (-not $candle -or -not $light) {
|
|
Write-Error "WiX candle/light not on PATH — refusing unsigned MSI build (fail closed)."
|
|
}
|
|
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\build-full-msi.ps1 -Arch amd64
|
|
$msi = Get-ChildItem -Path platform\windows\wix\out -Filter "VeraePrintStamp-windows-*.msi" -ErrorAction SilentlyContinue |
|
|
Sort-Object LastWriteTime -Descending |
|
|
Select-Object -First 1
|
|
if (-not $msi) {
|
|
Write-Error "build-full-msi.ps1 did not produce VeraePrintStamp-windows-*.msi under platform/windows/wix/out"
|
|
}
|
|
Write-Host "MSI: $($msi.FullName) ($([math]::Round($msi.Length/1MB, 2)) MB)"
|
|
Get-FileHash -Algorithm SHA256 -Path $msi.FullName | Format-List
|
|
"MSI_PATH=$($msi.FullName)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
"MSI_NAME=$($msi.Name)" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
|
|
|
|
# --- Future Authenticode (NOT enabled) ---
|
|
# Wire only after certs exist in the org secret store. Never commit PFX or passwords.
|
|
# Full copy-paste example (gated if: false): .github/workflows/windows-msi-sign.yml.example
|
|
# Local dry-run (no secrets): platform/windows/scripts/sign-dry-run.ps1
|
|
# After sign + CDN upload: docs/PUBLISH-DIGESTS.md + fill-manifest-sha256.ps1
|
|
# Secret / var names (placeholders only — see CI-SIGN-NOTARY.md):
|
|
# secrets.WINDOWS_CERT_PFX_BASE64
|
|
# secrets.WINDOWS_CERT_PFX_PASSWORD
|
|
# secrets.WINDOWS_CERT_THUMBPRINT # optional /sha1 after import
|
|
# vars.WINDOWS_SIGN_TIMESTAMP_URL # RFC 3161 TSA
|
|
# secrets.WINDOWS_TRUSTED_SIGNING_TENANT_ID # Path B: Azure Trusted Signing
|
|
# secrets.WINDOWS_TRUSTED_SIGNING_CLIENT_ID
|
|
# secrets.WINDOWS_TRUSTED_SIGNING_CLIENT_SECRET # omit when OIDC id-token: write
|
|
# vars.WINDOWS_TRUSTED_SIGNING_ENDPOINT
|
|
# vars.WINDOWS_TRUSTED_SIGNING_ACCOUNT
|
|
# vars.WINDOWS_TRUSTED_SIGNING_CERTIFICATE_PROFILE
|
|
#
|
|
# --- Path A: PFX → signtool (commented; secret NAMES only) ---
|
|
# - name: Import code-signing PFX
|
|
# if: ${{ false }}
|
|
# shell: pwsh
|
|
# env:
|
|
# WINDOWS_CERT_PFX_BASE64: ${{ secrets.WINDOWS_CERT_PFX_BASE64 }}
|
|
# WINDOWS_CERT_PFX_PASSWORD: ${{ secrets.WINDOWS_CERT_PFX_PASSWORD }}
|
|
# run: |
|
|
# $pfx = Join-Path $env:RUNNER_TEMP "codesign.pfx"
|
|
# [IO.File]::WriteAllBytes($pfx, [Convert]::FromBase64String($env:WINDOWS_CERT_PFX_BASE64))
|
|
# $pwd = ConvertTo-SecureString $env:WINDOWS_CERT_PFX_PASSWORD -AsPlainText -Force
|
|
# Import-PfxCertificate -FilePath $pfx -CertStoreLocation Cert:\CurrentUser\My -Password $pwd | Out-Null
|
|
# Remove-Item -LiteralPath $pfx -Force -ErrorAction SilentlyContinue
|
|
# # Never Upload-Artifact the PFX; never echo password or base64.
|
|
#
|
|
# - name: signtool Authenticode (EXEs + MSI)
|
|
# if: ${{ false }}
|
|
# shell: pwsh
|
|
# env:
|
|
# WINDOWS_SIGN_TIMESTAMP_URL: ${{ vars.WINDOWS_SIGN_TIMESTAMP_URL }}
|
|
# WINDOWS_CERT_THUMBPRINT: ${{ secrets.WINDOWS_CERT_THUMBPRINT }}
|
|
# run: |
|
|
# $tsa = $env:WINDOWS_SIGN_TIMESTAMP_URL
|
|
# if (-not $tsa) { $tsa = "https://timestamp.digicert.com" }
|
|
# $signtool = (Get-Command signtool.exe -ErrorAction Stop).Source
|
|
# $stage = "platform\windows\wix\StageFull\bin"
|
|
# $targets = @(
|
|
# (Join-Path $stage "verae-print.exe"),
|
|
# (Join-Path $stage "verae-printhelper.exe"),
|
|
# $env:MSI_PATH
|
|
# ) | Where-Object { $_ -and (Test-Path -LiteralPath $_) }
|
|
# foreach ($t in $targets) {
|
|
# if ($env:WINDOWS_CERT_THUMBPRINT) {
|
|
# & $signtool sign /fd SHA256 /tr $tsa /td SHA256 /sha1 $env:WINDOWS_CERT_THUMBPRINT $t
|
|
# } else {
|
|
# & $signtool sign /fd SHA256 /tr $tsa /td SHA256 /a $t
|
|
# }
|
|
# if ($LASTEXITCODE -ne 0) { Write-Error "signtool sign failed: $t" }
|
|
# & $signtool verify /pa $t
|
|
# if ($LASTEXITCODE -ne 0) { Write-Error "signtool verify failed: $t" }
|
|
# }
|
|
#
|
|
# --- Path B: Azure Trusted Signing (prefer over PFX when available) ---
|
|
# - name: Azure Trusted Signing (EXEs + MSI)
|
|
# if: ${{ false }}
|
|
# # uses: azure/trusted-signing-action@v0 # pin a reviewed tag when enabling
|
|
# # with:
|
|
# # azure-tenant-id: ${{ secrets.WINDOWS_TRUSTED_SIGNING_TENANT_ID }}
|
|
# # azure-client-id: ${{ secrets.WINDOWS_TRUSTED_SIGNING_CLIENT_ID }}
|
|
# # azure-client-secret: ${{ secrets.WINDOWS_TRUSTED_SIGNING_CLIENT_SECRET }}
|
|
# # endpoint: ${{ vars.WINDOWS_TRUSTED_SIGNING_ENDPOINT }}
|
|
# # trusted-signing-account-name: ${{ vars.WINDOWS_TRUSTED_SIGNING_ACCOUNT }}
|
|
# # certificate-profile-name: ${{ vars.WINDOWS_TRUSTED_SIGNING_CERTIFICATE_PROFILE }}
|
|
# # files: ${{ env.MSI_PATH }}
|
|
# # file-digest: SHA256
|
|
# # timestamp-rfc3161: ${{ vars.WINDOWS_SIGN_TIMESTAMP_URL }}
|
|
# # timestamp-digest: SHA256
|
|
# shell: pwsh
|
|
# run: |
|
|
# Write-Error "Trusted Signing not enabled — unsigned artifact only. See windows-msi-sign.yml.example."
|
|
|
|
- name: Upload unsigned MSI artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: VeraePrintStamp-windows-msi-unsigned
|
|
path: platform/windows/wix/out/VeraePrintStamp-windows-*.msi
|
|
if-no-files-found: error
|
|
retention-days: 14
|