Skip to content

Commit 9551275

Browse files
Document the ci-ios pipeline and fix the stale Ruby pin in BITRISE.md
Part of the macOS CI speed-up. Tracked on shop/issues-checkout-kit#1213, under shop/issues-checkout-kit#1202. Docs only. No behaviour change, no code path touched. ## Change **`e2e/BITRISE.md` gains a `ci-ios` section** The file described one pipeline, `e2e`. There are now two, and the second one is a merge gate, so its non-obvious properties need writing down. Three subsections: - *Its trigger carries no `changed_files`.* Unlike `e2e`, the `ci-ios` entry has no filter at all. A required check that never posts leaves a pull request permanently unmergeable, so the pipeline starts on every pull request and the cheap Linux `ci-ios-plan` workflow decides which macOS jobs are worth starting. Same two-layer idea as `e2e`, with the first layer set to "always". - *The check is self-posted.* `ci-ios-report` runs with `should_always_run: workflow`. Bitrise's own pipeline status cannot tell the two kinds of not-run apart: a job the plan did not select is a pass, a job the plan did select but that never finished is a failure. A failed `ci-ios-plan` is a failure, not a green off an empty selection. - *Changing which files select which job.* Edit `e2e/config/ios_ci.yml`, not the workflows. `e2e/test/ios_ci_run_plan_test.rb` enforces set equality between the emitted variables and the `run_if` expressions. The `## Caching` section gains a paragraph for the two caches phases 8 and 9 add, and records the trap that cost time in phase 9: `restore-cache` takes a single `key` input holding one key per line in priority order. There is no plural `keys` input, and `bitrise validate` does not catch that mistake — `e2e/test/bitrise_config_test.rb` does. **`e2e/RUNBOOK.md` gains "The iOS check failed or never posted"** The first question on a red or missing `Checkout Kit iOS` check is which of the three layers broke: the trigger, the plan, or one macOS job. The entry is keyed by symptom, in the order worth checking: | Symptom | Layer | Usual cause | | --- | --- | --- | | Never appears | Trigger | Branch head older than the `trigger_map` entry, or still a draft | | Red, every job skipped | Plan | `ci-ios-plan` failed — expired token or malformed config | | Red, names a job | One macOS job | Failed, or timed out and reported nothing | | Green, every job skipped | None | Expected on a docs, Android or web change | The last row is the one that looks wrong and is not, so it carries the command to confirm the selection is right rather than empty by accident: ```bash ruby e2e/scripts/ios_ci_run_plan selected-jobs --changed-file <path> ``` **🟡 Stale Ruby version** `BITRISE.md` claimed `ruby: 3.3.6`. `e2e/bitrise.yml` pins `3.4:installed`. The doc has been wrong since that pin changed, and it is the line a reader copies when adding a workflow. The correction also explains the `:installed` suffix, which is the part that matters: it tells each stack to use its own preinstalled 3.4.x rather than compiling one from source. ## Verification - `shadowenv exec -- ./scripts/test_ruby` — green. - The runbook command was run before it was written down. `Package.swift` prints `swift-package-tests,swift-samples,react-native-build-ios,react-native-test-ios`; `README.md` prints nothing. An earlier draft omitted the `selected-jobs` subcommand and errored with `Unknown command "--changed-file"`.
1 parent 1780924 commit 9551275

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

e2e/BITRISE.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,31 @@ For example, editing `platforms/react-native/README.md` matches the coarse `chan
5252

5353
The GitHub checks are kept non-blocking while the suite stabilizes; they become merge-blocking only once the "Checkout Kit E2E" check is marked required in branch protection.
5454

55+
## The `ci-ios` pipeline
56+
57+
`ci-ios` is the second pipeline in `e2e/bitrise.yml`. It runs the four macOS jobs that used to run on GitHub Actions: the Swift package tests, the Swift sample build and test, the React Native iOS sample build, and the React Native iOS tests. It is separate from `e2e` rather than a set of extra workflows inside it, because Bitrise reports one status per pipeline: sharing one would tie a merge gate to the BrowserStack device flake that the E2E checks deliberately keep non-blocking.
58+
59+
### Its trigger carries no `changed_files`
60+
61+
Unlike `e2e`, the `ci-ios` `trigger_map` entry has no filter at all. `ci-ios` is a merge-blocking check, and a required check that never posts leaves a pull request permanently unmergeable — so the pipeline has to start on every pull request, including a docs-only one.
62+
63+
Selection happens inside the pipeline instead. The Linux `ci-ios-plan` workflow reads the pull request's changed files, applies the shared filter groups in `.ci/changed-file-filters.yml` through `e2e/config/ios_ci.yml`, and publishes one `CI_IOS_*` variable per job with `share-pipeline-variable`. Each macOS workflow guards on its own variable with `run_if`. A change that needs no macOS job runs the Linux plan and the report, and nothing else.
64+
65+
This is the same two-layer idea as `e2e` — a cheap first pass, then a precise runtime decision — with the first layer set to "always".
66+
67+
### The check is self-posted
68+
69+
`ci-ios-report` runs with `should_always_run: workflow` and posts the `Checkout Kit iOS` Check Run itself, through `e2e/scripts/report_ios_ci_results`. Bitrise's own pipeline status cannot tell the two kinds of not-run apart:
70+
71+
- a job the plan did not select is a **pass** — there was nothing to build
72+
- a job the plan did select but that never finished is a **failure**
73+
74+
The reporter also fails when `ci-ios-plan` itself fails, rather than reporting green off an empty selection. `e2e/test/ios_ci_reporter_test.rb` pins all three cases.
75+
76+
### Changing which files select which job
77+
78+
Edit `e2e/config/ios_ci.yml`, not the workflows. `e2e/test/ios_ci_run_plan_test.rb` asserts set equality between the variables the plan emits and the `run_if` expressions parsed out of `e2e/bitrise.yml`, so a job added on one side and not the other fails the Ruby tests.
79+
5580
## Duplicate PR build cancellation
5681

5782
Duplicate in-progress PR pipelines are cancelled by Bitrise native Rolling builds rather than a repo-owned cancellation script. Under **Project settings > Builds > Build strategy**, **Abort builds triggered by pull requests** and **Abort running builds** are enabled, so a newer PR build cancels the older one.
@@ -175,4 +200,6 @@ The pipeline uses Bitrise cache steps for key-based pnpm/CocoaPods/Gradle cache
175200

176201
Do not add `activate-build-cache-for-xcode` or `activate-build-cache-for-gradle`; the Bitrise Build Cache add-on is disabled for Shopify Bitrise apps.
177202

178-
Ruby and Node versions are pinned in `e2e/bitrise.yml` via the Bitrise `tools:` configuration (`ruby: 3.3.6`, `nodejs: 22.14.0`), which Bitrise installs before each workflow runs. Pin exact versions that the target stacks preinstall so setup stays fast and reproducible; a version the stack does not ship is installed on demand and is slower. pnpm is pinned separately through Corepack via the `packageManager` field in `platforms/react-native/package.json`.
203+
The `ci-ios` macOS jobs add two more caches. DerivedData is keyed on `Package.resolved` and the relevant `Podfile.lock`, and the build scripts no longer pass `xcodebuild clean`, which would delete the restored copy. ccache is keyed on the branch and commit, with branch-then-architecture prefixes as fallbacks, so each build starts from the last one on its branch. `restore-cache` takes a single `key` input holding one key per line in priority order; there is no plural `keys` input, and `bitrise validate` does not catch that mistake, so `e2e/test/bitrise_config_test.rb` does.
204+
205+
Ruby and Node versions are pinned in `e2e/bitrise.yml` via the Bitrise `tools:` configuration (`ruby: "3.4:installed"`, `nodejs: 22.14.0`), which Bitrise installs before each workflow runs. The `:installed` suffix tells each stack to use its own preinstalled 3.4.x rather than compiling one from source. Pin exact versions that the target stacks preinstall so setup stays fast and reproducible; a version the stack does not ship is installed on demand and is slower. pnpm is pinned separately through Corepack via the `packageManager` field in `platforms/react-native/package.json`.

e2e/RUNBOOK.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,35 @@ The report keeps a single sticky PR comment, identified by a hidden marker, and
115115
in place on every build, so green runs never add a second comment. Because that comment
116116
always carries the Tophat install links, it is posted even on a fully green run — a passing
117117
build stays installable from the PR.
118+
119+
## The iOS check failed or never posted
120+
121+
`Checkout Kit iOS` comes from the `ci-ios` pipeline, described in `BITRISE.md`. Three
122+
layers can break, and the symptom tells you which one. Work down the list in order.
123+
124+
**The check never appears.** The pipeline did not start. Its `trigger_map` entry has no
125+
file filter, so the usual cause is the branch head: Bitrise reads `trigger_map` from the
126+
pull request's own commit, and a branch older than the entry never triggers. Rebase on
127+
`main` and push. The entry also sets `draft_pull_request_enabled: false`, so a draft posts
128+
nothing until it is marked ready.
129+
130+
**The check is red but every job says skipped.** `ci-ios-plan` failed, and the reporter
131+
refuses to call an empty selection green. Open that workflow's log. It fetches the changed
132+
file list from GitHub and reads `e2e/config/ios_ci.yml`, so the usual causes are an expired
133+
build token or a malformed config file.
134+
135+
**The check is red and names a job.** That macOS workflow failed or never finished. The
136+
reporter lists a selected job that produced no result as a failure, so a timeout and a
137+
compile error look different in the summary: a timeout shows as missing, a compile error
138+
shows as failed. Both link back to the Bitrise pipeline.
139+
140+
**The check is green and every job says skipped.** Expected on a change that touches no
141+
iOS input — documentation, Android, or web. `ci-ios-plan` and `ci-ios-report` still run,
142+
which costs about a minute on Linux. To confirm the selection is right rather than empty by
143+
accident, run the plan locally against the same file list:
144+
145+
```bash
146+
ruby e2e/scripts/ios_ci_run_plan selected-jobs --changed-file <path>
147+
```
148+
149+
It prints a comma-separated job list, or nothing when no macOS job is needed.

0 commit comments

Comments
 (0)