fix(release): bound macOS notarization waits

Add an outer watchdog around the signed macOS electron-builder step so hung notarytool waits return control to the retry loop instead of idling until the GitHub step timeout.\n\nTested: bun test scripts/pr/release-workflow.test.ts\nTested: git diff --check\nTested: bun run scripts/release.ts 0.4.3 --dry\nConfidence: medium\nScope-risk: narrow
This commit is contained in:
程序员阿江(Relakkes) 2026-06-17 03:38:46 +08:00
parent 5c01675cfa
commit a45d3492b1
2 changed files with 44 additions and 4 deletions

View File

@ -161,7 +161,7 @@ jobs:
- name: Build signed macOS Electron release artifacts
if: matrix.smoke_platform == 'macos' && needs.signing-preflight.outputs.macos_signed == 'true'
working-directory: desktop
timeout-minutes: 90
timeout-minutes: 80
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEBUG: 'electron-builder,electron-osx-sign,electron-notarize*'
@ -184,10 +184,45 @@ jobs:
security find-identity -v -p codesigning || true
echo "::endgroup::"
max_attempts=2
build_timeout_seconds=2100
run_signed_electron_builder() {
local timeout_seconds="$1"
shift
"$@" &
local build_pid=$!
local start_epoch
start_epoch=$(date +%s)
while true; do
if ! jobs -pr | grep -q "^${build_pid}$"; then
break
fi
local now_epoch elapsed_seconds
now_epoch=$(date +%s)
elapsed_seconds=$((now_epoch - start_epoch))
if [ "$elapsed_seconds" -ge "$timeout_seconds" ]; then
echo "::warning::Signed electron-builder timed out after ${elapsed_seconds}s; terminating process ${build_pid}"
pkill -TERM -P "$build_pid" 2>/dev/null || true
kill -TERM "$build_pid" 2>/dev/null || true
sleep 10
pkill -KILL -P "$build_pid" 2>/dev/null || true
kill -KILL "$build_pid" 2>/dev/null || true
wait "$build_pid" 2>/dev/null || true
return 124
fi
sleep 15
done
wait "$build_pid"
}
for attempt in $(seq 1 "$max_attempts"); do
echo "Starting signed electron-builder attempt ${attempt}/${max_attempts} at $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
echo "Starting signed electron-builder attempt ${attempt}/${max_attempts} at $(date -u '+%Y-%m-%dT%H:%M:%SZ') with ${build_timeout_seconds}s watchdog"
rm -rf build-artifacts/electron
if node ./node_modules/electron-builder/out/cli/cli.js ${{ matrix.builder_args }} --publish never; then
if run_signed_electron_builder "$build_timeout_seconds" node ./node_modules/electron-builder/out/cli/cli.js ${{ matrix.builder_args }} --publish never; then
echo "Finished signed electron-builder attempt ${attempt}/${max_attempts} at $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
exit 0
fi

View File

@ -129,12 +129,17 @@ describe('release desktop workflow', () => {
expect(signedBuildStep).toContain('APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}')
expect(signedBuildStep).toContain('APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}')
expect(signedBuildStep).not.toContain('CSC_IDENTITY_AUTO_DISCOVERY')
expect(signedBuildStep).toContain('timeout-minutes: 90')
expect(signedBuildStep).toContain('timeout-minutes: 80')
expect(signedBuildStep).toContain("DEBUG: 'electron-builder,electron-osx-sign,electron-notarize*'")
expect(signedBuildStep).toContain('macOS signing diagnostics')
expect(signedBuildStep).toContain('xcrun --find notarytool')
expect(signedBuildStep).toContain('security find-identity -v -p codesigning')
expect(signedBuildStep).toContain('max_attempts=2')
expect(signedBuildStep).toContain('build_timeout_seconds=2100')
expect(signedBuildStep).toContain('run_signed_electron_builder')
expect(signedBuildStep).toContain('Signed electron-builder timed out')
expect(signedBuildStep).toContain('pkill -TERM -P "$build_pid"')
expect(signedBuildStep).toContain('with ${build_timeout_seconds}s watchdog')
expect(signedBuildStep).toContain('rm -rf build-artifacts/electron')
expect(signedBuildStep).toContain('Starting signed electron-builder attempt')
expect(signedBuildStep).toContain('Finished signed electron-builder attempt')