fix(macos): configure release signing and notarization#422
fix(macos): configure release signing and notarization#422
Conversation
Greptile SummaryThis PR wires up macOS release signing and notarization for the Moltis macOS app — adding Apple certificate import, Key changes and concerns:
Confidence Score: 2/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant GHA as GitHub Actions
participant KC as macOS Keychain
participant XC as xcodebuild
participant NT as notarytool
participant ST as stapler
GHA->>KC: Import Apple certificate (if !dry_run)
GHA->>XC: Build with CODE_SIGN_STYLE=Manual<br/>CODE_SIGN_IDENTITY="Developer ID Application"<br/>DEVELOPMENT_TEAM (always – even in dry_run ⚠️)
XC-->>GHA: Moltis.app (signed)
GHA->>GHA: ditto → moltis-VERSION-macos.app.zip
GHA->>NT: notarytool submit zip --wait (if !dry_run)
NT-->>GHA: Notarization approved
GHA->>ST: stapler staple Moltis.app (if !dry_run)
ST-->>GHA: Ticket stapled
GHA->>GHA: rm zip, ditto → new zip (stapled)
GHA->>GHA: Sign with Sigstore + upload artifact
GHA->>KC: security delete-keychain (always)
Last reviewed commit: 50c1a06 |
| - name: Build macOS app | ||
| env: | ||
| DERIVED_DATA_DIR: apps/macos/.derivedData-ci | ||
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | ||
| run: | | ||
| xcodebuild \ | ||
| -project apps/macos/Moltis.xcodeproj \ | ||
| -scheme Moltis \ | ||
| -configuration Release \ | ||
| -destination "platform=macOS" \ | ||
| -derivedDataPath "$DERIVED_DATA_DIR" \ | ||
| CODE_SIGN_STYLE=Manual \ | ||
| CODE_SIGN_IDENTITY="Developer ID Application" \ | ||
| DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \ | ||
| OTHER_CODE_SIGN_FLAGS="--options runtime" \ | ||
| build |
There was a problem hiding this comment.
Signing parameters applied unconditionally while certificate import is conditional
The "Import Apple certificate" step is gated on RELEASE_DRY_RUN != 'true', but the "Build macOS app" step always runs — including the CODE_SIGN_STYLE=Manual, CODE_SIGN_IDENTITY="Developer ID Application", and DEVELOPMENT_TEAM overrides. During a dry run, no certificate is imported into the keychain, so xcodebuild will fail immediately with "code signing identity 'Developer ID Application' does not match any code signing certificate in your keychain".
You should guard the signing parameters with the same condition, or add a separate code path that builds with CODE_SIGNING_ALLOWED=NO for dry runs. For example:
- name: Build macOS app (dry run – no signing)
if: ${{ env.RELEASE_DRY_RUN == 'true' }}
env:
DERIVED_DATA_DIR: apps/macos/.derivedData-ci
run: |
xcodebuild \
-project apps/macos/Moltis.xcodeproj \
-scheme Moltis \
-configuration Release \
-destination "platform=macOS" \
-derivedDataPath "$DERIVED_DATA_DIR" \
CODE_SIGNING_ALLOWED=NO \
build
- name: Build macOS app (release – signed)
if: ${{ env.RELEASE_DRY_RUN != 'true' }}
env:
DERIVED_DATA_DIR: apps/macos/.derivedData-ci
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
xcodebuild \
-project apps/macos/Moltis.xcodeproj \
-scheme Moltis \
-configuration Release \
-destination "platform=macOS" \
-derivedDataPath "$DERIVED_DATA_DIR" \
CODE_SIGN_STYLE=Manual \
CODE_SIGN_IDENTITY="Developer ID Application" \
DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \
OTHER_CODE_SIGN_FLAGS="--options runtime" \
build| ENABLE_HARDENED_RUNTIME: YES | ||
| CODE_SIGN_STYLE: Manual | ||
| CODE_SIGN_IDENTITY: "Developer ID Application" |
There was a problem hiding this comment.
Manual signing identity in base settings breaks Debug builds for most developers
CODE_SIGN_STYLE: Manual and CODE_SIGN_IDENTITY: "Developer ID Application" are placed in the base settings block, which means they apply to both Debug and Release configurations. When a developer opens the project in Xcode and runs a normal Debug build without the CODE_SIGNING_ALLOWED=NO command-line override, Xcode will look for a "Developer ID Application" certificate in their keychain. Most contributors won't have this certificate (it requires a paid account with the specific distribution cert), causing the build to fail immediately in Xcode.
Consider scoping these signing settings to the Release configuration only:
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: org.moltis.app
GENERATE_INFOPLIST_FILE: YES
SWIFT_EMIT_LOC_STRINGS: NO
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
SWIFT_OBJC_BRIDGING_HEADER: Sources/Bridging-Header.h
ENABLE_HARDENED_RUNTIME: YES
OTHER_LDFLAGS:
...
configs:
Release:
CODE_SIGN_STYLE: Manual
CODE_SIGN_IDENTITY: "Developer ID Application"There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 50c1a06fa0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| CODE_SIGN_STYLE=Manual \ | ||
| CODE_SIGN_IDENTITY="Developer ID Application" \ | ||
| DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \ |
There was a problem hiding this comment.
Skip signing in dry-run macOS release builds
In .github/workflows/release.yml, this step now always forces manual Developer ID signing, but the certificate import is gated behind if: ${{ env.RELEASE_DRY_RUN != 'true' }}. For workflow_dispatch dry runs, no signing cert is installed while xcodebuild still requires one, so the macOS job fails before packaging/notarization logic can be exercised. This makes the workflow’s dry-run mode effectively unusable.
Useful? React with 👍 / 👎.
| CODE_SIGN_STYLE: Manual | ||
| CODE_SIGN_IDENTITY: "Developer ID Application" |
There was a problem hiding this comment.
Restrict manual Developer ID signing to release builds
Adding manual signing at the target base settings level applies it to all generated macOS builds, not just release packaging. Local developer workflows (just swift-build / just swift-test, via scripts/build-swift.sh and scripts/test-swift.sh) call xcodebuild without CODE_SIGNING_ALLOWED=NO, so machines without a Developer ID certificate will now fail to build/test the app. This is a regression in day-to-day macOS development.
Useful? React with 👍 / 👎.
Merging this PR will not alter performance
Comparing Footnotes
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Summary
Risks
Required fixes
Optional improvements
Verdictrequest_changes |
Summary
Validation
Completed
./scripts/generate-swift-project.shgit rebase origin/maingit push -u origin ios-signaturesRemaining
./scripts/lint-swift.sh(fails on existingfunction_body_lengthviolation inapps/macos/Sources/ConfigurationPane.swift:225)xcodebuild -project apps/macos/Moltis.xcodeproj -scheme Moltis -configuration Release -destination "platform=macOS" -derivedDataPath apps/macos/.derivedData-local-validate CODE_SIGNING_ALLOWED=NO build(fails in this environment becauseapps/macos/Sources/Bridging-Header.hcannot findmoltis_bridge.h)Manual QA