fix(release): notarize before publish + repair DMG verification#16
Merged
Conversation
Publishes site/manifest.json to https://light-cloud-com.github.io/out-loud/manifest.json so the in-app announcements + update notice can be driven remotely.
…panel Accessibility: - Talker mode (Settings toggle, default off): Enter speaks + clears, text box stays editable during playback, audio click + screen-reader status. - Cmd/Ctrl+Enter speaks anywhere; Shift+Enter = newline; Esc refocuses the box; textarea autofocuses on launch. Speech: - Pause tags: [1s], [500ms], <pause=1s>, <break time="1s"/> (forgiving units). - Highlighting now treats pause tags as silence so it stays in sync. Updates & help: - In-app update check against GitHub releases with a direct per-platform download button (skipped in MAS builds). Replaces the remote-manifest approach (removes site/manifest.json and the Pages workflow). - Help/About panel (footer ? button) with version, shortcuts, and pause docs. Bumps version to 1.0.6; updates CHANGELOG, README, and architecture docs.
- Point the Help/About link, tray About item, and Chrome extension download banner at https://www.out-loud.io (was out-loud.pro). - Update the default example text to demonstrate inline <pause=...> tags. - Bump version to 1.0.7; update CHANGELOG.
Add scripts/release.mjs (npm run release <version>): bump → PR → wait CI → squash-merge → tag → wait build → notarize → publish, in a single command. Update releasing docs.
Repo-level tag ruleset protecting v* tags from deletion/force-push while allowing creation (so npm run release works); admins bypass always. Already applied to the repo via the GitHub API.
* release: 1.0.9 * v1.0.9
Two bugs left v1.0.9's Intel DMG unnotarized and its arm64 DMG unstapled: 1. notarize-release.mjs verified each stapled DMG with `spctl --assess` on the unmounted .dmg, which always reports "no usable signature" (a disk image has no code signature of its own — the ticket is validated by `stapler`). That threw right after stapling the arm64 DMG, aborting the loop before the x64 DMG was ever submitted. Fix: verify with `stapler validate`, and separately assess the .app inside the mounted DMG (the real Gatekeeper check). Also: retry `stapler staple` (Apple's ticket CDN lags behind `submit --wait`), isolate per-DMG failures so one arch can't abort the others, and only re-upload DMGs that were successfully stapled. 2. release.mjs published (un-drafted) BEFORE notarizing. GitHub "Immutable releases" freezes assets at publish time — permanently — so the stapled DMGs could never be re-uploaded. Fix: notarize while the release is still a draft, then publish. Docs updated to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
While fixing v1.0.9's notarization (only the arm64 DMG was notarized; the Intel DMG wasn't, and neither was stapled) I found two bugs in the release tooling.
1. Bogus DMG verification aborted the notarize loop
notarize-release.mjsverified each stapled DMG withspctl --assesson the unmounted.dmg. A disk image has no code signature of its own, so that always returnsno usable signatureand exits non-zero. It threw right after stapling the arm64 DMG, aborting the loop before the x64 DMG was ever submitted — exactly why every past release only has an arm64 notarization on record.Fix:
xcrun stapler validate(authoritative for a stapled DMG).spctl-assess the.appinside (the real Gatekeeper check).stapler staple(Apple's ticket CDN lags a few seconds behindnotarytool submit --wait).2. Publish-before-notarize is incompatible with Immutable Releases
release.mjsun-drafted the release before notarizing. GitHub "Immutable releases" freezes a release's assets at publish time permanently, so the stapled DMGs could never be re-uploaded (HTTP 422: Cannot delete asset from an immutable release).Fix: notarize while the release is still a draft, then publish. Docs updated to match.
🤖 Generated with Claude Code