Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 174 additions & 2 deletions .github/workflows/build-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ on:
required: false
default: false
type: boolean
windows_sign:
description: "Sign Windows winget bundle (requires Windows SM_* signing secrets)"
required: false
default: false
type: boolean

concurrency:
# SHA is added to the end if on `main` to let all main workflows run
Expand All @@ -39,6 +44,14 @@ jobs:
CHIA_ENABLE_AVX512_IFMA: "1"
# On release workflows, pin embedded CLI version to the tag.
RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || '' }}
# Keep Windows bundle/sign targets in one place.
WINDOWS_BUNDLE_EXE_FILES: |-
vdf_client.exe
vdf_bench.exe
hw_vdf_client.exe
emu_hw_vdf_client.exe
hw_test.exe
emu_hw_test.exe
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -227,6 +240,38 @@ jobs:
if: matrix.os == 'windows-latest'
run: powershell -ExecutionPolicy Bypass -File scripts/get-libft4222.ps1 install

- name: Test for Windows signing secrets
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1'
id: check_windows_signing_secrets
shell: pwsh
env:
SM_CLIENT_CERT_FILE_B64: "${{ secrets.SM_CLIENT_CERT_FILE_B64 }}"
SM_API_KEY: "${{ secrets.SM_API_KEY }}"
SM_CLIENT_CERT_PASSWORD: "${{ secrets.SM_CLIENT_CERT_PASSWORD }}"
SM_CODE_SIGNING_CERT_SHA1_HASH: "${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }}"
SM_CERTKEY_ALIAS: "${{ secrets.SM_CERTKEY_ALIAS }}"
run: |
$required = @(
"SM_CLIENT_CERT_FILE_B64",
"SM_API_KEY",
"SM_CLIENT_CERT_PASSWORD",
"SM_CODE_SIGNING_CERT_SHA1_HASH",
"SM_CERTKEY_ALIAS"
)
$missing = @()
foreach ($name in $required) {
$value = [Environment]::GetEnvironmentVariable($name)
if ([string]::IsNullOrWhiteSpace($value)) {
$missing += $name
}
}
if ($missing.Count -eq 0) {
"HAS_WINDOWS_SIGNING_SECRET=true" | Out-File -Append -FilePath $env:GITHUB_OUTPUT
} else {
Write-Host "Windows signing disabled. Missing secrets: $($missing -join ', ')"
"HAS_WINDOWS_SIGNING_SECRET=false" | Out-File -Append -FilePath $env:GITHUB_OUTPUT
}

- name: Build on Windows
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1'
shell: pwsh
Expand Down Expand Up @@ -402,6 +447,111 @@ jobs:
.\vdf_bench.exe square_asm 2000000
if ($LASTEXITCODE -ne 0) { throw "vdf_bench failed with exit code $LASTEXITCODE" }

- name: Assemble Windows zip bundle
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1'
shell: pwsh
env:
INSTALLER_VERSION: "${{ github.event_name == 'release' && github.event.release.tag_name || format('0.0.1-{0}', github.run_id) }}"
REQUEST_WINDOWS_SIGNING: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.windows_sign == 'true') }}
HAS_WINDOWS_SIGNING_SECRET: ${{ steps.check_windows_signing_secrets.outputs.HAS_WINDOWS_SIGNING_SECRET || '' }}
run: |
$baseName = "chiavdf-$env:INSTALLER_VERSION-windows-amd64"
$bundleRoot = "dist/windows/$baseName"
$binDir = "$bundleRoot/bin"
$libDir = "$bundleRoot/lib"
New-Item -ItemType Directory -Force -Path $binDir, $libDir | Out-Null

if ($env:REQUEST_WINDOWS_SIGNING -eq "true" -and $env:HAS_WINDOWS_SIGNING_SECRET -ne "true") {
throw "Windows signing was requested but signing secrets (SM_*) are not configured."
}

$exeFiles = @($env:WINDOWS_BUNDLE_EXE_FILES -split "`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ })
if (-not $exeFiles -or $exeFiles.Count -eq 0) {
throw "WINDOWS_BUNDLE_EXE_FILES is empty; expected one or more executable names."
}
foreach ($exe in $exeFiles) {
$source = "build/$exe"
if (-not (Test-Path $source)) {
throw "Missing expected binary: $source"
}
Copy-Item $source -Destination $binDir -Force
}

$ftdiDlls = Get-ChildItem "src/hw/libft4222" -Filter "*.dll" -File -ErrorAction Stop
foreach ($dll in $ftdiDlls) {
Copy-Item $dll.FullName -Destination $libDir -Force
}
$mpirDlls = Get-ChildItem "mpir_gc_x64" -Filter "*.dll" -File -ErrorAction Stop
foreach ($dll in $mpirDlls) {
Copy-Item $dll.FullName -Destination $libDir -Force
}

if ($env:REQUEST_WINDOWS_SIGNING -ne "true") {
Write-Host "Windows signing not requested; publishing unsigned Windows bundle"
}

- name: Setup Windows signer tooling
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1' && steps.check_windows_signing_secrets.outputs.HAS_WINDOWS_SIGNING_SECRET == 'true' && (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.windows_sign == 'true'))
uses: chia-network/actions/digicert/windows-sign@main
with:
sm_certkey_alias: ${{ secrets.SM_CERTKEY_ALIAS }}
sm_api_key: ${{ secrets.SM_API_KEY }}
sm_client_cert_file_b64: ${{ secrets.SM_CLIENT_CERT_FILE_B64 }}
sm_client_cert_password: ${{ secrets.SM_CLIENT_CERT_PASSWORD }}
sm_code_signing_cert_sha1_hash: ${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }}
sign: "false"
Comment thread
cmmarslender marked this conversation as resolved.

- name: Sign Windows bundled executables
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1' && steps.check_windows_signing_secrets.outputs.HAS_WINDOWS_SIGNING_SECRET == 'true' && (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.windows_sign == 'true'))
shell: pwsh
env:
INSTALLER_VERSION: "${{ github.event_name == 'release' && github.event.release.tag_name || format('0.0.1-{0}', github.run_id) }}"
SM_CODE_SIGNING_CERT_SHA1_HASH: "${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }}"
run: |
$binDir = "dist/windows/chiavdf-$env:INSTALLER_VERSION-windows-amd64/bin"
$exeFiles = @($env:WINDOWS_BUNDLE_EXE_FILES -split "`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ })
if (-not $exeFiles -or $exeFiles.Count -eq 0) {
throw "WINDOWS_BUNDLE_EXE_FILES is empty; expected one or more executable names."
}
foreach ($exe in $exeFiles) {
$file = Join-Path $binDir $exe
if (-not (Test-Path $file)) {
throw "Missing expected executable for signing: $file"
}
& signtool.exe sign /sha1 "$env:SM_CODE_SIGNING_CERT_SHA1_HASH" /tr "http://timestamp.digicert.com" /td SHA256 /fd SHA256 "$file"
if ($LASTEXITCODE -ne 0) {
throw "signtool sign failed for $file with exit code $LASTEXITCODE"
}
& signtool.exe verify /v /pa "$file"
if ($LASTEXITCODE -ne 0) {
throw "signtool verify failed for $file with exit code $LASTEXITCODE"
}
}

- name: Package Windows zip bundle
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1'
shell: pwsh
env:
INSTALLER_VERSION: "${{ github.event_name == 'release' && github.event.release.tag_name || format('0.0.1-{0}', github.run_id) }}"
IS_RELEASE: ${{ github.event_name == 'release' && 'true' || 'false' }}
run: |
$baseName = "chiavdf-$env:INSTALLER_VERSION-windows-amd64"
$bundleRoot = "dist/windows/$baseName"
if (-not (Test-Path $bundleRoot)) {
throw "Missing expected bundle directory: $bundleRoot"
}
$assetName = "$baseName.zip"
$assetPath = "dist/windows/$assetName"
Compress-Archive -Path $bundleRoot -DestinationPath $assetPath -Force
$assetHash = (Get-FileHash -Path $assetPath -Algorithm SHA256).Hash.ToLowerInvariant()
Set-Content -Path "$assetPath.sha256" -Value $assetHash -NoNewline

if ($env:IS_RELEASE -eq "true") {
$wingetAssetPath = "dist/windows/chiavdf-win64.zip"
Copy-Item $assetPath -Destination $wingetAssetPath -Force
Set-Content -Path "$wingetAssetPath.sha256" -Value $assetHash -NoNewline
}

- name: Assemble macOS brew bundle
if: startsWith(matrix.os, 'macos') && matrix.config == 'optimized=1'
env:
Expand Down Expand Up @@ -661,6 +811,15 @@ jobs:
src/hw/libft4222/*.lib
mpir_gc_x64/*.dll

- name: Upload Windows bundle artifact
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1'
uses: actions/upload-artifact@v6
with:
name: windows-amd64-bundle
path: |
dist/windows/*.zip
dist/windows/*.sha256

- name: Assemble Ubuntu .deb (same runner as build)
if: startsWith(matrix.os, 'ubuntu') && matrix.config == 'optimized=1'
env:
Expand Down Expand Up @@ -726,6 +885,19 @@ jobs:
"$RELEASE_TAG" \
"${release_files[@]}"

- name: Upload Windows release artifacts
if: matrix.os == 'windows-latest' && matrix.config == 'optimized=1' && github.event_name == 'release'
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
$releaseFiles = Get-ChildItem "dist/windows" -File | Where-Object { $_.Extension -in ".zip", ".sha256" } | ForEach-Object { $_.FullName }
if (-not $releaseFiles -or $releaseFiles.Count -eq 0) {
throw "No Windows release artifacts found to upload"
}
& gh release upload --clobber $env:RELEASE_TAG @releaseFiles

trigger-repo-update:
name: Trigger repo update
runs-on: ubuntu-latest
Expand All @@ -745,13 +917,13 @@ jobs:
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
set -euo pipefail
JSON_DATA="$(jq -nc --arg release_version "$RELEASE_TAG" '{release_version:$release_version}')"
JSON_DATA="$(jq -nc --arg release_version "$RELEASE_TAG" --arg windows_amd64 "chiavdf-win64.zip" '{release_version:$release_version,windows_amd64:$windows_amd64}')"
echo "json_data=${JSON_DATA}" >> "$GITHUB_OUTPUT"

- name: Trigger repo update
uses: Chia-Network/actions/github/glue@main
with:
json_data: '{"release_version":"${{ github.event.release.tag_name }}"}'
json_data: ${{ steps.brew_metadata.outputs.json_data }}
glue_url: ${{ secrets.GLUE_API_URL }}
glue_project: "chiavdf"
glue_path: "trigger"
Loading