Skip to content

ci-host: reject Percy build when a host-test shard fails#4638

Open
backspace wants to merge 4 commits intomainfrom
cs-percy-cancel-on-failure
Open

ci-host: reject Percy build when a host-test shard fails#4638
backspace wants to merge 4 commits intomainfrom
cs-percy-cancel-on-failure

Conversation

@backspace
Copy link
Copy Markdown
Contributor

Summary

Percy auto-approve is enabled on main, so a build that finalises without the snapshots from a crashed shard would otherwise lock in a partial baseline — and the next clean build would surface those missing snapshots as "new" diffs on PRs. Host shards do crash periodically (OOM, ChunkLoadError before the retry catches it, etc.), so this is a real source of noise now that the branch filter matches.

Capture the build URL/ID from percy build:finalize, and follow up with percy build:reject <id> whenever needs.host-test.result is anything other than success. The reject step is gated on finalize having actually emitted a build URL so we don't try to reject an empty string when finalize itself fails.

Follow-up to #4518 (CS-10954).

Verification I'd appreciate

  • I parsed the build ID from percy build:finalize stdout via grep — if Percy CLI changes its log format this becomes brittle. There's no documented "give me the build ID" flag on build:finalize. An alternative would be querying GET /api/v1/builds?filter[parallel_nonce]=... but that endpoint isn't documented either. Open to a cleaner discovery path.
  • percy build:reject exists in @percy/cli (verified via --help) but I haven't manually tested whether it reliably prevents auto-approve. If it doesn't, build:delete is a more aggressive alternative.

Test plan

  • Confirm the workflow still finalises Percy normally on a clean run (open this PR, watch CI)
  • Manually force a shard failure (or wait for one to happen organically) and verify the reject step fires + the build is marked rejected in the Percy UI

🤖 Generated with Claude Code

Percy auto-approve is enabled on `main`, so a build that finalises
without the snapshots from a crashed shard would otherwise lock in
a partial baseline — and the next clean build would surface those
missing snapshots as "new" diffs on PRs.

Capture the build URL/ID from `percy build:finalize`, and follow up
with `percy build:reject <id>` whenever `needs.host-test.result` is
anything other than `success`. The reject step is gated on the
finalize step having actually emitted a build URL so we don't try
to reject an empty string when finalize itself fails.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3115f31ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci-host.yaml Outdated
`set -e` alone does not fail a step on non-final pipeline elements,
so a `percy build:finalize` failure piped through `tee` would have
its exit code masked by `tee`'s success. Pre-this-change, the bare
`npx percy build:finalize` invocation failed the step immediately;
this restores that behaviour.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Host Test Results

    1 files  ±0      1 suites  ±0   2h 0m 19s ⏱️ - 1m 10s
2 562 tests ±0  2 547 ✅ ±0  15 💤 ±0  0 ❌ ±0 
2 581 runs  ±0  2 566 ✅ ±0  15 💤 ±0  0 ❌ ±0 

Results for commit 6514a44. ± Comparison against earlier commit 72359a1.

Two temporary changes to verify the new reject-on-failure flow in
this PR's own CI run, both clearly marked TEMPORARY (PR #4638):

1. check-percy unconditionally sets percy_needed=true so Percy runs
   on this workflow-only PR (no UI-relevant files would otherwise
   trigger it).
2. Shard 1 exits 1 immediately after the test step, so Percy has
   real snapshots from shards 1-20 but the matrix result is failure.

Both blocks must be removed before merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts the Host CI workflow to prevent Percy from auto-approving an incomplete baseline when one or more host-test shards fail, by finalizing the Percy build, extracting its build ID, and rejecting the build on shard failure.

Changes:

  • Capture Percy build URL/ID from percy build:finalize output and expose it as step outputs.
  • Add a follow-up percy build:reject <build_id> step when needs.host-test.result is not success.
  • Introduce temporary workflow modifications to force Percy on and to force a shard failure (intended for verification only).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +39 to +44
# TEMPORARY (PR #4638): force Percy on so the reject-on-failure
# step has a real build to reject. Remove this block before merge.
echo "percy_needed=true" >> "$GITHUB_OUTPUT"
echo "TEMP: Forcing Percy on for reject-on-failure verification"
exit 0

Comment on lines +220 to +228
# TEMPORARY (PR #4638): deliberately fail shard 1 after Percy has
# already received its snapshots, so the reject-on-failure step in
# host-percy-finalize has something to reject. Remove before merge.
- name: TEMP — force shard 1 failure to exercise Percy reject path
if: matrix.shardIndex == 1
run: |
echo "::warning::TEMP: failing shard 1 deliberately to verify the percy build:reject step"
exit 1

Comment thread .github/workflows/ci-host.yaml Outdated
Comment on lines +342 to +343
BUILD_URL=$(grep -oE 'https://percy\.io/[A-Za-z0-9_-]+/[A-Za-z0-9_-]+/builds/[0-9]+' /tmp/percy-finalize.log | tail -1)
BUILD_ID="${BUILD_URL##*/}"
The Percy build URL has three path segments between percy.io/ and
/builds/ (org/product/project), not two — the previous regex matched
nothing and the grep failure propagated through pipefail to fail the
whole finalize step before the reject step could run.

Allow 1–3 trailing segments in the regex and append `|| true` to the
extraction so a parse failure no longer kills the step. Emit a
`::warning::` if the build ID can't be parsed; the reject step is
already gated on a non-empty build_id, so it'll skip cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants