Skip to content

Fix iOS native change detection - #1975

Merged
Asherlc merged 1 commit into
mainfrom
codex/issue-1765
Jul 26, 2026
Merged

Asherlc merged 1 commit into
mainfrom
codex/issue-1765

Conversation

@Asherlc

@Asherlc Asherlc commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • classify every current Expo prebuild, CocoaPods, and local-module native input as requiring a TestFlight binary
  • keep route, component, and local-module TypeScript changes eligible for OTA-only delivery
  • test the exact workflow classifier and record the deploy reliability incident

Root cause

The TestFlight workflow embedded an incomplete untested regex that omitted the mobile dependency manifest, root lockfile, actual app.config.js, config plugins, and Expo module metadata.

Validation

  • pnpm lint
  • pnpm tsc --noEmit
  • cd packages/server && pnpm tsc --noEmit
  • cd packages/web && pnpm tsc --noEmit
  • pnpm exec vitest run scripts/mobile-deploy-workflows.test.ts --project unit (41 passed)
  • pnpm test (13,648 passed, 21 skipped)

Fixes #1765

Summary by Sourcery

Tighten iOS deploy classification so native build inputs always trigger a TestFlight binary while JS/TS-only changes remain OTA-eligible, and record the incident and mitigation.

Bug Fixes:

  • Ensure the iOS deploy workflow uses a centralized native input pattern that covers dependency manifests, app configuration, config plugins, build/target files, and local Expo module metadata and sources.

Enhancements:

  • Expose the iOS native input classifier as a named environment variable in the deploy workflow and verify its behavior via unit tests that exercise the exact pattern across native and OTA-only paths.

Documentation:

  • Add a production incident entry describing the iOS deploy classifier gap, its impact, root cause, fix, and validation steps.

Summary by cubic

Fix the iOS deploy classifier to catch all native build inputs and trigger TestFlight when required, while keeping JS/TS-only changes OTA. Aligns detection with Expo prebuild/autolinking and addresses #1765.

  • Bug Fixes
    • Add IOS_NATIVE_INPUT_PATTERN to deploy-ios.yml and use it in detection; covers pnpm-lock.yaml, packages/mobile/package.json, app.json, app.config.*, plugins/, build/, targets/, native/, and modules/*/(expo-module.config.json|ios/).
    • Add tests that read the pattern and verify native vs OTA-only paths.
    • Document the incident and fix in production-incident-baseline.md.

Written for commit 58360b7. Summary will update on new commits.

Review in cubic

Keep TestFlight binary releases aligned with Expo prebuild and autolinking inputs instead of treating dependency and module metadata changes as OTA-only.

Closes #1765
Copilot AI review requested due to automatic review settings July 26, 2026 00:57
@cursor

cursor Bot commented Jul 26, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@sourcery-ai

sourcery-ai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

🧙 Sourcery has finished reviewing your pull request!


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Asherlc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 12 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8db01b96-18e7-435b-95b6-c0df4a55c41e

📥 Commits

Reviewing files that changed from the base of the PR and between e905f0c and 58360b7.

📒 Files selected for processing (3)
  • .github/workflows/deploy-ios.yml
  • docs/production-incident-baseline.md
  • scripts/mobile-deploy-workflows.test.ts

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix iOS deploy native-input change detection

🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Centralize iOS native-input classifier to correctly gate TestFlight vs OTA releases.
• Expand detection to include Expo prebuild, lockfile, config plugins, and module metadata.
• Add regression tests and document the production incident and mitigation.
Diagram

graph TD
  A["Git file changes"] --> B["Deploy Check job"] --> C["Detect native changes (grep)"] --> D{"Matches native-input pattern?"}
  D -->|"yes"| E["TestFlight binary deploy"]
  D -->|"no"| F["OTA-only deploy"]
  G["deploy-ios.yml"] --> B
  H["mobile-deploy-workflows.test.ts"] --> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use a dedicated changed-files/paths-filter action
  • ➕ Avoids hand-rolled regex maintenance and escaping issues
  • ➕ Can express path sets declaratively with clearer semantics
  • ➖ Adds third-party action dependency and version pinning responsibility
  • ➖ May be less flexible than a single regex for complex anchors/edge cases
2. Move classifier into a repo script/config shared by CI and tests
  • ➕ Single source of truth without embedding long regex in YAML
  • ➕ Easier to add comments and structure (lists, helper functions)
  • ➖ Requires runtime setup in CI step (node invocation)
  • ➖ Slightly more moving parts than an env var string

Recommendation: The PR’s approach (one named IOS_NATIVE_INPUT_PATTERN in the workflow, validated by parsing the workflow in unit tests) is a good balance: it keeps CI logic self-contained while eliminating the prior “inline, untested regex” failure mode. If the pattern continues to grow, consider migrating to a small shared script or a paths-filter action to improve readability and reduce regex fragility.

Files changed (3) +77 / -1

Tests (1) +41 / -0
mobile-deploy-workflows.test.tsParse workflow env and add regression tests for iOS native-input detection +41/-0

Parse workflow env and add regression tests for iOS native-input detection

• Extends the workflow schema to include the Deploy Check job env and reads IOS_NATIVE_INPUT_PATTERN directly from deploy-ios.yml. Adds a dedicated test suite verifying native-triggering paths (lockfile/config/plugins/modules/ios) and confirming TypeScript/UI-only changes remain OTA-eligible.

scripts/mobile-deploy-workflows.test.ts

Documentation (1) +33 / -0
production-incident-baseline.mdDocument incident: iOS deploy classifier missed native build inputs +33/-0

Document incident: iOS deploy classifier missed native build inputs

• Adds a production incident entry describing symptoms, user impact, root cause (incomplete inline regex), and the mitigation plan. Captures validation steps and the follow-up expectation to extend the single classifier with regression tests when new native inputs arise.

docs/production-incident-baseline.md

Other (1) +3 / -1
deploy-ios.ymlIntroduce shared iOS native-input classifier and use it for deploy gating +3/-1

Introduce shared iOS native-input classifier and use it for deploy gating

• Adds an IOS_NATIVE_INPUT_PATTERN environment variable to the Deploy Check job and switches the change-detection step to use it. The pattern now covers lockfile, mobile manifest/config, plugins, build/targets/native inputs, and local module metadata/iOS sources to correctly require TestFlight binaries for native-impacting changes.

.github/workflows/deploy-ios.yml

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@qodo-code-review

qodo-code-review Bot commented Jul 26, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 154 rules

Grey Divider


Action required

1. Package.swift not classified ✗ Dismissed 🐞 Bug ≡ Correctness
Description
IOS_NATIVE_INPUT_PATTERN does not match packages/mobile/modules/*/Package.swift, so changes to
local-module Swift package manifests can incorrectly produce should_deploy=false and skip a required
TestFlight binary. This reintroduces a native-input false negative despite the expanded classifier.
Code

.github/workflows/deploy-ios.yml[44]

+      IOS_NATIVE_INPUT_PATTERN: '^(pnpm-lock\.yaml$|packages/mobile/(package\.json$|app\.json$|app\.config\.(js|ts|mjs|cjs)$|build/|plugins/|targets/|native/|modules/[^/]+/(expo-module\.config\.json$|ios/)))'
Relevance

⭐⭐⭐ High

Matches PR intent: expand change-detection to avoid skipped deploys; team has accepted similar
workflow classifier coverage fixes.

PR-#1380
PR-#871
PR-#1958

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workflow uses IOS_NATIVE_INPUT_PATTERN to decide whether to set should_deploy=true. The pattern
only matches module paths ending in expo-module.config.json or beginning with ios/, but this repo’s
modules include Package.swift at the module root and it declares iOS Swift package targets—so
changes to it would not match the pattern and could be skipped. The unit tests also do not include a
regression case for Package.swift, so this gap would not be caught.

.github/workflows/deploy-ios.yml[43-47]
.github/workflows/deploy-ios.yml[120-132]
packages/mobile/modules/health-kit/Package.swift[1-18]
scripts/mobile-deploy-workflows.test.ts[107-131]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The iOS deploy workflow's `IOS_NATIVE_INPUT_PATTERN` does not match `packages/mobile/modules/<module>/Package.swift`. Those files define Swift packages used by iOS builds in this repo, so edits can require a new binary but will not trigger `should_deploy=true`.

## Issue Context
Local Expo modules under `packages/mobile/modules/*` include `Package.swift` at the module root (outside `ios/`). The current pattern only matches `expo-module.config.json` or `ios/` under each module.

## Fix Focus Areas
- .github/workflows/deploy-ios.yml[43-44]
- scripts/mobile-deploy-workflows.test.ts[107-132]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread .github/workflows/deploy-ios.yml
@Asherlc
Asherlc merged commit e3de03d into main Jul 26, 2026
98 checks passed
@Asherlc
Asherlc deleted the codex/issue-1765 branch July 26, 2026 01:12
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.

Deploy a new iOS binary when native dependencies or Expo module metadata change

2 participants