Commit ce2f58f
ci: stop update-playwright-expectations failing open and cancelling other PRs (#14684)
Two independent defects in `pr-update-playwright-expectations.yaml`,
both found while regenerating baselines for #14682 (the container-image
bump). Both are specific to the `/update-playwright` comment trigger.
## Bug 1: the comment trigger fails open (silent false green)
GitHub runs `issue_comment`-triggered workflows from the **default
branch's** copy of the workflow file, not the PR's. The container image
was a literal in that file, so `/update-playwright` on a PR that bumps
the image tag regenerated snapshots under **main's** image (0.0.21), not
the PR's (0.0.22). No pixels changed, nothing was committed, and the run
reported **success**. A maintainer sees a green "baselines updated"
result for work that never happened.
The label trigger (`New Browser Test Expectations`) does not have this
bug: `pull_request` events run the PR's own copy of the workflow.
**Fix chosen: derive the tag from the PR's checked-out files at
runtime**, rather than merely detecting the mismatch and failing. This
makes the comment path *correct* instead of merely *loud* — a maintainer
who comments `/update-playwright` on an image bump now gets working
baselines instead of a red run telling them to go use the label.
`jobs.<id>.container.image` accepts the `needs` context, so the `setup`
job (which already checks out the PR branch) resolves the tag and the
sharded job consumes it.
The tag is read from the PR's `ci-tests-e2e.yaml` because that is the
workflow which will *verify* these snapshots, so it defines the
environment they must match. Matching is anchored to `image:` value
lines, and all containerized jobs in that file must agree on one tag -
`ci-tests-e2e.yaml` has two (`playwright-tests` and
`playwright-tests-chromium-sharded`), and requiring agreement catches
them drifting apart. Resolution is fail-closed: a missing file, zero
matches, or conflicting tags all `::error::` and fail the job. As a side
effect this workflow no longer carries an image literal, so future bumps
touch two files instead of three.
The two rejected options: detecting the mismatch and failing loudly
leaves the comment path unusable for exactly the PRs that most need it;
removing the comment trigger discards a workflow maintainers actively
use.
**Residual risk, now surfaced rather than silent:** only the image is
taken from the PR. Everything else in this file (job graph, shard
matrix, `run` commands) still comes from the default branch on the
comment path. A new non-fatal step emits a `::warning::` when the PR
modifies this workflow, pointing the maintainer at the label trigger. It
cannot fail the job — a failed `git fetch` degrades to a `::notice::`
and exits 0.
## Bug 2: concurrency group collides across PRs
`concurrency.group` keyed on `github.ref`, which for `issue_comment` is
always the default branch. Every comment-triggered run therefore shared
one group with `cancel-in-progress: true`, so a comment on **any** PR
cancelled an in-flight regeneration on **any other** PR. This actually
happened. Note the blast radius is wider than it looks: workflow-level
concurrency is evaluated when the run is created, before the job-level
`if:` guard filters non-matching comments, so an ordinary comment on an
unrelated issue also entered the group.
Now keyed on the PR number, with a fallback that is valid for every
declared trigger:
```
${{ github.workflow }}-${{ github.event.issue.number || github.event.number || github.ref }}
```
`github.event.issue.number` for `issue_comment`, `github.event.number`
for `pull_request` (`github.event.issue` is absent there and
dereferences to null), `github.ref` as a last resort. The label path was
already correctly isolated (`refs/pull/N/merge`) and keeps per-PR
isolation under the new key.
## Verification
Cannot be exercised end-to-end without merging — `issue_comment`
workflows only ever run from the default branch, so the fixed comment
path is unreachable until this lands. Same structural constraint as
#13699 (a different workflow, `pr-backport.yaml`, unrelated defect).
Validated as far as statically possible:
- `yamllint --config-file .yamllint` (the repo's `CI: YAML Validation`
gate) passes.
- `actionlint` v1.7.11 reports **no** expression or context errors. It
emits the same 6 pre-existing `SC2086:info` findings as the file on
`main` — zero new findings. This is what checks expression validity per
trigger.
- `bash -n` passes on every inline script.
- The image-resolution script was **executed** against 7 real inputs:
`main`'s `ci-tests-e2e.yaml` -> `0.0.21`; **#14682's branch ->
`0.0.22`** (the bug, directly demonstrated); a decoy tag inside a YAML
comment -> still `0.0.21`; a quoted `image:` value -> `0.0.21`; missing
file -> error, exit 1; two conflicting tags -> error, exit 1; no tag ->
error, exit 1.
- The drift-warning script was executed in a throwaway repo: no drift ->
silent; modified workflow -> `::warning::`; unreachable remote ->
`::notice::`, exit 0.
**Unverifiable until merge:** that GitHub actually accepts `needs.*` in
`container.image` at runtime (documented and widely used, but not
exercised here); that the resolved image pulls under `credentials`; and
the real end-to-end comment-triggered regeneration.
## Other fail-open path, not fixed here
`Update snapshots (Shard N)` carries `continue-on-error: true`. That is
necessary — `--update-snapshots` exits non-zero when it rewrites a
baseline — but it also swallows hard failures. If a shard dies for an
unrelated reason (ComfyUI server never boots, container broken,
Playwright crashes), zero snapshots change, `merge-and-commit` logs "No
changes to commit", and the workflow goes green having done nothing.
That is the same silent-false-green shape as Bug 1 and survives this PR;
distinguishing "no diffs" from "the run never happened" needs the
Playwright result JSON and is a larger change. Flagging for a follow-up
rather than bundling it.
---------
Co-authored-by: t <t@t.t>
Co-authored-by: Amp <amp@ampcode.com>1 parent 4a4b1e4 commit ce2f58f
1 file changed
Lines changed: 206 additions & 5 deletions
Lines changed: 206 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
10 | 12 | | |
11 | | - | |
| 13 | + | |
12 | 14 | | |
13 | 15 | | |
14 | 16 | | |
| |||
28 | 30 | | |
29 | 31 | | |
30 | 32 | | |
| 33 | + | |
31 | 34 | | |
32 | 35 | | |
33 | 36 | | |
| |||
59 | 62 | | |
60 | 63 | | |
61 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
62 | 114 | | |
63 | 115 | | |
64 | 116 | | |
| |||
81 | 133 | | |
82 | 134 | | |
83 | 135 | | |
84 | | - | |
| 136 | + | |
85 | 137 | | |
86 | 138 | | |
87 | 139 | | |
| |||
109 | 161 | | |
110 | 162 | | |
111 | 163 | | |
112 | | - | |
| 164 | + | |
113 | 165 | | |
114 | 166 | | |
115 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
116 | 170 | | |
117 | 171 | | |
118 | 172 | | |
| |||
150 | 204 | | |
151 | 205 | | |
152 | 206 | | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
153 | 264 | | |
154 | 265 | | |
155 | 266 | | |
| |||
270 | 381 | | |
271 | 382 | | |
272 | 383 | | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
273 | 460 | | |
274 | 461 | | |
275 | 462 | | |
| |||
289 | 476 | | |
290 | 477 | | |
291 | 478 | | |
292 | | - | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
293 | 494 | | |
294 | 495 | | |
295 | 496 | | |
| |||
0 commit comments