Swap to azure code signing (#21116)

* Swap to azure code signing

* Update electron builder to allow building when using OIDC credentials for azure

* Try direct signing to work around hanging

* Use prod credential chain to azure signing service

* Disable signing in electron-builder for windows, since its done manually

* Remove unused azure login step

* Fix lint
This commit is contained in:
Chris Marslender
2026-07-14 10:13:08 -07:00
committed by GitHub
parent 24db9ad390
commit f8b3350ff1
10 changed files with 3451 additions and 5963 deletions
+35 -30
View File
@@ -45,6 +45,7 @@ jobs:
build:
name: Build EXE
runs-on: [windows-2022]
environment: windows-code-signing
needs:
- version
timeout-minutes: 65
@@ -110,41 +111,41 @@ jobs:
if [ -n "$SIGNING_SECRET" ]; then HAS_SIGNING_SECRET='true' ; fi
echo "HAS_SIGNING_SECRET=${HAS_SIGNING_SECRET}" >> "$GITHUB_OUTPUT"
env:
SIGNING_SECRET: "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}"
SIGNING_SECRET: "${{ secrets.AZURE_SIGNING_CLIENT_ID }}"
- name: Setup Certificate
- name: Install Azure Artifact Signing client
if: steps.check_secrets.outputs.HAS_SIGNING_SECRET
shell: bash
shell: pwsh
run: |
echo "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
$toolsDir = Join-Path $env:RUNNER_TEMP "artifact-signing-client"
New-Item -ItemType Directory -Path $toolsDir -Force | Out-Null
Push-Location $toolsDir
- name: Set signing variables
if: steps.check_secrets.outputs.HAS_SIGNING_SECRET
shell: bash
run: |
{
echo "SM_HOST=${{ secrets.SM_HOST }}"
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}"
echo "SM_CLIENT_CERT_FILE=D:/Certificate_pkcs12.p12"
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}"
echo "SM_CODE_SIGNING_CERT_SHA1_HASH=${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }}"
} >> "$GITHUB_ENV"
{
echo "C:/Program Files (x86)/Windows Kits/10/App Certification Kit"
echo "C:/Program Files (x86)/Microsoft SDKs/Windows/v10.0A/bin/NETFX 4.8 Tools"
echo "C:/Program Files/DigiCert/DigiCert One Signing Manager Tools"
} >> "$GITHUB_PATH"
Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile nuget.exe
.\nuget.exe install Microsoft.ArtifactSigning.Client -x -OutputDirectory .
- name: Setup SSM KSP on windows latest
if: steps.check_secrets.outputs.HAS_SIGNING_SECRET
shell: cmd
run: |
curl -X GET https://download.chia.net/dc/smtools-windows-x64.msi -o smtools-windows-x64.msi
msiexec /i smtools-windows-x64.msi /quiet /qn
smksp_registrar.exe list
smctl.exe keypair ls
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
smctl.exe windows certsync --keypair-alias=${{ secrets.SM_CERTKEY_ALIAS }}
$dlib = Get-ChildItem -Recurse -Filter "Azure.CodeSigning.Dlib.dll" |
Where-Object { $_.FullName -match '[\\/]x64[\\/]' } |
Select-Object -First 1
if (-not $dlib) {
throw "Azure.CodeSigning.Dlib.dll (x64) not found after installing Microsoft.ArtifactSigning.Client"
}
$metadataPath = Join-Path $toolsDir "metadata.json"
@{
Endpoint = "https://wus2.codesigning.azure.net/"
CodeSigningAccountName = "ChiaNetworkInc"
CertificateProfileName = "ChiaNetworkInc"
CorrelationId = "github-actions-$env:GITHUB_RUN_ID"
} | ConvertTo-Json | Set-Content -Path $metadataPath
Add-Content -Path $env:GITHUB_ENV -Value "AZURE_CODE_SIGNING_DLIB=$($dlib.FullName)"
Add-Content -Path $env:GITHUB_ENV -Value "AZURE_CODE_SIGNING_METADATA=$metadataPath"
Write-Output "dlib=$($dlib.FullName)"
Write-Output "metadata=$metadataPath"
Get-Content $metadataPath
Pop-Location
- name: Get latest madmax plotter
env:
@@ -228,6 +229,10 @@ jobs:
shell: pwsh
env:
HAS_SIGNING_SECRET: ${{ steps.check_secrets.outputs.HAS_SIGNING_SECRET }}
# prod chain: EnvironmentCredential / WorkloadIdentity (not Azure CLI).
AZURE_TOKEN_CREDENTIALS: ${{ steps.check_secrets.outputs.HAS_SIGNING_SECRET && 'prod' || '' }}
AZURE_TENANT_ID: ${{ steps.check_secrets.outputs.HAS_SIGNING_SECRET && secrets.AZURE_SIGNING_TENANT_ID || '' }}
AZURE_CLIENT_ID: ${{ steps.check_secrets.outputs.HAS_SIGNING_SECRET && secrets.AZURE_SIGNING_CLIENT_ID || '' }}
run: |
$env:path="C:\Program` Files\Microsoft` Visual` Studio\2022\Enterprise\SDK\ScopeCppSDK\vc15\VC\bin\;$env:path"
$env:path="C:\Program` Files` (x86)\Windows` Kits\10\App` Certification` Kit;$env:path"
+98 -22
View File
@@ -65,7 +65,7 @@ $packageName = "Chia-$packageVersion"
Write-Output "packageName is $packageName"
Write-Output " ---"
Write-Output "fix version in package.json"
Write-Output "npm version in package.json"
choco install jq
cp package.json package.json.orig
jq --arg VER "$env:CHIA_SEMVER_VERSION" '.version=$VER' package.json > temp.json
@@ -73,42 +73,118 @@ rm package.json
mv temp.json package.json
Write-Output " ---"
# Signing is done with signtool /dlib after packaging. electron-builder signing is
# disabled via win.signtoolOptions.sign=null in electron-builder.json.
$env:CSC_IDENTITY_AUTO_DISCOVERY = "false"
function Request-AzureFederatedToken {
# prod credential chain needs AZURE_FEDERATED_TOKEN_FILE (not Azure CLI).
# Request a fresh GitHub OIDC token immediately before signing so it does not expire
# during the long pyinstaller / electron-builder packaging steps above.
if (-not $env:ACTIONS_ID_TOKEN_REQUEST_URL -or -not $env:ACTIONS_ID_TOKEN_REQUEST_TOKEN) {
throw "ACTIONS_ID_TOKEN_REQUEST_URL/TOKEN not available; ensure permissions.id-token: write is set"
}
if (-not $env:AZURE_TENANT_ID -or -not $env:AZURE_CLIENT_ID) {
throw "AZURE_TENANT_ID and AZURE_CLIENT_ID must be set for AZURE_TOKEN_CREDENTIALS=prod"
}
$tokenUrl = "$($env:ACTIONS_ID_TOKEN_REQUEST_URL)&audience=api://AzureADTokenExchange"
$headers = @{ Authorization = "Bearer $($env:ACTIONS_ID_TOKEN_REQUEST_TOKEN)" }
$response = Invoke-RestMethod -Uri $tokenUrl -Headers $headers -Method GET
if (-not $response.value) {
throw "Failed to obtain GitHub OIDC token for Azure federated credential"
}
$tokenFile = Join-Path $env:RUNNER_TEMP "azure-federated-token"
Set-Content -Path $tokenFile -Value $response.value -NoNewline
$env:AZURE_FEDERATED_TOKEN_FILE = $tokenFile
Write-Output "Wrote Azure federated token to $tokenFile"
}
function Invoke-AzureArtifactSigning {
param(
[Parameter(Mandatory = $true)]
[string]$FilePath
)
if (-not $env:AZURE_CODE_SIGNING_DLIB -or -not (Test-Path $env:AZURE_CODE_SIGNING_DLIB)) {
throw "AZURE_CODE_SIGNING_DLIB is not set or does not exist: $env:AZURE_CODE_SIGNING_DLIB"
}
if (-not $env:AZURE_CODE_SIGNING_METADATA -or -not (Test-Path $env:AZURE_CODE_SIGNING_METADATA)) {
throw "AZURE_CODE_SIGNING_METADATA is not set or does not exist: $env:AZURE_CODE_SIGNING_METADATA"
}
Write-Output "Signing $FilePath"
signtool.exe sign /v /fd SHA256 /tr "http://timestamp.acs.microsoft.com" /td SHA256 `
/dlib $env:AZURE_CODE_SIGNING_DLIB `
/dmdf $env:AZURE_CODE_SIGNING_METADATA `
$FilePath
if ($LASTEXITCODE -ne 0) {
throw "Azure Artifact Signing failed for $FilePath with exit code $LASTEXITCODE"
}
}
Write-Output " ---"
Write-Output "electron-builder create package directory"
Write-Output " ---"
& "$NPM_PATH/electron-builder.ps1" --version
& "$NPM_PATH/electron-builder.ps1" build --win --x64 --config.productName="Chia" --dir --config ../../../build_scripts/electron-builder.json
if ($LASTEXITCODE -ne 0) {
throw "electron-builder package-directory build failed with exit code $LASTEXITCODE"
}
Get-ChildItem dist\win-unpacked\resources
Write-Output " ---"
If ($env:HAS_SIGNING_SECRET) {
Write-Output " ---"
Write-Output "Sign all EXEs"
Get-ChildItem ".\dist\win-unpacked" -Recurse | Where-Object { $_.Extension -eq ".exe" } | ForEach-Object {
$exePath = $_.FullName
Write-Output "Signing $exePath"
signtool.exe sign /sha1 $env:SM_CODE_SIGNING_CERT_SHA1_HASH /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 $exePath
Write-Output "Verify signature"
signtool.exe verify /v /pa $exePath
}
} Else {
Write-Output "Skipping verify signatures - no authorization to install certificates"
Write-Output " ---"
Write-Output "Sign all EXEs with Azure Artifact Signing"
Write-Output " ---"
Request-AzureFederatedToken
Get-ChildItem ".\dist\win-unpacked" -Recurse -File |
Where-Object { $_.Extension -eq ".exe" } |
ForEach-Object {
Invoke-AzureArtifactSigning -FilePath $_.FullName
Write-Output "Verify signature"
signtool.exe verify /v /pa $_.FullName
if ($LASTEXITCODE -ne 0) {
throw "Signature verification failed for $($_.FullName)"
}
}
} Else {
Write-Output "Skipping signing/verify - no authorization for Azure Artifact Signing"
}
Write-Output " ---"
Write-Output "electron-builder create installer"
Write-Output " ---"
& "$NPM_PATH/electron-builder.ps1" build --win --x64 --config.productName="Chia" --pd ".\dist\win-unpacked" --config ../../../build_scripts/electron-builder.json --publish never
if ($LASTEXITCODE -ne 0) {
throw "electron-builder installer build failed with exit code $LASTEXITCODE"
}
Write-Output " ---"
$installerPath = ".\dist\ChiaSetup-$packageVersion.exe"
If ($env:HAS_SIGNING_SECRET) {
Write-Output " ---"
Write-Output "Sign Final Installer App"
signtool.exe sign /sha1 $env:SM_CODE_SIGNING_CERT_SHA1_HASH /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 .\dist\ChiaSetup-$packageVersion.exe
Write-Output " ---"
Write-Output "Verify signature"
Write-Output " ---"
signtool.exe verify /v /pa .\dist\ChiaSetup-$packageVersion.exe
} Else {
Write-Output "Skipping verify signatures - no authorization to install certificates"
Write-Output " ---"
Write-Output "Sign Final Installer App"
Write-Output " ---"
Request-AzureFederatedToken
Invoke-AzureArtifactSigning -FilePath $installerPath
Write-Output " ---"
Write-Output "Verify final installer signature"
Write-Output " ---"
signtool.exe verify /v /pa $installerPath
if ($LASTEXITCODE -ne 0) {
throw "Signature verification failed for $installerPath"
}
$signature = Get-AuthenticodeSignature $installerPath
$signature | Select-Object Status, StatusMessage
$signature.SignerCertificate | Select-Object Subject, Issuer, Thumbprint, NotBefore, NotAfter
} Else {
Write-Output "Skipping signing/verify - no authorization for Azure Artifact Signing"
}
Write-Output " ---"
@@ -116,7 +192,7 @@ Write-Output "Moving final installers to expected location"
Write-Output " ---"
Copy-Item ".\dist\win-unpacked" -Destination "$env:GITHUB_WORKSPACE\chia-blockchain-gui\Chia-win32-x64" -Recurse
mkdir "$env:GITHUB_WORKSPACE\chia-blockchain-gui\release-builds\windows-installer" -ea 0
Copy-Item ".\dist\ChiaSetup-$packageVersion.exe" -Destination "$env:GITHUB_WORKSPACE\chia-blockchain-gui\release-builds\windows-installer"
Copy-Item $installerPath -Destination "$env:GITHUB_WORKSPACE\chia-blockchain-gui\release-builds\windows-installer"
Write-Output " ---"
Write-Output "Windows Installer complete"
+1 -1
View File
@@ -20,7 +20,7 @@
"icon": "src/assets/img/chia.ico",
"executableName": "Chia",
"signtoolOptions": {
"timeStampServer": "http://timestamp.comodoca.com"
"sign": null
}
},
"nsis": {
+1098 -2086
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -10,6 +10,6 @@
"author": "",
"license": "ISC",
"dependencies": {
"electron-builder": "^26.7.0"
"electron-builder": "^26.15.6"
}
}
+1091 -1712
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -11,6 +11,6 @@
"license": "ISC",
"dependencies": {
"dmg-license": "^1.0.11",
"electron-builder": "^26.7.0"
"electron-builder": "^26.15.6"
}
}
+1119 -2109
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -10,6 +10,6 @@
"author": "",
"license": "ISC",
"dependencies": {
"electron-builder": "^26.7.0"
"electron-builder": "^26.15.6"
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"name": "chia-blockchain",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}