diff --git a/e2e/BITRISE.md b/e2e/BITRISE.md index 55c8372fb..796803d03 100644 --- a/e2e/BITRISE.md +++ b/e2e/BITRISE.md @@ -52,6 +52,31 @@ For example, editing `platforms/react-native/README.md` matches the coarse `chan 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. +## The `ci-ios` pipeline + +`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. + +### Its trigger carries no `changed_files` + +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. + +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. + +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". + +### The check is self-posted + +`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: + +- a job the plan did not select is a **pass** — there was nothing to build +- a job the plan did select but that never finished is a **failure** + +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. + +### Changing which files select which job + +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. + ## Duplicate PR build cancellation 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 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. -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`. +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. + +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`. diff --git a/e2e/RUNBOOK.md b/e2e/RUNBOOK.md index a6fb280de..1f48f770f 100644 --- a/e2e/RUNBOOK.md +++ b/e2e/RUNBOOK.md @@ -115,3 +115,35 @@ The report keeps a single sticky PR comment, identified by a hidden marker, and in place on every build, so green runs never add a second comment. Because that comment always carries the Tophat install links, it is posted even on a fully green run — a passing build stays installable from the PR. + +## The iOS check failed or never posted + +`Checkout Kit iOS` comes from the `ci-ios` pipeline, described in `BITRISE.md`. Three +layers can break, and the symptom tells you which one. Work down the list in order. + +**The check never appears.** The pipeline did not start. Its `trigger_map` entry has no +file filter, so the usual cause is the branch head: Bitrise reads `trigger_map` from the +pull request's own commit, and a branch older than the entry never triggers. Rebase on +`main` and push. The entry also sets `draft_pull_request_enabled: false`, so a draft posts +nothing until it is marked ready. + +**The check is red but every job says skipped.** `ci-ios-plan` failed, and the reporter +refuses to call an empty selection green. Open that workflow's log. It fetches the changed +file list from GitHub and reads `e2e/config/ios_ci.yml`, so the usual causes are an expired +build token or a malformed config file. + +**The check is red and names a job.** That macOS workflow failed or never finished. The +reporter lists a selected job that produced no result as a failure, so a timeout and a +compile error look different in the summary: a timeout shows as missing, a compile error +shows as failed. Both link back to the Bitrise pipeline. + +**The check is green and every job says skipped.** Expected on a change that touches no +iOS input — documentation, Android, or web. `ci-ios-plan` and `ci-ios-report` still run, +which costs about a minute on Linux. To confirm the selection is right rather than empty by +accident, run the plan locally against the same file list: + +```bash +ruby e2e/scripts/ios_ci_run_plan selected-jobs --changed-file +``` + +It prints a comma-separated job list, or nothing when no macOS job is needed.