Add Windows code signing setup for x64 builds (#22022)

## Summary
- Implements automated Windows code signing for x64 and x64-baseline
builds
- Integrates DigiCert KeyLocker for secure certificate management
- Adds CI/CD pipeline support for signing during builds

## Changes
- Added `.buildkite/scripts/sign-windows.sh` script for automated
signing
- Updated CMake configurations to support signing workflow
- Modified build scripts to integrate signing step

## Testing
- Script tested locally with manual signing process
- Successfully signed test binaries at:
  - `C:\Builds\bun-windows-x64\bun.exe`
  - `C:\Builds\bun-windows-x64-baseline\bun.exe`

## References
Uses DigiCert KeyLocker tools for Windows signing

## Next Steps
- Validate Buildkite environment variables in CI
- Test full pipeline in CI environment

---------

Co-authored-by: Jarred Sumner <jarred@bun.sh>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
connerlphillippi
2025-08-22 03:53:57 -07:00
committed by GitHub
parent 0e37dc4e78
commit 73fe9a4484
7 changed files with 595 additions and 6 deletions

View File

@@ -5,7 +5,9 @@ import { chmodSync, cpSync, existsSync, mkdirSync, readFileSync } from "node:fs"
import { basename, join, relative, resolve } from "node:path";
import {
formatAnnotationToHtml,
getSecret,
isCI,
isWindows,
parseAnnotations,
printEnvironment,
reportAnnotationToBuildKite,
@@ -214,14 +216,47 @@ function parseOptions(args, flags = []) {
async function spawn(command, args, options, label) {
const effectiveArgs = args.filter(Boolean);
const description = [command, ...effectiveArgs].map(arg => (arg.includes(" ") ? JSON.stringify(arg) : arg)).join(" ");
let env = options?.env;
console.log("$", description);
label ??= basename(command);
const pipe = process.env.CI === "true";
if (isBuildkite()) {
if (process.env.BUN_LINK_ONLY && isWindows) {
env ||= options?.env || { ...process.env };
// Pass signing secrets directly to the build process
// The PowerShell signing script will handle certificate decoding
env.SM_CLIENT_CERT_PASSWORD = getSecret("SM_CLIENT_CERT_PASSWORD", {
redact: true,
required: true,
});
env.SM_CLIENT_CERT_FILE = getSecret("SM_CLIENT_CERT_FILE", {
redact: true,
required: true,
});
env.SM_API_KEY = getSecret("SM_API_KEY", {
redact: true,
required: true,
});
env.SM_KEYPAIR_ALIAS = getSecret("SM_KEYPAIR_ALIAS", {
redact: true,
required: true,
});
env.SM_HOST = getSecret("SM_HOST", {
redact: true,
required: true,
});
}
}
const subprocess = nodeSpawn(command, effectiveArgs, {
stdio: pipe ? "pipe" : "inherit",
...options,
env,
});
let killedManually = false;

View File

@@ -40,7 +40,25 @@ if ($args.Count -gt 0) {
$commandArgs = @($args[1..($args.Count - 1)] | % {$_})
}
Write-Host "$ $command $commandArgs"
# Don't print the full command as it may contain sensitive information like certificates
# Just show the command name and basic info
$displayArgs = @()
foreach ($arg in $commandArgs) {
if ($arg -match "^-") {
# Include flags
$displayArgs += $arg
} elseif ($arg -match "\.(mjs|js|ts|cmake|zig|cpp|c|h|exe)$") {
# Include file names
$displayArgs += $arg
} elseif ($arg.Length -gt 100) {
# Truncate long arguments (likely certificates or encoded data)
$displayArgs += "[REDACTED]"
} else {
$displayArgs += $arg
}
}
Write-Host "$ $command $displayArgs"
& $command $commandArgs
exit $LASTEXITCODE
}