Repository navigation
Unblock internal TestFlight: strip embedded static frameworks, fix assign jobs - #8235
Conversation
…sign jobs Three stacked failures kept every internal beta out of TestFlight: 1. ITMS-90208 processing rejection: iroh-ffi's Iroh.framework binary is a static archive, and Xcode embeds it into cmux.app/Frameworks/ anyway. ASC validates the embedded framework BINARY, which has no Mach-O minimum-OS load command, so every upload containing Iroh was rejected in processing regardless of deployment target or the framework's Info.plist. The re-sign path now strips embedded static-archive frameworks (their code is already statically linked into the app executable; a load-command gate proves it), and the IPA verifier hard-fails if one is still embedded. 2. Internal group assignment failed instantly: the workflow passed both CMUX_TESTFLIGHT_INTERNAL_GROUP_ID and _NAME, and the assign script errors when both are set. Only the id is passed now. 3. assign-external-group hung 40 minutes per run polling dev.cmux.app.beta for builds that now upload to dev.cmux.app.internal. Job removed; the decide job's assign-only retry logic now keys off the internal assignment job, and the internal job uploads the assignment-state artifact name decide checks. Also restores IPHONEOS_DEPLOYMENT_TARGET to 18.4. The 18.0/17.5 lowering chased the ITMS-90208 symptom at the wrong layer, and 17.5 broke the build outright (packages declare .iOS(.v18); run #509 failed with 'compiling for iOS 17.5, but module CMUXMobileCore has a minimum deployment target of iOS 18.0'). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR narrows the iOS TestFlight workflow to the internal app and aligns assignment retry artifacts and inputs. It also raises the deployment target and adds static-archive framework validation and removal during manual IPA signing. ChangesiOS TestFlight delivery
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
Greptile SummaryThis PR unblocks internal TestFlight uploads that were failing at App Store Connect processing (ITMS-90208) and fixes silent CI failures in the assignment jobs. The root causes — an embedded static-archive
Confidence Score: 3/5Safe to merge for unblocking TestFlight uploads, but the assign-only retry path for the internal group will silently no-op if assignment ever fails after a successful upload. The shell script and xcconfig changes are solid and directly fix the ITMS-90208 rejection. The workflow changes correctly remove the polling-wrong-bundle-ID external job and fix the group ID/name mutual-exclusion bug. The one concrete gap: assign-internal-group lacks always() on its if condition, so scheduled runs that hit shouldAssignOnly=true skip the job entirely. A secondary assignment failure after a good upload would strand the build unassigned with no automated recovery. .github/workflows/ios-testflight.yml — specifically the assign-internal-group job if condition and the two stale external labels in the decide job. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[decide job] -->|should_build=true| B[upload job]
A -->|should_assign_only=true| D
B --> C{upload success?}
C -->|yes| D[assign-internal-group]
C -->|no| E[workflow fails]
D --> F{assignment done?}
F -->|yes| G[upload artifact:
ios-testflight-assignment-state-complete]
F -->|no| H[workflow step fails
no artifact uploaded]
G --> I[next decide run:
lastAssignmentSucceeded=true]
H --> J[next decide run:
shouldAssignOnly=true]
J --> K[assign-internal-group SKIPPED
missing always on if condition]
style K fill:#ff9999
style G fill:#99ff99
%%{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"}}}%%
flowchart TD
A[decide job] -->|should_build=true| B[upload job]
A -->|should_assign_only=true| D
B --> C{upload success?}
C -->|yes| D[assign-internal-group]
C -->|no| E[workflow fails]
D --> F{assignment done?}
F -->|yes| G[upload artifact:
ios-testflight-assignment-state-complete]
F -->|no| H[workflow step fails
no artifact uploaded]
G --> I[next decide run:
lastAssignmentSucceeded=true]
H --> J[next decide run:
shouldAssignOnly=true]
J --> K[assign-internal-group SKIPPED
missing always on if condition]
style K fill:#ff9999
style G fill:#99ff99
|
Every internal beta upload was rejected by App Store Connect during processing with ITMS-90208. Root cause: iroh-ffi's Iroh.framework binary is a static archive (
ar), and Xcode embeds it intocmux.app/Frameworks/anyway. ASC validates the embedded framework binary, which has no Mach-O minimum-OS load command, so the rejection fired regardless of deployment target — the1.0.2-cmux.2Info.plist pin and the 18.4→18.0→17.5 deployment-target changes were all aimed at the wrong layer. The external beta's history of good builds all predate the Iroh integration (#7908).Fixes:
ios/scripts/upload-testflight.sh: the manual re-sign path strips embedded static-archive frameworks before signing (their code is already statically linked into the app executable; anotool -Lgate proves nothing dynamically links them).verify_ipa_framework_minimum_os_versionsnow hard-fails on any embedded static archive, covering the automatic path too..github/workflows/ios-testflight.yml: the internal assign job passed both group id and name, which the assign script rejects (set only one of --group-id or --group-name) — every internal assignment failed in seconds. Only the id is passed now. Theassign-external-groupjob is removed: it polleddev.cmux.app.betafor builds that upload todev.cmux.app.internal, hanging 40 minutes per run. The decide job's assign-only retry now keys off the internal assignment job and its artifact.ios/Config/Shared.xcconfig: restoresIPHONEOS_DEPLOYMENT_TARGET = 18.4. The 17.5 lowering broke the build (run https://github.com/manaflow-ai/cmux/actions/runs/29469612881 failed:compiling for iOS 17.5, but module 'CMUXMobileCore' has a minimum deployment target of iOS 18.0).Follow-up (not this PR): make manaflow-ai/iroh-ffi ship a dynamic framework or a plain static-library target so nothing needs stripping.
🤖 Generated with Claude Code
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Unblocks internal TestFlight uploads by stripping embedded static frameworks and fixing the internal assignment flow, resolving ITMS-90208 and hung jobs. Restores the iOS deployment target to 18.4 to match package minimums.
ios/scripts/upload-testflight.sh: strip embedded static-archive frameworks before re-signing and hard-fail IPA verification if any remain (preventsITMS-90208)..github/workflows/ios-testflight.yml: pass onlyCMUX_TESTFLIGHT_INTERNAL_GROUP_IDto the assign script; remove the external assignment job that polleddev.cmux.app.betaand timed out; publishios-testflight-assignment-state-completeso decide’s assign-only retry keys off the internal job.ios/Config/Shared.xcconfig: setIPHONEOS_DEPLOYMENT_TARGETback to 18.4 to align with.iOS(.v18)Swift packages and fix build failures.Written for commit b8da97a. Summary will update on new commits.
Summary by CodeRabbit
New Features
Bug Fixes
Maintenance