Skip to content

Add internal provisioning profile support to iOS TestFlight workflow - #8185

Merged
azooz2003-bit merged 1 commit into
mainfrom
fix/ios-internal-profile-secret
Jul 15, 2026
Merged

azooz2003-bit merged 1 commit into
mainfrom
fix/ios-internal-profile-secret

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jul 15, 2026 •

Copy link
Copy Markdown
Collaborator

Support separate internal and beta provisioning profiles, selected based on bundle ID. Internal builds (dev.cmux.app.internal) now use the internal provisioning profile from GitHub Secrets. Fixes export mismatch error when uploading internal builds to TestFlight.


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


Summary by cubic

Add internal iOS TestFlight support by selecting the correct provisioning profile based on the bundle ID. Fixes export mismatch errors when uploading dev.cmux.app.internal builds.

  • New Features

    • Auto-selects provisioning profile by IOS_BETA_BUNDLE_ID (internal vs beta).
    • Uses IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64 for internal builds and logs which profile is installed.
    • Validates application-identifier and aps-environment=production to prevent mismatches.
  • Migration

    • Add GitHub secret IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64 with the internal profile (base64).
    • Set IOS_BETA_BUNDLE_ID=dev.cmux.app.internal for internal builds.

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

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved iOS beta build provisioning to support both internal and external testing profiles.
    • Added validation to ensure provisioning profiles target the correct app and use production push notifications.
    • Automatically selects and installs the appropriate profile for the selected beta environment.

Support separate internal and beta provisioning profiles, selected based on
bundle ID. Internal builds (dev.cmux.app.internal) now use the internal
provisioning profile. Fixes export mismatch error when uploading internal builds.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jul 16, 2026 3:23am
cmux-staging Building Building Preview, Comment Jul 16, 2026 3:23am

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The iOS TestFlight workflow now selects an internal or beta provisioning profile from secrets based on IOS_BETA_BUNDLE_ID, validates its application identifier and production push entitlement, installs it by UUID, and exports the profile name.

Changes

iOS TestFlight provisioning profile handling

Layer / File(s) Summary
Profile selection and entitlement validation
.github/workflows/ios-testflight.yml
The workflow selects the internal or beta profile secret, validates the expected application identifier and production aps-environment, installs the decoded profile, and exports IOS_BETA_PROVISIONING_PROFILE_NAME.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • manaflow-ai/cmux#7753: Both changes adjust iOS provisioning-profile secret resolution, decoding, validation, and installation.
  • manaflow-ai/cmux#8183: Both changes handle internal versus external bundle IDs using IOS_BETA_BUNDLE_ID.

Suggested reviewers: lawrencecchen

🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description lacks the required template sections for Testing, Demo Video, Review Trigger, and Checklist, so it is largely incomplete. Rewrite the PR description using the repository template and add the missing Testing, Demo Video, Review Trigger, and Checklist sections.
✅ Passed checks (24 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely matches the main change: adding internal provisioning profile support to the iOS TestFlight workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 PR only changes .github/workflows/ios-testflight.yml; no Swift files or actor-isolation-relevant production code changed.
Cmux Swift Blocking Runtime ✅ Passed PR changes only .github/workflows/ios-testflight.yml; no Swift files or blocking/timing synchronization were introduced.
Cmux Browser Automation Off-Main ✅ Passed PR changes only .github/workflows/ios-testflight.yml; no browser automation code, worker routing, or main-actor WebKit/AppKit logic was touched.
Cmux Expensive Synchronous Load ✅ Passed PASS — HEAD changes only .github/workflows/ios-testflight.yml; no Swift source or interactive load paths were added or moved.
Cmux Cache Substitution Correctness ✅ Passed PR only changes a GitHub Actions workflow; no production Swift/TS/JS cache substitution in a persistence/history/undo/snapshot path is present.
Cmux No Hacky Sleeps ✅ Passed The only touched file is workflow YAML, which the rule exempts, and the changed provisioning step contains no sleeps, timers, or polling.
Cmux Algorithmic Complexity ✅ Passed The workflow change is a fixed two-branch shell check over two secrets; it adds no scalable collection scans, repeated filtering, or other complexity regressions.
Cmux Swift Concurrency ✅ Passed Only a GitHub Actions workflow changed; no cmux-owned Swift code or legacy async patterns were introduced.
Cmux Swift @Concurrent ✅ Passed The diff only changes .github/workflows/ios-testflight.yml; no Swift files or concurrency annotations are touched.
Cmux Swift Package Boundaries ✅ Passed Diff changes only .github/workflows/ios-testflight.yml; no Swift production code was added or moved across package boundaries.
Cmux Swiftpm Lockfiles ✅ Passed Only .github/workflows/ios-testflight.yml changed; no SwiftPM manifests, package refs, or .gitignore lockfile policy edits were touched.
Cmux Swift Logging ✅ Passed The PR only changes .github/workflows/ios-testflight.yml; no production Swift/runtime logging was added or modified.
Cmux User-Facing Error Privacy ✅ Passed PASS: the changed strings are CI/workflow logs, not end-user errors, and use operational terms only; no secrets or raw upstream messages were exposed.
Cmux Full Internationalization ✅ Passed Only .github/workflows/ios-testflight.yml changed; it updates CI provisioning/profile logic and operational logs, with no user-facing Swift/web/i18n content.
Cmux Swiftui State Layout ✅ Passed PR only changes .github/workflows/ios-testflight.yml; no Swift/SwiftUI state or layout code was modified, so the rule is not implicated.
Cmux Architecture Rethink ✅ Passed Only .github/workflows/ios-testflight.yml changed; no Swift lifecycle/state wiring or timing/observer workaround was introduced.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed Diff only changes .github/workflows/ios-testflight.yml; no Swift windows/controllers were added or modified, so the auxiliary-window shortcut rule is not applicable.
Cmux Source Artifacts ✅ Passed Only .github/workflows/ios-testflight.yml changed; it’s hand-written CI config, not a generated artifact, cache, or temp output.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Only .github/workflows/ios-testflight.yml changed; no Swift files under Sources/ were touched, so the no-test/debug-seam rule is not applicable.
Cmux No Ambient Global State ✅ Passed The diff only changes .github/workflows/ios-testflight.yml; no Swift source or new ambient global state was introduced.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ios-internal-profile-secret

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.

@greptile-apps

greptile-apps Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds logic to select between a beta and an internal provisioning profile during the iOS TestFlight upload, choosing based on IOS_BETA_BUNDLE_ID to fix an export mismatch when uploading internal builds.

  • The profile-selection branch reads ${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta}, but IOS_BETA_BUNDLE_ID is defined only in the env: block of a later step ("Archive, export, and upload") and is therefore never set when the provisioning profile step runs — the internal branch is unreachable and the mismatch the PR intends to fix persists.
  • The step summary still hardcodes bundle id dev.cmux.app.beta, external-eligible, which no longer describes the actual upload target.

Confidence Score: 2/5

The change introduces a profile-selection branch that is permanently unreachable due to a variable scoping mistake, meaning every upload will still mismatch the bundle ID and fail at export — the core defect the PR was written to fix.

The profile-selection logic gates on IOS_BETA_BUNDLE_ID, which is defined only as a step-level env var in a later step. That variable is invisible here, so the internal branch never executes, the wrong provisioning profile is always installed, and the export fails exactly as before. The fix is not complex, but as written the PR does not solve the stated problem.

.github/workflows/ios-testflight.yml — specifically the env: placement of IOS_BETA_BUNDLE_ID relative to the provisioning profile installation step.

Important Files Changed

Filename Overview
.github/workflows/ios-testflight.yml Adds internal provisioning profile selection gated on IOS_BETA_BUNDLE_ID, but that variable is only a step-level env in a later step, so it is never visible here; the internal branch is dead code and the upload will still mismatch.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Step1 as Install beta provisioning profile
    participant Env as $GITHUB_ENV / Job env
    participant Step2 as Archive, export, and upload

    Note over Step1: IOS_BETA_BUNDLE_ID NOT set in job env
    Step1->>Env: reads IOS_BETA_BUNDLE_ID (unset)
    Note over Step1: Fallback: dev.cmux.app.beta
    Step1->>Step1: Installs BETA profile (always)

    Step2->>Step2: "env: IOS_BETA_BUNDLE_ID=dev.cmux.app.internal (step-scoped)"
    Step2->>Step2: Archives with dev.cmux.app.internal bundle ID
    Note over Step2: Mismatch: internal bundle ID + beta profile = export error
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Step1 as Install beta provisioning profile
    participant Env as $GITHUB_ENV / Job env
    participant Step2 as Archive, export, and upload

    Note over Step1: IOS_BETA_BUNDLE_ID NOT set in job env
    Step1->>Env: reads IOS_BETA_BUNDLE_ID (unset)
    Note over Step1: Fallback: dev.cmux.app.beta
    Step1->>Step1: Installs BETA profile (always)

    Step2->>Step2: "env: IOS_BETA_BUNDLE_ID=dev.cmux.app.internal (step-scoped)"
    Step2->>Step2: Archives with dev.cmux.app.internal bundle ID
    Note over Step2: Mismatch: internal bundle ID + beta profile = export error
Loading

Comments Outside Diff (1)

  1. .github/workflows/ios-testflight.yml, line 552 (link)

    P2 Stale bundle-ID reference in step summary

    The summary still says bundle id \dev.cmux.app.beta`, external-eligiblebut the workflow's normal upload path now targetsdev.cmux.app.internal`. This will mislead anyone reading the Actions summary about which app was actually uploaded.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "Add internal provisioning profile suppor..." | Re-trigger Greptile

Comment on lines +435 to +443
if [ "${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta}" = "dev.cmux.app.internal" ]; then
PROFILE_BASE64="${IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64}"
EXPECTED_APP_ID="7WLXT3NR37.dev.cmux.app.internal"
PROFILE_TYPE="internal"
else
PROFILE_BASE64="${IOS_BETA_PROVISIONING_PROFILE_BASE64}"
EXPECTED_APP_ID="7WLXT3NR37.dev.cmux.app.beta"
PROFILE_TYPE="beta"
fi

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 IOS_BETA_BUNDLE_ID is not in scope when this step runs

IOS_BETA_BUNDLE_ID is defined only in the env: block of the later "Archive, export, and upload to TestFlight" step (line 497). In GitHub Actions, step-level env: variables are scoped exclusively to that step — they are never written to $GITHUB_ENV and are invisible to earlier steps. When "Install beta provisioning profile" executes, IOS_BETA_BUNDLE_ID is unset, so ${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta} always expands to dev.cmux.app.beta, the internal branch is never entered, IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64 is never installed, and the upload step still archives dev.cmux.app.internal with the beta profile — reproducing the exact mismatch this PR is meant to fix.

To resolve this, promote IOS_BETA_BUNDLE_ID to a job-level env: var (under the upload: job's top-level env: block, alongside ASC_API_KEY_ID etc.), so it is visible to every step in the job including the profile installation step. The unset IOS_BETA_BUNDLE_ID line in the marketing_version_override branch will still work correctly at the shell level.

@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: 2

🤖 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 @.github/workflows/ios-testflight.yml:
- Around line 455-464: Update the PlistBuddy lookups assigning APP_ID and
APS_ENVIRONMENT in the provisioning-profile validation block to suppress stderr
and tolerate missing entitlement keys under set -euo pipefail, using the same
handling as install-app-store-provisioning-profile.sh. Preserve the existing
comparisons and descriptive validation errors so missing values fail through
those checks.
- Around line 431-435: Define IOS_BETA_BUNDLE_ID in the provisioning step’s env
block before the run script, using the same evaluation logic as the subsequent
Archive, export, and upload to TestFlight step, including the conditional unset
when INPUT_MARKETING_VERSION_OVERRIDE is present. Ensure the existing bundle-ID
check selects the internal provisioning profile when the resolved value is
dev.cmux.app.internal.
🪄 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: 77dce6dc-2c2e-4de2-ae93-cee3d0c37cd0

📥 Commits

Reviewing files that changed from the base of the PR and between d91d836 and ed19d9b.

📒 Files selected for processing (1)
  • .github/workflows/ios-testflight.yml

Comment on lines +431 to +435
IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64: ${{ secrets.IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64 }}
run: |
set -euo pipefail
if [ -z "${IOS_BETA_PROVISIONING_PROFILE_BASE64:-}" ]; then
echo "Missing IOS_BETA_PROVISIONING_PROFILE_BASE64 secret" >&2
# Determine which profile to use based on bundle ID
if [ "${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta}" = "dev.cmux.app.internal" ]; then

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 | 🔴 Critical | ⚡ Quick win

Pass the bundle ID to the provisioning step.

IOS_BETA_BUNDLE_ID is only defined in the env block of the subsequent Archive, export, and upload to TestFlight step (line 497). Because it is completely absent in the environment of this step, [ "${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta}" = "dev.cmux.app.internal" ] will always evaluate to false. As a result, the workflow will always install the beta profile and never the internal profile.

You must either define IOS_BETA_BUNDLE_ID in this step's env block or lift its evaluation to a prior step. Since the upload step dynamically unsets the variable when INPUT_MARKETING_VERSION_OVERRIDE is present, you can replicate that logic here to ensure the correct bundle ID is used.

🐛 Proposed fix to replicate the bundle ID logic
       - name: Install beta provisioning profile
         env:
           IOS_BETA_PROVISIONING_PROFILE_BASE64: ${{ secrets.IOS_BETA_PROVISIONING_PROFILE_BASE64 }}
           IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64: ${{ secrets.IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64 }}
+          INPUT_MARKETING_VERSION_OVERRIDE: ${{ github.event.inputs.marketing_version_override }}
         run: |
           set -euo pipefail
+
+          # Match the upload step's bundle ID selection logic
+          if [ -n "${INPUT_MARKETING_VERSION_OVERRIDE:-}" ]; then
+            IOS_BETA_BUNDLE_ID="dev.cmux.app.beta"
+          else
+            IOS_BETA_BUNDLE_ID="dev.cmux.app.internal"
+          fi
+
           # Determine which profile to use based on bundle ID
           if [ "${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta}" = "dev.cmux.app.internal" ]; then
📝 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
IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64: ${{ secrets.IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64 }}
run: |
set -euo pipefail
if [ -z "${IOS_BETA_PROVISIONING_PROFILE_BASE64:-}" ]; then
echo "Missing IOS_BETA_PROVISIONING_PROFILE_BASE64 secret" >&2
# Determine which profile to use based on bundle ID
if [ "${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta}" = "dev.cmux.app.internal" ]; then
IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64: ${{ secrets.IOS_BETA_PROVISIONING_PROFILE_INTERNAL_BASE64 }}
INPUT_MARKETING_VERSION_OVERRIDE: ${{ github.event.inputs.marketing_version_override }}
run: |
set -euo pipefail
# Match the upload step's bundle ID selection logic
if [ -n "${INPUT_MARKETING_VERSION_OVERRIDE:-}" ]; then
IOS_BETA_BUNDLE_ID="dev.cmux.app.beta"
else
IOS_BETA_BUNDLE_ID="dev.cmux.app.internal"
fi
# Determine which profile to use based on bundle ID
if [ "${IOS_BETA_BUNDLE_ID:-dev.cmux.app.beta}" = "dev.cmux.app.internal" ]; then
🤖 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 @.github/workflows/ios-testflight.yml around lines 431 - 435, Define
IOS_BETA_BUNDLE_ID in the provisioning step’s env block before the run script,
using the same evaluation logic as the subsequent Archive, export, and upload to
TestFlight step, including the conditional unset when
INPUT_MARKETING_VERSION_OVERRIDE is present. Ensure the existing bundle-ID check
selects the internal provisioning profile when the resolved value is
dev.cmux.app.internal.

Comment on lines 455 to 464
APP_ID="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:application-identifier" "$TMP_PLIST")"
if [ "$APP_ID" != "7WLXT3NR37.dev.cmux.app.beta" ]; then
echo "Beta provisioning profile targets unexpected app ID: $APP_ID" >&2
if [ "$APP_ID" != "$EXPECTED_APP_ID" ]; then
echo "$PROFILE_TYPE provisioning profile targets unexpected app ID: $APP_ID (expected $EXPECTED_APP_ID)" >&2
exit 1
fi
APS_ENVIRONMENT="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:aps-environment" "$TMP_PLIST")"
if [ "$APS_ENVIRONMENT" != "production" ]; then
echo "Beta provisioning profile aps-environment is '$APS_ENVIRONMENT', expected 'production'" >&2
echo "$PROFILE_TYPE provisioning profile aps-environment is '$APS_ENVIRONMENT', expected 'production'" >&2
exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Prevent PlistBuddy from crashing the script when entitlements are missing.

Because set -euo pipefail is active, if the provisioning profile happens to be missing the application-identifier or aps-environment entitlements entirely, PlistBuddy will exit with a non-zero status (1) and the script will terminate immediately. This bypasses the descriptive validation error messages on lines 457 and 462.

As seen in .github/scripts/install-app-store-provisioning-profile.sh, you should discard stderr and append || true to allow the script to proceed and fail gracefully with the intended error messages.

🛡️ Proposed fix to handle missing keys gracefully
-          APP_ID="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:application-identifier" "$TMP_PLIST")"
+          APP_ID="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:application-identifier" "$TMP_PLIST" 2>/dev/null || true)"
           if [ "$APP_ID" != "$EXPECTED_APP_ID" ]; then
             echo "$PROFILE_TYPE provisioning profile targets unexpected app ID: $APP_ID (expected $EXPECTED_APP_ID)" >&2
             exit 1
           fi
-          APS_ENVIRONMENT="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:aps-environment" "$TMP_PLIST")"
+          APS_ENVIRONMENT="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:aps-environment" "$TMP_PLIST" 2>/dev/null || true)"
           if [ "$APS_ENVIRONMENT" != "production" ]; then
             echo "$PROFILE_TYPE provisioning profile aps-environment is '$APS_ENVIRONMENT', expected 'production'" >&2
             exit 1
           fi
📝 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
APP_ID="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:application-identifier" "$TMP_PLIST")"
if [ "$APP_ID" != "7WLXT3NR37.dev.cmux.app.beta" ]; then
echo "Beta provisioning profile targets unexpected app ID: $APP_ID" >&2
if [ "$APP_ID" != "$EXPECTED_APP_ID" ]; then
echo "$PROFILE_TYPE provisioning profile targets unexpected app ID: $APP_ID (expected $EXPECTED_APP_ID)" >&2
exit 1
fi
APS_ENVIRONMENT="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:aps-environment" "$TMP_PLIST")"
if [ "$APS_ENVIRONMENT" != "production" ]; then
echo "Beta provisioning profile aps-environment is '$APS_ENVIRONMENT', expected 'production'" >&2
echo "$PROFILE_TYPE provisioning profile aps-environment is '$APS_ENVIRONMENT', expected 'production'" >&2
exit 1
fi
APP_ID="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:application-identifier" "$TMP_PLIST" 2>/dev/null || true)"
if [ "$APP_ID" != "$EXPECTED_APP_ID" ]; then
echo "$PROFILE_TYPE provisioning profile targets unexpected app ID: $APP_ID (expected $EXPECTED_APP_ID)" >&2
exit 1
fi
APS_ENVIRONMENT="$(/usr/libexec/PlistBuddy -c "Print :Entitlements:aps-environment" "$TMP_PLIST" 2>/dev/null || true)"
if [ "$APS_ENVIRONMENT" != "production" ]; then
echo "$PROFILE_TYPE provisioning profile aps-environment is '$APS_ENVIRONMENT', expected 'production'" >&2
exit 1
fi
🤖 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 @.github/workflows/ios-testflight.yml around lines 455 - 464, Update the
PlistBuddy lookups assigning APP_ID and APS_ENVIRONMENT in the
provisioning-profile validation block to suppress stderr and tolerate missing
entitlement keys under set -euo pipefail, using the same handling as
install-app-store-provisioning-profile.sh. Preserve the existing comparisons and
descriptive validation errors so missing values fail through those checks.

This branch was successfully deployed

1 active deployment
Preview – cmux — ed19d9bb Deployed Jul 16, 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