Skip to content

Limit CMUX INTERNAL builds to iOS changes - #8812

Merged
azooz2003-bit merged 3 commits into
mainfrom
feat-ios-testflight-path-filter
Jul 24, 2026
Merged

azooz2003-bit merged 3 commits into
mainfrom
feat-ios-testflight-path-filter

Conversation

@azooz2003-bit

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

Copy link
Copy Markdown
Collaborator

Summary:

  • trigger automatic CMUX INTERNAL uploads only for iOS source and direct archive-input changes
  • preserve manual workflow dispatch for intentional rebuilds
  • keep TestFlight notes paths aligned and enforce the contract in static CI

Tests:

  • python3 tests/test_ios_testflight_main_push_filter.py
  • python3 tests/test_ios_testflight_notes.py
  • parsed .github/workflows/ios-testflight.yml and .github/workflows/ci.yml with Ruby YAML
  • git diff --check

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Limit automatic CMUX INTERNAL TestFlight uploads to iOS-affecting changes only. Manual dispatch remains, and TestFlight notes mirror the same path contract with CI checks.

  • Refactors
    • Added a paths filter in .github/workflows/ios-testflight.yml for ios/**, Packages/iOS/**, Packages/Shared/**, Sources/Mobile/**, GhosttyKit inputs (ghostty, ghostty.h), related scripts, and the workflow file.
    • Synced paths in ios/scripts/generate-testflight-notes.sh; added tests to verify exact trigger keys and that workflow and notes paths match; enforced via a new CI step.
    • Preserved concurrency: push runs keyed by SHA; manual runs keyed by run_id.

Written for commit 7c09399. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • iOS TestFlight builds now trigger automatically only when iOS-related files change.
    • TestFlight “What to Test” notes now include a broader set of iOS-related updates.
  • Bug Fixes
    • Improved automated checks to ensure iOS TestFlight workflow trigger rules and the notes path contract stay aligned.
    • Added an extra CI guard step to strengthen TestFlight-related validations.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The TestFlight workflow now runs on main pushes only when iOS-related paths change. TestFlight notes use the same expanded path set, and a CI guard parses the workflow to verify the trigger contract.

Changes

iOS TestFlight path gating

Layer / File(s) Summary
Workflow path filter
.github/workflows/ios-testflight.yml
Main-push execution is restricted to iOS, mobile, package, Ghostty, script, artifact, and workflow paths; related comments describe push and manual-run behavior.
Path contract and notes validation
tests/test_ios_testflight_main_push_filter.py, ios/scripts/generate-testflight-notes.sh
The test parses and validates the workflow’s exact path list, while the notes generator tracks the expanded paths and preserves related TestFlight workflow assertions.
CI guard wiring
.github/workflows/ci.yml
CI runs the TestFlight main-push path-filter validation script.

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

Possibly related PRs

Suggested reviewers: lawrencecchen

🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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 (24 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 Diff touches only workflows, a shell script, and Python tests; no production .swift files or actor-isolation changes are present.
Cmux Swift Blocking Runtime ✅ Passed PASS: The PR diff only changes a Python test file; no .swift files or production Swift code were modified, so the blocking-runtime rule is not implicated.
Cmux Browser Automation Off-Main ✅ Passed Diff only changes an iOS TestFlight test file; no browser.* routing, WebKit/AppKit, or policy-scoped files were touched.
Cmux Expensive Synchronous Load ✅ Passed Diff only changes a test file; no Swift production code or main-actor load path was touched.
Cmux Cache Substitution Correctness ✅ Passed No production Swift/TS/JS code changed; the PR only edits workflows, a shell script, and Python tests, so the cache-substitution rule doesn’t apply.
Cmux No Hacky Sleeps ✅ Passed PASS: The PR only adds deterministic test/YAML path-filter checks; no new sleeps/timers/polling appear, and the rule exempts workflow YAML and test scaffolding.
Cmux Algorithmic Complexity ✅ Passed Only tests and fixed-size workflow/script path filters changed; no scalable production collection scans or worse hot-path algorithms were introduced.
Cmux Swift Concurrency ✅ Passed No Swift source files are changed; the PR only touches tests, workflows, and shell scripts, so the Swift concurrency modernization check is not in scope.
Cmux Swift @Concurrent ✅ Passed No Swift files changed in this PR; the only diff is a Python test file, so the Swift concurrency annotation rule is not applicable.
Cmux Swift Package Boundaries ✅ Passed No production Swift files changed in this diff, so the Swift package-boundary rule is not implicated.
Cmux Swiftpm Lockfiles ✅ Passed HEAD only changes tests/test_ios_testflight_main_push_filter.py; no Package.resolved, package .gitignore, or Xcode package-reference diffs are present.
Cmux Swift Logging ✅ Passed No production Swift files changed; the diff is limited to a Python test, so the Swift logging rules are not implicated.
Cmux User-Facing Error Privacy ✅ Passed Diff only changes workflow path filters, CI wiring, and internal tests/comments; no new user-facing error, alert, or recovery copy was added.
Cmux Full Internationalization ✅ Passed PASS: The only changed file is a test; no production user-facing Swift/web/metadata text or locale catalogs changed, so the i18n rules don’t apply.
Cmux Swiftui State Layout ✅ Passed No SwiftUI sources changed; the PR only touches workflows, a shell script, and tests, so the state-layout rules don’t apply.
Cmux Architecture Rethink ✅ Passed Only workflow, shell, and test files changed; no Swift architecture or lifecycle code was touched.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed No Swift files or window/shortcut code changed; the PR only edits workflows, scripts, and tests, so the auxiliary-window-close-shortcuts rule is not applicable.
Cmux Source Artifacts ✅ Passed Changed paths are intentional workflow, script, and test sources; no local/generated artifacts or scratch dirs were added.
Cmux No Test Or Debug Seam In Production Source ✅ Passed No production Sources/**/*.swift files changed; the diff only touches a test file, so no new test/debug seam in production source was introduced.
Cmux No Ambient Global State ✅ Passed Diff only changes a Python test file; no production Swift source or new global state surface is introduced.
Title check ✅ Passed The title clearly matches the main change: limiting CMUX INTERNAL builds to iOS-related changes.
Description check ✅ Passed The description includes Summary and Testing and is sufficiently complete, though some template sections are omitted.
✨ 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-ios-testflight-path-filter

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.

@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 `@tests/test_ios_testflight_main_push_filter.py`:
- Around line 32-50: Update test_main_push_triggers_only_for_ios_affecting_paths
and its trigger parsing helpers to isolate the push configuration structurally,
including both push.branches and push.paths. Parse quoted and unquoted YAML
entries consistently, then assert branches equal exactly ("main",) and paths
equal exactly IOS_PATHS instead of relying on partial string matches.
🪄 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 Plus

Run ID: 65440564-d5a6-425e-9acc-2ba7d36f8660

📥 Commits

Reviewing files that changed from the base of the PR and between a0ba929 and d25597a.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/ios-testflight.yml
  • ios/scripts/generate-testflight-notes.sh
  • tests/test_ios_testflight_main_push_filter.py

Comment thread tests/test_ios_testflight_main_push_filter.py Outdated
@greptile-apps

greptile-apps Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR narrows the automatic CMUX INTERNAL TestFlight trigger from every main push to only pushes that touch iOS-relevant files (sources, shared packages, GhosttyKit inputs, related build scripts, and the workflow itself). Manual workflow_dispatch is unchanged. The same path list is mirrored in generate-testflight-notes.sh so TestFlight notes only mention commits that actually affect the build.

  • ios-testflight.yml: Replaces the unconditional push: branches: [main] trigger with an explicit paths: filter listing twelve iOS-affecting globs and exact files; workflow_dispatch and concurrency logic are preserved.
  • generate-testflight-notes.sh: Expands the PATHS variable to match the new paths filter exactly, adding ghostty, ghostty.h, and several scripts that were missing from the previous shell-side list.
  • Tests: Deletes the now-contradictory test_ios_testflight_every_main_push.py and replaces it with test_ios_testflight_main_push_filter.py, which validates both the workflow paths: entries and the notes-script PATHS= assignment in lockstep; the new test is wired into CI.

Confidence Score: 5/5

Safe to merge — the change is limited to CI trigger logic and test scaffolding with no production Swift or runtime code touched.

All five changed files are GitHub Actions workflow YAML, a bash notes-generation script, and Python tests. The path filter is correctly mirrored between the workflow and the shell script, the new test enforces that contract in CI, and the now-contradictory every-push test is cleanly removed. No correctness, security, or runtime concerns were found.

No files require special attention.

Important Files Changed

Filename Overview
.github/workflows/ios-testflight.yml Adds a paths: filter to the push trigger; workflow_dispatch, concurrency, and build logic are unchanged and correct.
ios/scripts/generate-testflight-notes.sh Expands the PATHS variable to mirror the new workflow path filter; the added paths (ghostty binary, header, build scripts) are consistent with what the workflow will now trigger on.
tests/test_ios_testflight_main_push_filter.py New test file validating both the workflow paths list and its mirror in the notes script; replaces the deleted every-push test with robust YAML parsing helpers.
tests/test_ios_testflight_every_main_push.py Deleted — previously enforced a no-paths-filter contract that directly contradicts the new behaviour; removal is correct.
.github/workflows/ci.yml Adds a single CI step to run the new path-filter test; ordering and surrounding steps are unchanged.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Push to main branch] --> B{Paths filter match?}
    B -->|"iOS source / scripts / workflow touched"| C[Queue ios-testflight workflow\nConcurrency key: SHA]
    B -->|"Non-iOS change only"| D[Workflow skipped — no upload]
    E[workflow_dispatch] --> F[Queue ios-testflight workflow\nConcurrency key: run_id]
    C --> G{shouldBuild?}
    F --> G
    G -->|"push or workflow_dispatch"| H[Build & upload CMUX INTERNAL\nto TestFlight]
    H --> I[generate-testflight-notes.sh\nuses same PATHS list\nfor 'What to Test' notes]
Loading

Reviews (3): Last reviewed commit: "Validate TestFlight trigger keys exactly" | Re-trigger Greptile

Comment on lines +32 to +38
def trigger_paths(triggers: str) -> tuple[str, ...]:
lines = triggers[triggers.index(" paths:\n") :].splitlines()[1:]
return tuple(
line.removeprefix(' - "').removesuffix('"')
for line in lines
if line.startswith(' - "')
)

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 trigger_paths has no stop condition past the paths: list

The slice starts at paths:\n and runs to the end of the trigger block (bounded by concurrency:), meaning the workflow_dispatch input section is also scanned. Today none of those lines start with - ", so the filter is safe. However, if a future workflow_dispatch input description were wrapped in a YAML block sequence at 6-space indentation (e.g. - "some description"), it would be silently counted as a path entry and the assertion would either pass incorrectly or give a confusing mismatch. An explicit stop at the first non- - line after paths: would make the boundary deterministic.

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!

Comment thread tests/test_ios_testflight_main_push_filter.py
@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@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 `@tests/test_ios_testflight_main_push_filter.py`:
- Around line 70-72: Update the trigger assertions in the test to parse direct
keys under the YAML on: block structurally, using indentation-aware logic
consistent with mapping_block and defining mapping_keys. Assert that schedule is
absent from those parsed keys while preserving the workflow_dispatch check.
🪄 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 Plus

Run ID: 4d1336d7-a76b-4d6e-ab95-093878615cf3

📥 Commits

Reviewing files that changed from the base of the PR and between d25597a and ef3d292.

📒 Files selected for processing (1)
  • tests/test_ios_testflight_main_push_filter.py

Comment thread tests/test_ios_testflight_main_push_filter.py Outdated
@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@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 `@tests/test_ios_testflight_main_push_filter.py`:
- Around line 83-85: Update the assertions in the workflow trigger test around
mapping_keys, sequence_values, and IOS_PATHS to compare sorted collections
rather than their source order. Preserve exact membership and duplicate
detection while allowing workflow triggers and paths to be reordered.
🪄 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 Plus

Run ID: f24f860a-75d5-45d0-8678-e72f15f35c0b

📥 Commits

Reviewing files that changed from the base of the PR and between ef3d292 and 7c09399.

📒 Files selected for processing (1)
  • tests/test_ios_testflight_main_push_filter.py

Comment thread tests/test_ios_testflight_main_push_filter.py
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