Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions e2e/BITRISE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Validate the configuration locally with:
bitrise validate -c e2e/bitrise.yml
```

## PR trigger
## PR and manual runs

The `e2e` pipeline defines a target-based pull request trigger in `e2e/bitrise.yml`. The trigger uses Bitrise `changed_files.regex` as a coarse source-tree gate for Checkout Kit platform, protocol, shared filter, package, and E2E paths. Target-based triggers are defined on each pipeline so one pull request can start both `e2e` and `ci-ios`; the legacy project-level `trigger_map` starts only its first match and must not be restored. Bitrise does not support the same named include/exclude filter objects as GitHub Actions, so `platforms` level filtering is enforced by `e2e/config/matrix.yml` and `e2e/scripts/e2e_matrix_to_browserstack_run_plan` after the pipeline starts (essentially fulfilling the same need that `dorny/paths-filter` holds in GitHub Actions).

Expand All @@ -52,6 +52,8 @@ 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.

A manually started pipeline has no pull request file list, so it selects every application in the E2E matrix. Choose the branch and `e2e` pipeline from the Bitrise **Start build** page to run the complete E2E suite against that branch. No push trigger is configured, so merging to `main` does not automatically start this pipeline.

## 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.
Expand All @@ -64,6 +66,8 @@ Selection happens inside the pipeline instead. The Linux `ci-ios-plan` workflow

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".

A manually started `ci-ios` pipeline selects all four macOS jobs. Choose the branch and `ci-ios` pipeline from the Bitrise **Start build** page to verify the complete iOS build and test suite. Like `e2e`, `ci-ios` has no push trigger and does not run automatically after a merge to `main`.

### 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:
Expand Down Expand Up @@ -202,7 +206,7 @@ Do not pass storefront tokens or customer data through BrowserStack Maestro envi

## GitHub reporting

The `e2e-report` workflow creates commit statuses, Check Runs, and sticky PR comments using the short-lived token generated by the Bitrise GitHub App.
For pull request builds, the `e2e-report` workflow creates commit statuses, Check Runs, and sticky PR comments using the short-lived token generated by the Bitrise GitHub App. Manual branch builds have no pull request to update, so both E2E and iOS reporting workflows skip GitHub reporting without requiring a token.

The Bitrise project has **Project settings > Repository > Extend GitHub App permissions to builds** enabled. Bitrise exposes the build-scoped GitHub App token as `GIT_HTTP_PASSWORD`; the report workflow maps it to `GITHUB_TOKEN` before running `e2e/scripts/report_e2e_results`.

Expand Down
4 changes: 2 additions & 2 deletions e2e/bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ workflows:
- content: |-
set -euo pipefail
source e2e/scripts/bitrise_ci_helpers
e2e_log "Fetching pull request changed files"
e2e_log "Selecting files for the iOS CI run plan"
changed_files="$(e2e_changed_files_file)"
ruby e2e/scripts/ios_ci_run_plan validate --changed-files-file "$changed_files"
e2e_log "Asserting the pipeline can run every selected job"
Expand Down Expand Up @@ -479,7 +479,7 @@ workflows:
- content: |-
set -euo pipefail
source e2e/scripts/bitrise_ci_helpers
e2e_log "Fetching pull request changed files"
e2e_log "Selecting files for the E2E run plan"
changed_files="$(e2e_changed_files_file)"
ruby e2e/scripts/e2e_matrix_to_browserstack_run_plan validate --changed-files-file "$changed_files"
e2e_log "Asserting the pipeline can build every selected target"
Expand Down
18 changes: 13 additions & 5 deletions e2e/scripts/bitrise_ci_helpers
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,24 @@ e2e_deploy_dir() {
printf '%s\n' "$dir"
}

e2e_has_pull_request() {
[ -n "${BITRISE_PULL_REQUEST:-}" ] && [ "$BITRISE_PULL_REQUEST" != "false" ] && [ "$BITRISE_PULL_REQUEST" != "0" ]
}

# Writes the changed file list and prints its path. Two gates read it — the E2E matrix
# and the iOS CI run plan — and a second copy of this derivation would let them select
# different work from the same commit.
#
# PR builds: the checkout is a shallow merge commit, so the GitHub API is the
# authoritative source for the PR's changed files. Non-PR runs (manual, scheduled,
# local) fall back to diffing the branch against its base with a three-dot range
# (changes since the merge-base, not tip-to-tip).
# authoritative source for the PR's changed files. Non-PR runs select every tracked
# file so manually starting a pipeline against a branch runs every applicable job.
e2e_changed_files_file() {
local changed_files
changed_files="$(mktemp "${TMPDIR:-/tmp}/checkout-kit-changed-files.XXXXXX")"
if [ -n "${BITRISE_PULL_REQUEST:-}" ]; then
if e2e_has_pull_request; then
ruby e2e/scripts/github_pr_changed_files > "$changed_files"
else
git diff --name-only "${BITRISE_GIT_BRANCH_DEST:-origin/main}...HEAD" > "$changed_files"
git ls-files > "$changed_files"
fi
printf '%s\n' "$changed_files"
}
Expand All @@ -58,6 +61,11 @@ e2e_branch_bitrise_config() {
}

e2e_export_github_token() {
if ! e2e_has_pull_request; then
e2e_log "No pull request associated with this build; skipping GitHub reporting configuration"
return
fi

e2e_log "Checking GitHub reporting configuration"
if [ -z "${GITHUB_TOKEN:-}" ]; then
: "${GIT_HTTP_PASSWORD:?GITHUB_TOKEN or Bitrise GitHub App GIT_HTTP_PASSWORD is required. Enable Project settings > Repository > Extend GitHub App permissions to builds.}"
Expand Down
38 changes: 38 additions & 0 deletions e2e/test/bitrise_ci_helpers_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,44 @@ def test_changed_files_are_written_to_a_temporary_file
end
end

def test_non_pr_build_treats_every_tracked_file_as_changed
Dir.mktmpdir do |directory|
output, error, status = run_helper(
'changed_files="$(e2e_changed_files_file)"; cat "$changed_files"',
"TMPDIR" => directory,
"BITRISE_DEPLOY_DIR" => File.join(directory, "deploy")
)

assert status.success?, error
assert_equal `git ls-files`.lines.sort, output.lines.sort
end
end

def test_false_pull_request_value_treats_every_tracked_file_as_changed
Dir.mktmpdir do |directory|
output, error, status = run_helper(
'changed_files="$(e2e_changed_files_file)"; cat "$changed_files"',
"TMPDIR" => directory,
"BITRISE_DEPLOY_DIR" => File.join(directory, "deploy"),
"BITRISE_PULL_REQUEST" => "false"
)

assert status.success?, error
assert_equal `git ls-files`.lines.sort, output.lines.sort
end
end

def test_non_pr_build_does_not_require_a_github_token
Dir.mktmpdir do |directory|
_output, error, status = run_helper(
"e2e_export_github_token",
"BITRISE_DEPLOY_DIR" => directory
)

assert status.success?, error
end
end

def test_pr_build_fails_when_branch_head_config_cannot_be_read
Dir.mktmpdir do |directory|
_output, error, status = run_helper(
Expand Down
Loading