Fix rcodesign CLI: self-signed p12 instead of removed --ad-hoc
Release rolling / release (push) Has been cancelled
Release rolling / release (push) Has been cancelled
apple-codesign 0.29 rejects --ad-hoc. Generate a self-signed P12 and sign darwin .app bundles with --p12-file so Linux CI produces a sealed signature instead of failing postPackage.
This commit is contained in:
+120
-13
@@ -211,29 +211,136 @@ function codesignDarwin(appPath, id) {
|
||||
log('verify ok:', (v.stderr || v.stdout || '').trim().split('\n').slice(0, 3).join(' | '))
|
||||
}
|
||||
|
||||
/**
|
||||
* rcodesign 0.29+ does not accept `--ad-hoc`.
|
||||
* "Ad-hoc" equivalent for Linux CI: self-signed cert via p12/pem, then `rcodesign sign`.
|
||||
* Self-signed is enough for a *valid* sealed signature (avoids Gatekeeper "damaged");
|
||||
* it is NOT Developer ID / notarization.
|
||||
*/
|
||||
function ensureRcodesignSelfSignedP12(bin) {
|
||||
const certDir =
|
||||
process.env.PEARDOCK_RCODESIGN_CERT_DIR ||
|
||||
path.join(__dirname, '..', 'tools', 'rcodesign', 'ci-cert')
|
||||
const p12Path = path.join(certDir, 'peardock-ci.p12')
|
||||
const password = process.env.PEARDOCK_RCODESIGN_P12_PASSWORD || 'peardock-ci-sign'
|
||||
fs.mkdirSync(certDir, { recursive: true })
|
||||
if (fs.existsSync(p12Path) && fs.statSync(p12Path).size > 100) {
|
||||
return { p12Path, password }
|
||||
}
|
||||
|
||||
log('generating self-signed signing cert for rcodesign…')
|
||||
// Flags match apple-codesign 0.29 generate-self-signed-certificate CLI
|
||||
const gen = spawnSync(
|
||||
bin,
|
||||
[
|
||||
'generate-self-signed-certificate',
|
||||
'--p12-file',
|
||||
p12Path,
|
||||
'--p12-password',
|
||||
password,
|
||||
'--person-name',
|
||||
'peardock-ci',
|
||||
'--country-name',
|
||||
'US',
|
||||
'--validity-days',
|
||||
'3650',
|
||||
'--team-id',
|
||||
'NONE',
|
||||
'--profile',
|
||||
'developer-id-application',
|
||||
],
|
||||
{ encoding: 'utf8', stdio: 'pipe' }
|
||||
)
|
||||
if (gen.status !== 0 || !fs.existsSync(p12Path)) {
|
||||
// Older/newer flag variants
|
||||
const gen2 = spawnSync(
|
||||
bin,
|
||||
[
|
||||
'generate-self-signed-certificate',
|
||||
'--p12-file',
|
||||
p12Path,
|
||||
'--p12-password',
|
||||
password,
|
||||
'--person-name',
|
||||
'peardock-ci',
|
||||
'--country-name',
|
||||
'US',
|
||||
'--validity-days',
|
||||
'3650',
|
||||
],
|
||||
{ encoding: 'utf8', stdio: 'pipe' }
|
||||
)
|
||||
if (gen2.status !== 0 || !fs.existsSync(p12Path)) {
|
||||
throw new Error(
|
||||
`rcodesign generate-self-signed-certificate failed:\n` +
|
||||
`${gen.stderr || gen.stdout}\n${gen2.stderr || gen2.stdout}`
|
||||
)
|
||||
}
|
||||
}
|
||||
log('wrote', p12Path)
|
||||
return { p12Path, password }
|
||||
}
|
||||
|
||||
function codesignRcodesign(appPath, id) {
|
||||
const bin = which('rcodesign')
|
||||
if (!bin) {
|
||||
throw new Error(
|
||||
'rcodesign not found (needed to ad-hoc sign macOS .app on Linux). ' +
|
||||
'Install apple-codesign / rcodesign in CI, or package darwin clients on macOS.'
|
||||
'rcodesign not found (needed to sign macOS .app on Linux). ' +
|
||||
'CI installs tools/rcodesign/<host>/rcodesign, or package darwin clients on macOS.'
|
||||
)
|
||||
}
|
||||
if (id !== '-') {
|
||||
log('WARN: rcodesign path only used for ad-hoc here; Developer ID needs codesign on macOS + certs')
|
||||
log(
|
||||
'WARN: Linux rcodesign path uses self-signed cert only; ' +
|
||||
'Developer ID needs codesign on macOS + Apple certs'
|
||||
)
|
||||
}
|
||||
// Clear extended attrs if possible (mac only usually)
|
||||
const args = ['sign', '--ad-hoc', appPath]
|
||||
log('rcodesign', args.join(' '))
|
||||
const r = spawnSync(bin, args, { encoding: 'utf8', stdio: 'pipe' })
|
||||
if (r.status !== 0) {
|
||||
// newer CLI variants
|
||||
const r2 = spawnSync(bin, ['sign', appPath, '--ad-hoc'], { encoding: 'utf8', stdio: 'pipe' })
|
||||
if (r2.status !== 0) {
|
||||
throw new Error(`rcodesign failed:\n${r.stderr || r.stdout}\n${r2.stderr || r2.stdout}`)
|
||||
|
||||
const entitlements = ensureEntitlements()
|
||||
const { p12Path, password } = ensureRcodesignSelfSignedP12(bin)
|
||||
|
||||
// Prefer full Electron-friendly sign: p12 + runtime + entitlements
|
||||
const attempts = [
|
||||
[
|
||||
'sign',
|
||||
'--p12-file',
|
||||
p12Path,
|
||||
'--p12-password',
|
||||
password,
|
||||
'--code-signature-flags',
|
||||
'runtime',
|
||||
'--entitlements-xml-file',
|
||||
entitlements,
|
||||
appPath,
|
||||
],
|
||||
[
|
||||
'sign',
|
||||
'--p12-file',
|
||||
p12Path,
|
||||
'--p12-password',
|
||||
password,
|
||||
'--code-signature-flags',
|
||||
'runtime',
|
||||
appPath,
|
||||
],
|
||||
['sign', '--p12-file', p12Path, '--p12-password', password, appPath],
|
||||
]
|
||||
|
||||
let lastErr = ''
|
||||
for (const args of attempts) {
|
||||
// Never log the password
|
||||
log(
|
||||
'rcodesign',
|
||||
args.map((a) => (a === password ? '***' : a)).join(' ')
|
||||
)
|
||||
const r = spawnSync(bin, args, { encoding: 'utf8', stdio: 'pipe' })
|
||||
if (r.status === 0) {
|
||||
log('rcodesign sign complete (self-signed / sealed)')
|
||||
return
|
||||
}
|
||||
lastErr += `${r.stderr || r.stdout || ''}\n`
|
||||
}
|
||||
log('rcodesign ad-hoc sign complete')
|
||||
throw new Error(`rcodesign failed:\n${lastErr}`)
|
||||
}
|
||||
|
||||
function signApp(appPath) {
|
||||
|
||||
Reference in New Issue
Block a user