Adds code signing to tagged windows builds (#4473)

**Note**: This change requires the addition of new entries in the
secrets to work properly. These should be added prior to this merging.

# Description of Changes

* Add a tag-only Windows signing job that runs on a self-hosted signing
runner.
* This is an alternative/separate code-path just for the signing job.
See **Alternatives Considered** for details.
* Skip the unsigned Windows matrix build on tags so signed artifacts are
the only Windows release outputs.
* Sign `spacetimedb-update.exe`, `spacetimedb-cli.exe`, and
`spacetimedb-standalone.exe` before packaging, then upload the signed
artifacts as usual.

# Alternatives Considered
**Inline signing in the existing Windows packaging step**. This was
rejected because it would require all Windows builds (including non-tag
builds) to run on the signing-capable runner or to install/signing
tooling on GitHub-hosted runners. The chosen approach isolates signing
to tag releases, avoids exposing credentials in standard builds, and
keeps routine CI behavior unchanged.

# API and ABI breaking changes

None

# Expected complexity level and risk

2 – low risk. CI-only change that adds a new signing job and preserves
existing artifact layout.

# Testing

- [X] None (Not running, workflow change only)

---------

Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
This commit is contained in:
Ryan
2026-03-03 15:21:09 -08:00
committed by GitHub
parent 0b30b16c2d
commit 9a1ea26e25
+89
View File
@@ -7,9 +7,12 @@ on:
branches:
- master
- release/*
permissions:
contents: read
jobs:
build-cli:
if: ${{ !(startsWith(github.ref, 'refs/tags/') && matrix.target == 'x86_64-pc-windows-msvc') }}
strategy:
fail-fast: false
matrix:
@@ -85,3 +88,89 @@ jobs:
source_dir: build
endpoint: https://nyc3.digitaloceanspaces.com
destination_dir: ${{ steps.extract_branch.outputs.branch }}
build-cli-windows-signed:
if: ${{ startsWith(github.ref, 'refs/tags/') }}
name: Build and sign CLI for x86_64 Windows
runs-on: [self-hosted, windows, signing]
environment: codesign
concurrency:
group: codesign-${{ github.ref }}
cancel-in-progress: false
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Rust
uses: dsherret/rust-toolchain-file@v1
- name: Install rust target
run: rustup target add x86_64-pc-windows-msvc
- name: Compile
run: |
cargo build --release --target x86_64-pc-windows-msvc -p spacetimedb-cli -p spacetimedb-standalone -p spacetimedb-update
- name: Write certificate file
shell: powershell
env:
DIGICERT_CERT_B64: ${{ secrets.DIGICERT_CERT_B64 }}
run: |
[IO.File]::WriteAllBytes("digicert.crt", [Convert]::FromBase64String($env:DIGICERT_CERT_B64))
- name: Sign binaries
shell: powershell
env:
DIGICERT_KEYPAIR_ALIAS: ${{ secrets.DIGICERT_KEYPAIR_ALIAS }}
run: |
$ErrorActionPreference = 'Stop'
$targetDir = Join-Path $env:GITHUB_WORKSPACE 'target\x86_64-pc-windows-msvc\release'
$certFile = Join-Path $env:GITHUB_WORKSPACE 'digicert.crt'
$signtool = Get-Command signtool.exe -ErrorAction Stop
$files = @(
(Join-Path $targetDir 'spacetimedb-update.exe'),
(Join-Path $targetDir 'spacetimedb-cli.exe'),
(Join-Path $targetDir 'spacetimedb-standalone.exe')
)
foreach ($file in $files) {
& $signtool.Path sign /csp "DigiCert Signing Manager KSP" /kc $env:DIGICERT_KEYPAIR_ALIAS /f $certFile /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 $file
& $signtool.Path verify /v /pa $file
}
- name: Package (windows)
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
New-Item -ItemType Directory -Force -Path build | Out-Null
$releaseDir = Join-Path $env:GITHUB_WORKSPACE 'target\x86_64-pc-windows-msvc\release'
Copy-Item (Join-Path $releaseDir 'spacetimedb-update.exe') (Join-Path $env:GITHUB_WORKSPACE 'build\spacetimedb-update-x86_64-pc-windows-msvc.exe')
Compress-Archive -Force -Path @(
(Join-Path $releaseDir 'spacetimedb-cli.exe'),
(Join-Path $releaseDir 'spacetimedb-standalone.exe')
) -DestinationPath (Join-Path $env:GITHUB_WORKSPACE 'build\spacetime-x86_64-pc-windows-msvc.zip')
- name: Extract branch name
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
$branch = $env:GITHUB_HEAD_REF
if ([string]::IsNullOrEmpty($branch)) {
$branch = $env:GITHUB_REF -replace '^refs/heads/', ''
}
"branch=$branch" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
id: extract_branch
- name: Upload to DO Spaces
uses: shallwefootball/s3-upload-action@master
with:
aws_key_id: ${{ secrets.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
aws_bucket: ${{ vars.AWS_BUCKET }}
source_dir: build
endpoint: https://nyc3.digitaloceanspaces.com
destination_dir: ${{ steps.extract_branch.outputs.branch }}