Skip to content

[SDK-7461] fix(setup-env): deliver BUILD_RUN_IDENTIFIER, ask the API when the triggering actor is unknown, stop failing re-run delivery silently - #88

Open
anish353 wants to merge 1 commit into
masterfrom
fix/sdk-7461-rerun-delivery-identifier-and-diagnostics
Open

anish353 wants to merge 1 commit into
masterfrom
fix/sdk-7461-rerun-delivery-identifier-and-diagnostics

Conversation

@anish353

Copy link
Copy Markdown
Collaborator

Summary

Three defects in setup-env's BrowserStack re-run delivery path, surfaced by a Cypress + GitHub Actions re-run investigation (SDK-7461).

1. BROWSERSTACK_BUILD_RUN_IDENTIFIER has been silently dropped since 2026-05-07.

The rebuild/details response carries three variables. Verified against the live API (runId 29728341550, HTTP 200):

{"data":{"variables":{
  "BROWSERSTACK_RERUN": "true",
  "BROWSERSTACK_RERUN_TESTS": "cypress/tests/FlightOffer/FO-E2E-05.ts,...",
  "BROWSERSTACK_BUILD_RUN_IDENTIFIER": "1784546348645-29728341550"
}}}

ALLOWED_RERUN_ENV_VARS (added in 8ade0a3, APS-19076) lists only the first two plus BUILD_NAME, so the third is filtered out — the action logs Ignoring non-allowlisted env var from BrowserStack rerun API: BROWSERSTACK_BUILD_RUN_IDENTIFIER and moves on. Before 8ade0a3 the export loop was unfiltered, so this variable did reach the runner.

The SDKs read it as build_run_identifier in the build-start payload (browserstack-cypress-cli bin/testObservability/helper/helper.js:412, bin/testhub/testhubHandler.js:65) — it is what files a re-run as an attempt of its parent build run rather than as an unrelated build.

2. Every way re-run delivery can fail was silent.

With github-token left at its action.yml default of 'none', the job log on a re-run is byte-identical to an ordinary run — checkIfBStackReRun() returns false from two branches that log nothing. The CLI then runs the full spec set, because its only re-run switch is the presence of BROWSERSTACK_RERUN_TESTS. So "all my tests ran again instead of just the failed ones" was undiagnosable from the log, which is how SDK-7124 and SDK-7461 both stalled.

checkIfBStackReRun() now names the missing input, explains a human-triggered re-run, and an API failure is a core.warning rather than core.info. An absent GITHUB_TRIGGERING_ACTOR gets its own message rather than the App-not-installed one — that variable comes from the runner binary, so on a self-hosted runner it can simply be missing, and blaming the GitHub App there sends the reader after an install that is fine. Attempt 1 stays silent — an ordinary run is not a degraded re-run.

PR #85 predicted this. The allowlist's own PR body carries the caveat verbatim:

If the rerun API legitimately sets additional names in production, the list will need to grow — they will be visible as core.warning lines in workflow logs.

BROWSERSTACK_BUILD_RUN_IDENTIFIER is exactly such a name. The warning has been emitted on every BrowserStack-triggered re-run since 2026-05-07; nobody was watching for it. This PR is that predicted growth.

3. An unreported GITHUB_TRIGGERING_ACTOR aborted delivery on an otherwise correct setup.

checkIfBStackReRun() bailed when that variable was absent. But it comes from the runner binary, so a self-hosted runner can simply not set it — and the actor check is only a cheap pre-filter: rebuild/details is the authority and returns no variables when BrowserStack did not trigger the re-run. So the bail converted a working re-run into a full-suite run. It now warns and asks the API instead. This surfaced on a self-hosted Windows runner fleet, where the variable was not being set.

Security note (APS-19076 preserved)

The allowlist still blocks arbitrary names; only one BrowserStack-owned, BrowserStack-consumed name is added. The existing negative test asserting NODE_OPTIONS / PATH / GITHUB_TOKEN are rejected is unchanged and passing.

Testing

  • 47 unit tests passing (43 before, +4): identifier is exported; a missing input is named; a human-triggered re-run is explained; an unreported triggering actor is distinguished from a non-BrowserStack one.
  • eslint clean; dist rebuilt with ncc, reproducible (a second npm run build gives no further diff).
  • Runner-level A/B on the built dist/index.js, run exactly as a GitHub runner does (INPUT_* env, output read from $GITHUB_ENV), against the real details API:
Scenario Before After
all preconditions pass BUILD_RUN_IDENTIFIER unset + ::warning::Ignoring non-allowlisted… BUILD_RUN_IDENTIFIER=1784546348645-29728341550, no warning
github-token = none on a re-run log identical to a normal run ::warning::…the 'github-token' input is not set. Every test will run again…
re-run started by a human Triggering actor is - <x> only explains that no failed-test list applies, points at the GitHub App install
runner never set GITHUB_TRIGGERING_ACTOR silent, indistinguishable from above own message naming the runner, not the App
details API returns non-2xx core.info, easily missed ::warning:: naming the failure and its consequence
attempt 1 (ordinary run) silent silent (unchanged — deliberately)

Reproduced against a real reported failure

The reported build ran 11 sessions; the spec folder its workflow targets via --spec holds exactly 11 specs. Driving the real published CLI over that project with the same arguments:

BROWSERSTACK_RERUN_TESTS Specs dispatched
unset 11 of 11 — matches the reported build exactly
3 project-relative paths 3
3 bare basenames 3

That workflow is correctly configured (step present with github-token, same job, before Run Tests, no env shadowing, CLI unpinned → 1.36.19), which is what pointed at change 3.

Blast radius

Small, but not zero. Change 3 means workflows whose runner does not report a triggering actor will now make one extra authenticated GET on re-run attempts (>1) and, when BrowserStack did trigger the re-run, will start receiving the failed-test list they should always have had. Workflows on a BrowserStack-triggered re-run will now additionally receive BROWSERSTACK_BUILD_RUN_IDENTIFIER — the SDKs already read it and it was present before APS-19076, so this restores prior behaviour rather than introducing new behaviour. The rest is log-only. All eight delivery states were exercised end-to-end through the built action into the real CLI; seven of eight produce a full-suite re-run, and post-fix each carries a distinct signature. Docs recommend pinning @master, so this reaches every setup-env user on merge.

Ref: SDK-7461, SDK-7124.

🤖 Generated with Claude Code

…when the actor is unknown, stop failing silently

Three changes to the BrowserStack re-run delivery path.

1. BROWSERSTACK_BUILD_RUN_IDENTIFIER has been dropped since 2026-05-07.
The rebuild/details response carries three variables; the APS-19076 allowlist
(8ade0a3) listed only two plus BUILD_NAME, so the identifier is filtered out and
only a core.warning marks it. Verified against the live API. The SDKs send it as
build_run_identifier in the build-start payload, which files a re-run as an
attempt of its parent build rather than an unrelated build. PR #85's own body
predicted this: "If the rerun API legitimately sets additional names in
production, the list will need to grow."

2. An unreported GITHUB_TRIGGERING_ACTOR no longer aborts delivery.
That variable comes from the runner binary, so a self-hosted runner can simply
not set it. The actor check is only a cheap pre-filter — rebuild/details is the
authority and returns no variables when BrowserStack did not trigger the re-run.
Bailing on an absent actor turned a working re-run into a full-suite run on an
otherwise correctly configured workflow. We now warn and ask the API instead.

3. Every remaining delivery failure names itself.
With github-token at its 'none' default the job log was byte-identical to a
healthy run, and the CLI then runs the full spec set because
BROWSERSTACK_RERUN_TESTS is absent — so "all my tests ran again" was
undiagnosable. checkIfBStackReRun now names the missing input, a human-triggered
re-run says so, and an API failure is a warning rather than info. Attempt 1 stays
silent: an ordinary run is not a degraded re-run.

Verified end-to-end through the built dist into the real CLI across all eight
delivery states, and reproduced against a real reported failure: the build ran
11 sessions, the targeted spec folder holds 11 specs, and the real CLI dispatches
11 with the list absent and 3 with it present.

47 tests passing (4 new), eslint clean, dist rebuilt with ncc (reproducible).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@anish353
anish353 requested a review from a team as a code owner September 21, 2026 04:11
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited), Workspace UI (inherited)

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 01b48146-19af-4643-8333-e869c1693dd2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

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