Skip to content

Fix iOS App Store bundle identity - #7806

Closed
lawrencecchen wants to merge 8 commits into
mainfrom
feat-fix-appstore-bundle-id
Closed

lawrencecchen wants to merge 8 commits into
mainfrom
feat-fix-appstore-bundle-id

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Fix the production iOS lane to build and sign com.cmux.app, matching App Store Connect app 6783338052.

Add a live app-record bundle ID check before upload so a mismatched binary fails before delivery. Align the profile resolver, validation defaults, workflow summary, and App Store release docs.

Verification:

  • bash -n on the upload, validation, and profile scripts
  • live ASC app lookup returned com.cmux.app
  • downloaded cmux Distribution profile validated as 7WLXT3NR37.com.cmux.app with production APNs and Sign in with Apple
  • profile installer accepted and installed that profile

No app runtime behavior changes.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

Medium Risk
Changes production iOS release identity, signing validation, and App Store upload targeting—mistakes could block releases or mis-route uploads, though gates are designed to fail closed rather than ship wrong artifacts.

Overview
Production iOS App Store signing and release tooling now default to com.cmux.app instead of com.cmuxterm.app, including the CI provisioning-profile installer, upload-testflight.sh appstore lane, docs, and the production workflow summary (CI profile name cmux App Store CI).

Fail-closed gates were added so a wrong binary cannot reach App Store Connect: verify-ipa-release-identity.sh runs on every export path and checks Info.plist bundle id plus signed/profile application-identifier; the appstore upload path requires a numeric ASC app id (require-numeric-app-store-id.sh) and compares the live ASC app record’s bundleId to the built lane before asc builds upload. Archive bundle-id validation now fails when the identifier is missing, not only on mismatch.

validate-app-store-release.sh no longer falls back to a bundle id for --app; it enforces the numeric app id helper. APNs routePolicy treats com.cmux.app as production (legacy com.cmuxterm.app retained). CI runs tests/test_ios_app_store_identity.py for the new gates.

Reviewed by Cursor Bugbot for commit cc4e175. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Align the production iOS App Store identity to bundle id com.cmux.app across build/signing, CI, docs, and APNs. Add fail-closed gates that verify the final IPA and the App Store Connect app before upload.

  • Bug Fixes

    • Defaulted to com.cmux.app in provisioning installer, upload lane, validation, and CI; renamed CI profile to cmux App Store CI; updated docs and workflow summary.
    • Updated APNs route policy to treat com.cmux.app as production (keeps com.cmuxterm.app and dev.cmux.app.beta); enforced numeric ASC app id via require-numeric-app-store-id.sh in upload-testflight.sh and validate-app-store-release.sh (no bundle-id fallback), with CI coverage.
  • New Features

    • verify-ipa-release-identity.sh (run by upload-testflight.sh) verifies the final IPA’s Info.plist bundle id, signed application-identifier, and embedded profile match 7WLXT3NR37.com.cmux.app.
    • Early ASC app-record check fails if the live bundleId doesn’t match the built bundle id; tightened archive bundle-id validation when missing; added a CI test for the final IPA identity gate.

Written for commit cc4e175. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Updated iOS App Store/TestFlight signing and lane configuration to use com.cmux.app (instead of com.cmuxterm.app).
    • Added stricter validation to verify the final IPA’s code-signing identity and embedded provisioning profile identity, and to ensure the configured bundle ID matches the App Store Connect app before upload.
    • Enforced numeric App Store Connect app IDs.
  • Tests

    • Added a CI identity gate and automated tests covering passing and failing scenarios.
  • Documentation

    • Updated iOS App Store setup docs, workflow summaries, and the App Identity checklist to reflect com.cmux.app.

@vercel

vercel Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Canceled Canceled Jul 10, 2026 10:53am
cmux-staging Building Building Preview, Comment Jul 10, 2026 10:53am

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The iOS App Store configuration now uses com.cmux.app across scripts, provisioning profiles, CI summaries, and documentation. App Store Connect uploads validate bundle identity, release validation requires numeric app IDs, and CI tests IPA identity checks.

Changes

App Store identity alignment

Layer / File(s) Summary
Bundle identifier defaults and documentation
.github/scripts/install-app-store-provisioning-profile.sh, .github/workflows/ios-app-store.yml, ios/README.md, ios/AppStoreReview/*, ios/scripts/upload-testflight.sh
App Store defaults, provisioning profile names, CI output, setup instructions, and checklist entries now reference com.cmux.app.
Numeric App Store app ID validation
ios/scripts/require-numeric-app-store-id.sh, ios/scripts/validate-app-store-release.sh, ios/scripts/upload-testflight.sh
App Store IDs are validated as numeric values before release validation and ASC uploads.
ASC and final IPA identity gates
ios/scripts/upload-testflight.sh, ios/scripts/verify-ipa-release-identity.sh
Archive and ASC bundle identifiers are checked, and final IPAs are verified against bundle, signing entitlement, and provisioning profile identities.
Identity verifier tests and CI wiring
tests/test_ios_app_store_identity.py, .github/workflows/ci.yml
Adds fixture-based success and failure tests and runs them in CI workflow guard tests.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux User-Facing Error Privacy ❌ Error verify-ipa-release-identity.sh prints the expected TEAM.BUNDLE app id in command output, exposing an internal team id. Redact the team id from user-visible output; keep the full app id only in sanitized internal logs, and make success/error text bundle-id only.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (23 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed The PR diff contains no Swift files, only scripts/docs/tests/TS, so it cannot introduce Swift actor-isolation regressions.
Cmux Swift Blocking Runtime ✅ Passed No Swift files changed; the diff only touches shell scripts/docs, so the Swift blocking-runtime rule is not implicated.
Cmux Browser Automation Off-Main ✅ Passed No changed file touches browser automation routing or WebKit/AppKit main-actor policy; the diff is iOS signing/APNs/docs only.
Cmux Expensive Synchronous Load ✅ Passed No Swift files changed; the diff only touches shell scripts, so the Swift expensive-sync-load rule doesn’t apply.
Cmux Cache Substitution Correctness ✅ Passed No cache-substitution pattern found: the TS change only updates APNs bundle-id constants/tests, and the other edits are shell/docs, not cache-backed persistence/history/snapshot code.
Cmux No Hacky Sleeps ✅ Passed Diff adds validation/identity checks only; no new sleeps, timers, polling, or wall-clock waits in changed shell/runtime scripts.
Cmux Algorithmic Complexity ✅ Passed The new shell/Python paths are bounded or single-pass; no nested rescans or hot-path re-sorts were introduced.
Cmux Swift Concurrency ✅ Passed Diff only changes shell scripts; no Swift files or Swift concurrency patterns were introduced.
Cmux Swift @Concurrent ✅ Passed PR diff has no Swift files, so the Swift @concurrent rules are not applicable.
Cmux Swift File And Package Boundaries ✅ Passed No Swift files were changed; the PR only touches shell scripts, docs, workflow YAML, and tests, so the Swift file/package boundary rule is not applicable.
Cmux Swiftpm Lockfiles ✅ Passed PR diff touches scripts/workflows/docs only; no Package.swift, Package.resolved, Xcode project, or cmux-owned .gitignore changes, so the SwiftPM lockfile policy isn’t violated.
Cmux Swift Logging ✅ Passed No production Swift files changed; the diff only touches scripts, docs, tests, and TS, so the Swift logging rule isn’t implicated.
Cmux Full Internationalization ✅ Passed Only operational shell scripts changed; no Swift UI, web/messages, catalogs, or end-user copy was introduced, and bundle IDs/config tokens are exempt.
Cmux Swiftui State Layout ✅ Passed The PR only changes shell scripts; no SwiftUI or state-layout code is touched, so the rule is not applicable.
Cmux Architecture Rethink ✅ Passed No Swift files changed; the commit only updates iOS bash scripts, so the Swift architectural rethink rule isn’t applicable.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR changes only shell scripts/docs; no Swift windows, controllers, or WindowGroup code were touched, so the auxiliary-window shortcut rule is not in scope.
Cmux Source Artifacts ✅ Passed All changed paths are intentional scripts, docs, tests, config, or source; no logs, caches, temp, build, or other artifact directories were added.
Cmux No Test Or Debug Seam In Production Source ✅ Passed No Swift files under any Sources/ path were changed; the PR only modifies shell scripts, so the production-source seam rule is not implicated.
Cmux No Ambient Global State ✅ Passed The PR changes no Swift source files, and the rule applies only to production Swift code, so there is no applicable ambient-global-state violation.
Title check ✅ Passed The title clearly matches the main change: aligning the iOS App Store bundle identity.
Description check ✅ Passed The description covers the summary and testing, and is mostly aligned with the template.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-fix-appstore-bundle-id

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.


(
export "${asc_env[@]}"
local app_json app_bundle_identifier

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local variables in subshell

High Severity

The new App Store Connect bundle-id check declares app_json and app_bundle_identifier with local inside a ( … ) subshell. In Bash, local is only valid inside a function body, so the production upload_app_store_with_asc path aborts before asc apps view or upload run.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f6bc3bb. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rejected after reproduction: this subshell executes inside upload_app_store_with_asc, so local remains in a function context. The exact pattern succeeds under macOS /bin/bash 3.2.57 and Bash 5.3.9. No code change needed.

— Claude Code

@greptile-apps

greptile-apps Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR updates the production iOS App Store identity. The main changes are:

  • Switches App Store signing defaults and docs to com.cmux.app.
  • Adds a shared numeric App Store app-id check for release scripts.
  • Verifies the final IPA bundle id, signed entitlements, and embedded profile before upload.
  • Checks the live App Store Connect app bundle id before delivery.
  • Adds CI coverage for the new identity and app-id guards.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
ios/scripts/upload-testflight.sh Updates the App Store lane bundle id, runs the numeric app-id guard before ASC upload commands, verifies the final IPA identity, and checks the ASC app record bundle id.
ios/scripts/validate-app-store-release.sh Removes the bundle-id fallback and requires a numeric App Store app id before ASC validation commands run.
ios/scripts/require-numeric-app-store-id.sh Adds a shared helper that rejects missing or non-numeric App Store app ids.
ios/scripts/verify-ipa-release-identity.sh Adds a final IPA identity gate for bundle id, signed application identifier, and embedded profile application identifier.
web/services/apns/routePolicy.ts Treats com.cmux.app as a production APNs bundle id while keeping the existing production ids.

Reviews (8): Last reviewed commit: "Require numeric App Store app IDs" | Re-trigger Greptile

IOS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

APP="${ASC_APP_ID:-${IOS_APPSTORE_APP_ID:-${IOS_APPSTORE_BUNDLE_ID:-com.cmuxterm.app}}}"
APP="${ASC_APP_ID:-${IOS_APPSTORE_APP_ID:-${IOS_APPSTORE_BUNDLE_ID:-com.cmux.app}}}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Bundle ID Reaches App-ID Commands

When this script runs without ASC_APP_ID or IOS_APPSTORE_APP_ID, APP falls back to com.cmux.app, but the later asc ... --app "$APP" calls expect the numeric App Store Connect app id. That makes a local/default validation run fail at the first ASC command with an invalid app identifier instead of validating the production app.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4e9abf6. Validation now requires ASC_APP_ID/IOS_APPSTORE_APP_ID or an explicit numeric --app value and fails before invoking asc when none is configured; the usage text now says app-id.

— Claude Code

IOS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

APP="${ASC_APP_ID:-${IOS_APPSTORE_APP_ID:-${IOS_APPSTORE_BUNDLE_ID:-com.cmuxterm.app}}}"
APP="${ASC_APP_ID:-${IOS_APPSTORE_APP_ID:-}}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Bundle IDs Still Pass

This removes the default bundle-id fallback, but callers can still pass --app com.cmux.app or set ASC_APP_ID=com.cmux.app. The script only checks that APP is non-empty before passing it into the later asc ... --app "$APP" commands, so stale local invocations still fail late at the App Store Connect command instead of being rejected by the script. Add an early numeric app-id check, or explicitly resolve bundle ids before any ASC command is built.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the latest commit. The validation script now requires ^[0-9]+$ before constructing any asc command; both a missing ID and an explicit --app com.cmux.app fail immediately with script-owned diagnostics.

— Claude Code

(
export "${asc_env[@]}"
local app_json app_bundle_identifier
app_json="$(asc apps view --id "$ASC_APP_ID" --output json)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Validate app id

The upload path uses ASC_APP_ID in asc apps view before checking that it is a numeric App Store app id. When a local run or repo variable still has ASC_APP_ID=com.cmux.app, this lane reaches the ASC command and then fails through the CLI or JSON parsing instead of stopping with the script-owned app-id error used by the validation script. Add the same numeric guard before this command and before asc builds upload.

(
export "${asc_env[@]}"
local app_json app_bundle_identifier
app_json="$(asc apps view --id "$ASC_APP_ID" --output json)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Validate app ids This upload path still lets a stale bundle identifier in ASC_APP_ID reach the ASC CLI before the script checks that it is a numeric App Store Connect app id. For example, ASC_APP_ID=com.cmux.app passes the existing non-empty check, then this new asc apps view --id "$ASC_APP_ID" call can fail through the CLI and JSON parsing instead of the script-owned diagnostic used by the release validation script. Add the numeric guard before the first ASC command in this path.

Suggested change
app_json="$(asc apps view --id "$ASC_APP_ID" --output json)"
if [[ ! "$ASC_APP_ID" =~ ^[0-9]+$ ]]; then
echo "error: ASC_APP_ID must be numeric (got '$ASC_APP_ID')" >&2
exit 2
fi
app_json="$(asc apps view --id "$ASC_APP_ID" --output json)"

Comment thread ios/scripts/upload-testflight.sh
(
export "${asc_env[@]}"
local app_json app_bundle_identifier
app_json="$(asc apps view --id "$ASC_APP_ID" --output json)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Validate App Id This upload path still allows ASC_APP_ID=com.cmux.app to pass the existing non-empty check and reach asc apps view --id "$ASC_APP_ID". In that case the lane fails through the ASC command or JSON handling instead of stopping with the script-owned numeric app-id error used by the release validation script. Add the same numeric guard before this first ASC command so both the app-record check and asc builds upload only receive App Store Connect app ids.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 31c0e57. Configure here.

Comment thread tests/test_ios_app_store_identity.py
(
export "${asc_env[@]}"
local app_json app_bundle_identifier
app_json="$(asc apps view --id "$ASC_APP_ID" --output json)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Validate app id early

ASC_APP_ID is only checked for being non-empty before this asc apps view --id "$ASC_APP_ID" call. If a local run or repo variable still has ASC_APP_ID=com.cmux.app, the new app-record check sends that bundle id to the ASC CLI before the script can produce its own numeric app-id error. Add the same numeric guard used by the release validator before the first ASC command in this upload path.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ios/scripts/verify-ipa-release-identity.sh`:
- Line 27: Resolve and normalize the relative IPA path before the subshell
changes directories, then use that resolved path in the unzip command. Update
the extraction logic near the existing IPA validation and die handling so both
relative and absolute values of IPA_PATH remain accessible under WORKDIR.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 69826806-0ee6-4ca3-9c83-5bbae271a697

📥 Commits

Reviewing files that changed from the base of the PR and between ee8c56b and cc4e175.

📒 Files selected for processing (5)
  • ios/scripts/require-numeric-app-store-id.sh
  • ios/scripts/upload-testflight.sh
  • ios/scripts/validate-app-store-release.sh
  • ios/scripts/verify-ipa-release-identity.sh
  • tests/test_ios_app_store_identity.py

WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT

( cd "$WORKDIR" && unzip -q "$IPA_PATH" ) || die "could not unzip IPA: $IPA_PATH"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve relative IPA paths during extraction.

Line 27 changes directories before resolving $IPA_PATH. A valid relative path passes Line 18 but then cannot be found under $WORKDIR, blocking release verification.

Proposed fix
-( cd "$WORKDIR" && unzip -q "$IPA_PATH" ) || die "could not unzip IPA: $IPA_PATH"
+unzip -q "$IPA_PATH" -d "$WORKDIR" || die "could not unzip IPA: $IPA_PATH"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
( cd "$WORKDIR" && unzip -q "$IPA_PATH" ) || die "could not unzip IPA: $IPA_PATH"
unzip -q "$IPA_PATH" -d "$WORKDIR" || die "could not unzip IPA: $IPA_PATH"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ios/scripts/verify-ipa-release-identity.sh` at line 27, Resolve and normalize
the relative IPA path before the subshell changes directories, then use that
resolved path in the unzip command. Update the extraction logic near the
existing IPA validation and die handling so both relative and absolute values of
IPA_PATH remain accessible under WORKDIR.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Superseded by merged #7809, which ships the same App Store bundle identity correction with stronger end-to-end lane coverage. Closing this duplicate instead of resolving conflicts.

This branch was successfully deployed

1 active deployment
Preview – cmux — cc4e1756 Deployed Jul 10, 2026 by vercel[bot]
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.

1 participant