feat: macOS code signing, notarization, and Gatekeeper-clean release artifacts#4
Merged
Conversation
Specification, implementation plan, research decisions, data model, contracts, quickstart guide, and task list for notarized macOS release. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude Code <noreply@anthropic.com>
checkout v6, setup-python v6, upload-artifact v7, download-artifact v8, action-gh-release v3, import-codesign-certs v7. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude Code <noreply@anthropic.com>
- Add build/entitlements.plist with 4 Hardened Runtime entitlements required for PyInstaller binaries under codesign --options=runtime - Add import-codesign-certs, codesign, ditto, notarytool, and spctl verification steps to macOS job in release.yml - Split checksum step into macOS (hashes .zip) and Linux variants - macOS artifact is now risus-macos-arm64.zip (signed + notarized) - Add guaranteed API key cleanup step with if: always() - Update build.yml to run CI on 005-macos-signed-release branch - Document 6 Apple signing secrets and pre-tag verification in AGENTS.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
APPLE_TEAM_ID alone is not a valid codesign identity string. Replaced with APPLE_SIGNING_IDENTITY containing the full "Developer ID Application: Name (TeamID)" format.
spctl --assess --type execute is for .app bundles, not plain Mach-O executables. notarytool submit --wait already confirms Apple acceptance. codesign --verify is sufficient.
Field was defined but never referenced in any step.
- PLAYER.md: binary is now notarized; remove Gatekeeper bypass steps - quickstart (005): correct cert export method (Xcode not Keychain Access), add APPLE_SIGNING_IDENTITY secret, note Request Access gate in App Store Connect, warn to delete .p12 after upload, add version bump step, remove spctl verify (fails for CLI binaries) - AGENTS.md: replace APPLE_TEAM_ID with APPLE_SIGNING_IDENTITY in signing secrets table - quickstart (003): remove stale not-notarized macOS note Closes risus-cli-255
- spec.md: FR-005 now allows unsigned builds on non-tag pushes; FR-003 and SC-003 replace spctl with codesign --verify; FR-004 references APPLE_SIGNING_IDENTITY instead of APPLE_TEAM_ID - plan.md: add Notes section; fix constitution check (codesign not spctl) - tasks.md: fix T004/T009/T010 stale APPLE_TEAM_ID/spctl references; add T015 for conditional signing gate - quickstart.md: add Conditional signing section
Extracting risus-macos-arm64.zip currently produces dist/ — a CI build path leaking into the release artifact. Spec, plan, and tasks for fixing the zip to extract into a risus-macos-arm64/ directory.
- Gate all macOS signing steps on env.APPLE_CERTIFICATE != '' - Add Assert signing secrets step (fails loudly on tag push without secrets) - Unsigned fallback path for branch/PR builds without secrets - Fix zip structure: stage binary in /tmp/risus-macos-arm64/ before ditto so archive extracts to risus-macos-arm64/ not dist/ - Consolidate duplicate checksum and upload steps (non-signed path) Co-Authored-By: Claude Sonnet 4.6 <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.
Summary
env.APPLE_CERTIFICATE != '': branch builds produce unsigned binary (no failure); tag push asserts secrets present andexits 1 with clear error if missing
risus-macos-arm64/notdist/What changed
.github/workflows/release.yml— codesign, notarytool, post-notarization verify; conditional onAPPLE_CERTIFICATE; zip staged via/tmp;assert step on tag push
build/entitlements.plist— Hardened Runtime entitlements for PyInstaller Python runtimeAGENTS.md— Signing Setup subsection with 6 required secrets and how to obtain eachPLAYER.md/ quickstart docs — remove outdated Gatekeeper bypass instructionsRequired secrets
APPLE_CERTIFICATEAPPLE_CERTIFICATE_PASSWORDAPPLE_SIGNING_IDENTITYDeveloper ID Application: Name (TeamID)APPLE_API_KEY_IDAPPLE_API_ISSUER_IDAPPLE_API_KEY_CONTENTSee
specs/005-macos-signed-release/quickstart.mdfor setup steps.Test plan
risus-macos-arm64.zip,codesign --verify --deep --strictpassesrisus-macos-arm64/, notdist/