Skip to content

Retry the in-build macOS notarization - #60

Merged
iLevyTate merged 2 commits into
mainfrom
claude/gallant-babbage-mlfl4c
Nov 1, 2026
Merged

iLevyTate merged 2 commits into
mainfrom
claude/gallant-babbage-mlfl4c

Conversation

@iLevyTate

Copy link
Copy Markdown
Owner

Summary

  • With APPLE_* credentials set, electron-builder notarizes the signed .app right after codesigning, in one attempt. A dropped connection to Apple's notary service then fails the whole build. The macOS x64 jobs for 5.1.0 (NSURLErrorDomain -1005 while stapling) and 5.1.1 (-1009 while waiting on the submission) both died there. The retries from ci(mac-release): retry Apple notary and stapler network calls #46 only cover the workflow's later dmg/zip notarization.
  • electron-builder.json now sets mac.notarize: false and names an afterSign hook, scripts/notarize-mac-app.js. The hook runs at the same point (after codesigning, before the dmg and zip are built) and makes the same @electron/notarize call with the same credentials. It tries up to three times, 30 s and 60 s apart.
  • Same behaviour otherwise:
    • The hook loads app-builder-lib's own @electron/notarize (2.5.0), the copy electron-builder uses. The top-level 3.x is ESM-only and needs Node 22.12, but the release runners use Node 20.
    • It mirrors MacTargetHelper.getNotarizeOptions: Apple ID, API key or keychain profile, with the same errors.
    • It does nothing for Windows, Linux and Mac App Store builds, or without credentials.
  • docs/MAC_SIGNING.md describes the hook in the workflow walkthrough.

Scope

  • Area(s): macOS release (electron-builder config, afterSign hook)
  • Risk Level: medium. It changes how the signed macOS app gets notarized. The call and its options are identical, but only a release run proves it.
  • Breaking Changes: none

Type of Change

  • Bug fix
  • Enhancement
  • New feature
  • Refactor
  • Documentation update
  • Breaking change

Test Plan

Automated

  • npm run format:check (Prettier on the changed files)
  • npm run lint (ESLint on the hook and its test)
  • npm test: notarizeMacApp, electron-builder-config, verifyElectronFusesConfig, verifyPackagedArtifacts (all pass), knip:files, and compliance:commercial:verify (inventory unchanged)
  • Additional tests added/updated when behavior changed

test/notarizeMacApp.test.js covers:

  • the hook's options and errors against electron-builder's own getNotarizeOptions, for 8 credential cases
  • the retry, backoff and give-up paths
  • skipping non-darwin builds and builds without credentials
  • that electron-builder's resolveFunction loads the configured hook as afterSign (this check fails if the export is removed)

Manual QA

  • Manual checklist completed (see docs/TESTING.md)
  • Not applicable (explain below)

Manual QA notes:

  • Notarization needs Apple credentials and a macOS runner, so the next mac-release.yml run is the real test. The log should show [notarize] StratoSort Stack.app notarized and stapled in the signed build step.

Checklist

  • I scoped this PR to one logical change
  • I self-reviewed code and naming for clarity
  • I updated docs/config references where needed
  • I called out follow-up work or known limitations: the 5.1.1 macOS x64 job is being re-run on the old flow; this applies from the next release.

Generated by Claude Code

With APPLE_* credentials set, electron-builder notarizes the signed .app
right after codesigning, in one attempt. A dropped connection to Apple's
notary service then fails the build: the macOS x64 jobs for 5.1.0
(NSURLErrorDomain -1005 while stapling) and 5.1.1 (-1009 while waiting on
the submission) both died there. The retries added in #46 cover only the
workflow's later dmg/zip notarization.

electron-builder.json now sets mac.notarize to false and names an afterSign
hook, scripts/notarize-mac-app.js, which runs at the same point (after
codesigning, before the dmg and zip are built) and makes the same
@electron/notarize call with the same credentials: it loads
app-builder-lib's own @electron/notarize (the top-level 3.x is ESM-only and
needs Node 22.12; the release runners use Node 20) and mirrors
MacTargetHelper.getNotarizeOptions. It tries up to three times, 30 s and
60 s apart, and does nothing for Windows, Linux and Mac App Store builds or
without credentials.

Tests check the options and errors against electron-builder's own
getNotarizeOptions for every credential form, the retry and give-up paths,
and that electron-builder's resolveFunction would load the hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5Uo5hC58DRSh1qB489Sos
Runs app-builder-lib's resolveFunction on the configured afterSign path, as
electron-builder does when it loads hooks; it fails if the hook stops
exporting afterSign.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5Uo5hC58DRSh1qB489Sos
@iLevyTate
iLevyTate merged commit 1a40a5d into main Nov 1, 2026
11 checks passed
iLevyTate pushed a commit that referenced this pull request Nov 1, 2026
- package.json / package-lock.json: 5.1.2.
- CHANGELOG: 5.1.2 section for the glob and minimatch tooling updates
  (#61, #62) and the retried macOS notarization (#60); compare links.
- SECURITY.md: applies to 5.1.2; example patch versions.
- BETA_TESTER_GUIDE / INSTALL_GUIDE: current version and download names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5Uo5hC58DRSh1qB489Sos
@iLevyTate iLevyTate mentioned this pull request Nov 1, 2026
7 of 16 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants