fix(ci): the signing dlib skips the imds probe that hangs hosted runners

This commit is contained in:
ethernet 2026-08-09 17:02:13 -04:00
parent 657cc38805
commit 4c885c4902
2 changed files with 53 additions and 24 deletions

View File

@ -37,8 +37,53 @@ function isMachO(file) {
return MACHO_MAGICS.has(buf.readUInt32BE(0))
}
// Windows signing with Azure Trusted Signing. Composed here, not as
// -c.win.sign.* CLI arguments, for two reasons: the publisherName holds
// spaces and commas that do not survive cmd.exe argument hops, and
// additionalMetadata.ExcludeCredentials is an ARRAY, which dot-notation
// cannot express. This file loads inside the electron-builder process,
// so the values pass from the environment verbatim.
//
// ExcludeCredentials keeps only AzureCliCredential — the one azure/login
// (OIDC) prepares in CI. The dlib otherwise walks the full
// DefaultAzureCredential chain, and on GitHub-hosted runners (Azure VMs)
// the ManagedIdentityCredential probe reaches a live IMDS endpoint that
// never grants a token — observed as signtool hanging on the arm64
// runners.
function windowsSigning() {
if (!process.env.AZURE_SIGN_ENDPOINT || !process.env.AZURE_CLIENT_ID) {
return {}
}
return {
sign: {
type: "azure",
endpoint: process.env.AZURE_SIGN_ENDPOINT,
codeSigningAccountName: process.env.AZURE_SIGN_ACCOUNT,
certificateProfileName: process.env.AZURE_SIGN_PROFILE,
publisherName: process.env.AZURE_SIGN_PUBLISHER,
additionalMetadata: {
ExcludeCredentials: [
"EnvironmentCredential",
"WorkloadIdentityCredential",
"ManagedIdentityCredential",
"SharedTokenCacheCredential",
"VisualStudioCredential",
"VisualStudioCodeCredential",
"AzurePowerShellCredential",
"AzureDeveloperCliCredential",
"InteractiveBrowserCredential",
],
},
},
}
}
module.exports = {
...build,
win: {
...build.win,
...windowsSigning(),
},
mac: {
...build.mac,
sign: {

View File

@ -1,6 +1,5 @@
// Wraps the electron-builder CLI so config that cannot ride through cmd.exe
// argument hops (Windows signing values with spaces) is composed here, in the
// first spawn with no shell in between.
// Wraps the electron-builder CLI so the arguments compose in one place, in
// the first spawn with no shell in between.
//
// electron-builder downloads and extracts Electron itself (via electronVersion
// + ELECTRON_MIRROR). Earlier revisions passed -c.electronDist to reuse the
@ -50,28 +49,13 @@ if (!args.includes("--publish") && !args.some((a) => a.startsWith("-p"))) {
args.push("--publish", "never")
}
// Windows signing config is composed HERE, from the AZURE_SIGN_* variables,
// not passed down as -c arguments. The publisherName contains spaces and
// commas, and no quoting survives the cmd.exe hops between the outer build
// script, npm's lifecycle spawn, and this script. This spawn is the first
// one with no shell in between, so values pass through verbatim.
// (win.sign.type=azure is the 27.x schema; 26.x called it azureSignOptions.
// 27 signs through signtool /dlib from the winCodeSign 1.3.0 toolset — no
// PowerShell TrustedSigning module, which froze the arm64 CI runner.)
if (
args.includes("--win") &&
process.env.AZURE_SIGN_ENDPOINT &&
process.env.AZURE_CLIENT_ID &&
!args.some((a) => a.includes("win.sign"))
) {
// Windows signing config lives in electron-builder.config.cjs, composed from
// the AZURE_SIGN_* variables. It cannot ride through -c arguments: the
// publisherName contains spaces and commas that die in cmd.exe hops, and
// additionalMetadata.ExcludeCredentials is an array, which dot-notation
// cannot express. This block only announces the decision in the log.
if (args.includes("--win") && process.env.AZURE_SIGN_ENDPOINT && process.env.AZURE_CLIENT_ID) {
console.log(`[run-electron-builder] Windows signing: Azure Trusted Signing at ${process.env.AZURE_SIGN_ENDPOINT}`)
args.push(
"-c.win.sign.type=azure",
`-c.win.sign.endpoint=${process.env.AZURE_SIGN_ENDPOINT}`,
`-c.win.sign.codeSigningAccountName=${process.env.AZURE_SIGN_ACCOUNT}`,
`-c.win.sign.certificateProfileName=${process.env.AZURE_SIGN_PROFILE}`,
`-c.win.sign.publisherName=${process.env.AZURE_SIGN_PUBLISHER}`
)
}
const result = spawnSync(process.execPath, [electronBuilderCli(), ...args], {