The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Actions | Updated |
|---|---|---|---|
| External image rac | Ready Ready | Preview | Oct 27, 2026 10:21pm UTC |
Problem.
generate_sparkle_deltas.py assumes every earlier release has both architectures, so the release after an arm64-only 0.1.0 would have crashed.Change.
settings job. They receive no certificate, notarization password or provisioning profile. The finishing phase uploads the unsigned app as tar+zstd with a sha256 file.sign job on GitHub-hosted macos-latest:set-key-partition-list, so no dialog appears). The keychain is deleted in an always() step.codesign --verify --deep --strict; spctl with assessments enabled and source=Notarized Developer ID for both the app and the DMG (the DMG with -t open --context context:primary-signature); stapler validate; the signing team; and no profile-only entitlements without a profile.macos-latest because it holds the Sparkle key. It re-verifies each notarized DMG before signing it into the appcast.github_check_release_binary.sh runs strings over the app's executables and frameworks and looks for rac-agent-debug, rac-agent-mcp-echo, rac-window-screenshot and rac-launch-in-background. The new Developer switches (G6) input defaults to warn. Switch it to enforce once Core's BUILDFLAG(RAC_DEV_SWITCHES) change merges.docs/operations/releases.md and upstream-sync.md are updated.Preflight findings.
MAC_TEAM_ID (patches/rac/branding/identity.patch) doesn't affect signing or notarization, which use the certificate name and PROD_MACOS_NOTARIZATION_TEAM_ID. It only matters if branded entitlements are turned on: the app would then claim .me.kainoa.rac and fail to launch. github_verify_dmg.sh now fails the build in that case.allow-jit in the helpers) are allowed for a Developer ID app without a profile. The restricted set (application-identifier, keychain-access-groups, web-browser public-key credential) is off.Verified.
shellcheck is clean on the changed scripts. actionlint reports only the existing description error in prepare-environment.sign_and_package_app.sh, the DMG, the hashes and the outputs.xcrun.Patch surface (D17): no change, because this PR touches no patches.
Part of plan 06 M0 task 5 and M1 (the ci stream).
🤖 Generated with Claude Code (Claude Opus 5.5 and Claude Sonnet 5.5)
Note
High Risk Restructures where Apple signing/notarization and Sparkle release secrets run, and changes what ships if verification or the new sign job fails—core release security infrastructure.
Overview
Splits compile from signing so build phases never receive the Developer ID certificate, notarization credentials, or provisioning profile. Finished phases upload an unsigned rac.app (tar+zstd + checksum) instead of a DMG; a new per-arch sign job on macos-latest runs G6, signs/notarizes/staples the app and DMG, verifies the mounted image, and publishes the same release artifacts as before.
Secret exposure is reduced: a settings job exposes only a boolean for branded entitlements to compile jobs; the release job is pinned to GitHub's runner alongside sign. sign_and_package_app.sh now notarizes and staples the DMG (with retries), and generate_sparkle_deltas.py skips architectures missing from older releases.
G6 gate: new github_check_release_binary.sh scans Mach-O binaries for developer switch strings, controlled by a Developer switches (G6) workflow input (warn / enforce). The release job re-runs github_verify_dmg.sh on downloaded DMGs before appcast signing. Unit tests cover the gate and verify script behavior; release docs and upstream-sync notes describe the new flow.
Reviewed by Cursor Bugbot for commit 9f9e5a672251359b3c45f566ffc70ca2780917a9. Bugbot is set up for automated code reviews on this repo. Configure here.
Moves code signing, notarization, and release packaging out of the build phases and into a final sign job that always runs on GitHub's own macos-latest runner, so signing keys never reach build runners. Notarizes and staples the DMG, which was previously signed but never notarized.
settings job; the finished phase uploads the unsigned app as a tar.zst with a sha256.sign job imports the certificate into a temporary keychain (deleted in an always() step), runs a Gatekeeper check on the mounted DMG, signs, notarizes, and staples both app and DMG with retries on Apple's transient errors, and makes the update deltas.macos-latest and re-verifies each notarized DMG before writing it into the appcast.github_verify_dmg.sh fails if codesign can't read the entitlements instead of treating it as none.Written for commit 9f9e5a672251359b3c45f566ffc70ca2780917a9. Summary will update on new commits.
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Actions | Updated |
|---|---|---|---|
| External image rac | Ready Ready | Preview | Oct 27, 2026 10:21pm UTC |
Your OpenCode Zen account is out of credit. Top it up, then re-trigger Pullfrog.
| 1 | provider error: Upstream request failed: Insufficient account funds |
Pullfrog | Rerun failed job ➔ | View workflow run | via Pullfrog | Using kimi-k3
Important
Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.
2469baf4-964e-40f6-bd4d-46966c2f4382You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.
A user or team admin can review and increase usage limits in the Cursor dashboard.
(requestId: 09b66ebd-487a-410f-885e-e1e87b20e174)
[High impact] The PR changes the path used to produce and publish every macOS release.
The PR appears safe to merge, with two non-blocking improvements to release checks.
| 1 | ### Issue 1 |
| 2 | .github/workflows/build.yml:126 |
| 3 | If `PROD_MACOS_NOTARIZATION_TEAM_ID` contains a trailing newline, signing succeeds because `github_sign_app.sh` removes whitespace. The release job passes the original secret to `RAC_EXPECT_TEAM_ID`, so its exact team comparison then fails. Apply the same cleanup before the release check. |
| 4 | |
| 5 | ### Issue 2 |
| 6 | .github/scripts/github_verify_dmg.sh:51 |
| 7 | `github_verify_dmg.sh` ignores errors from the command that reads entitlements, then treats empty output as an empty entitlement list. If the command fails without writing output, the profile and application-ID checks silently do nothing. Fail when the command cannot read entitlements instead of treating that failure as a successful empty result. |
| 8 | |
| 9 | ```suggestion |
| 10 | if ! codesign -d --entitlements - --xml "$_app" > "$_mnt.entitlements.plist"; then |
| 11 | echo "::error::Could not read the app entitlements" |
| 12 | exit 1 |
| 13 | fi |
| 14 | ``` |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | For each issue above, determine whether it is valid and should be fixed. If so, fix it directly. |
Moves signing and notarization out of compile phases and onto GitHub-hosted runners.
Acknowledgment: notkainoa explicitly deferred enforcing G6 until the Core build flag lands. The default warning mode is intentional. notkainoa also stated that real certificate import and notarization remain unproven; this review does not claim runtime verification.
| 1 | %%{init: {'theme': 'neutral'}}%% |
| 2 | flowchart LR |
| 3 | Settings[Optional profile setting] --> Compile[Compile phases] |
| 4 | Compile --> Archive[Unsigned app and checksum] |
| 5 | Archive --> Gate[Check developer switches] |
| 6 | Gate --> Sign[Sign and notarize app] |
| 7 | Sign --> DMG[Package and notarize disk image] |
| 8 | DMG --> Verify[Verify image and make deltas] |
| 9 | Verify --> Release[Recheck images and sign update feeds] |
| 10 | Release --> Publish[Publish release] |
Reviews (1) · Last reviewed commit: "ci: harden the signing job after review" · Reviewed by Greptile
| … | … | @@ -85,6 +96,34 @@ jobs: | |
| 123 | + | env: | |
| 124 | + | # Only whether the certificate exists, and the (public) team ID. | |
| 125 | + | RAC_NOTARIZED: ${{ secrets.PROD_MACOS_CERTIFICATE != '' && '1' || '0' }} | |
| 126 | + | RAC_EXPECT_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} | |
P2 Team ID cleanup differs
If PROD_MACOS_NOTARIZATION_TEAM_ID contains a trailing newline, signing succeeds because github_sign_app.sh removes whitespace. The release job passes the original secret to RAC_EXPECT_TEAM_ID, so its exact team comparison then fails. Apply the same cleanup before the release check.
| 1 | This is a comment left during a code review. |
| 2 | Path: .github/workflows/build.yml |
| 3 | Line: 126 |
| 4 | |
| 5 | Comment: |
| 6 | **Team ID cleanup differs** |
| 7 | |
| 8 | If `PROD_MACOS_NOTARIZATION_TEAM_ID` contains a trailing newline, signing succeeds because `github_sign_app.sh` removes whitespace. The release job passes the original secret to `RAC_EXPECT_TEAM_ID`, so its exact team comparison then fails. Apply the same cleanup before the release check. |
| 9 | |
| 10 | --- |
| 11 | |
| 12 | For each issue above, determine whether it is valid and should be fixed. If so, fix it directly. |
| … | … | @@ -0,0 +1,131 @@ | |
| 48 | + | # An app that claims a restricted entitlement without a provisioning profile | |
| 49 | + | # that grants it is killed at launch, and notarization doesn't catch that. | |
| 50 | + | echo "== entitlements (main executable)" | |
| 51 | + | codesign -d --entitlements - --xml "$_app" 2>/dev/null > "$_mnt.entitlements.plist" || true | |
P2 Failed entitlement reads pass
github_verify_dmg.sh ignores errors from the command that reads entitlements, then treats empty output as an empty entitlement list. If the command fails without writing output, the profile and application-ID checks silently do nothing. Fail when the command cannot read entitlements instead of treating that failure as a successful empty result.
| 1 | if ! codesign -d --entitlements - --xml "$_app" > "$_mnt.entitlements.plist"; then |
| 2 | echo "::error::Could not read the app entitlements" |
| 3 | exit 1 |
| 4 | fi |
| 1 | This is a comment left during a code review. |
| 2 | Path: .github/scripts/github_verify_dmg.sh |
| 3 | Line: 51 |
| 4 | |
| 5 | Comment: |
| 6 | **Failed entitlement reads pass** |
| 7 | |
| 8 | `github_verify_dmg.sh` ignores errors from the command that reads entitlements, then treats empty output as an empty entitlement list. If the command fails without writing output, the profile and application-ID checks silently do nothing. Fail when the command cannot read entitlements instead of treating that failure as a successful empty result. |
| 9 | |
| 10 | ```suggestion |
| 11 | if ! codesign -d --entitlements - --xml "$_app" > "$_mnt.entitlements.plist"; then |
| 12 | echo "::error::Could not read the app entitlements" |
| 13 | exit 1 |
| 14 | fi |
| 15 | ``` |
| 16 | |
| 17 | --- |
| 18 | |
| 19 | For each issue above, determine whether it is valid and should be fixed. If so, fix it directly. |
Added 2 commits
Deployment failed for project rac with the following error:
| 1 | Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day"). |
Learn More: https://vercel.com/knewton?upgradeToPro=build-rate-limit
Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.
A user or team admin can review and increase usage limits in the Cursor dashboard.
(requestId: 23ea93f8-f4ae-4488-b2b4-86800d07d107)
Your OpenCode Zen account is out of credit. Top it up, then re-trigger Pullfrog.
| 1 | provider error: Upstream request failed: Insufficient account funds |
Pullfrog | Rerun failed job ➔ | View workflow run | via Pullfrog | Using kimi-k3
Added 1 commit
Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.
A user or team admin can review and increase usage limits in the Cursor dashboard.
(requestId: 3b6246cb-3999-43bf-8d89-879c704a8449)
Your OpenCode Zen account is out of credit. Top it up, then re-trigger Pullfrog.
| 1 | provider error: Upstream request failed: Insufficient account funds |
Pullfrog | Rerun failed job ➔ | View workflow run | via Pullfrog | Using kimi-k3