qwen-code/.github/scripts
易良 fc874dfe0b
fix(ci): retry sandbox image builds and file an issue when a release build fails (#9916)
* fix(ci): retry sandbox image builds and file an issue when a release build fails

The v0.22.0 tag build died on a transient ETXTBSY during `npm ci` and was
never retried, so ghcr.io/qwenlm/qwen-code:0.22.0 was never published while
npm already served 0.22.0. Every sandbox-based CI lane (/resolve, sandboxed
review, autofix) then crashes with "manifest unknown" until the image exists.

Add one bounded retry to the buildx step: the first attempt carries
continue-on-error so a successful retry turns the job green, and the retry
gates on the first attempt's outcome alone (a failure() gate would read false
once continue-on-error absorbs the first attempt). The publish condition is
shared through one job-level env so the two build steps cannot drift.

Add a follow-up job that files or updates one issue per version when both
attempts fail — for tag pushes and for publishing dispatches alike, since the
issue body itself recommends that dispatch as the recovery path. Dedup uses
an exact body marker matched client-side, because GitHub search tokenizes the
colon out of the marker and never finds these issues.

Extend the existing workflow gate test to pin the retry contract and the
issue-job gate.

Fixes #9898

* fix(ci): move the image-build failure issue logic to .github/scripts/

The workflow-size ratchet rejects growth past the recorded baseline +4096
bytes; the inline issue-filing step grew build-and-publish-image.yml by
~5.2 KB. Move the step body to .github/scripts/image-build-failure-issue.sh
(the gate's own recommended remedy), leaving the job as a thin env + script
call. No behavior change; the gate test now pins the script call and reads
the dedup contract from the script.

* fix(ci): grant the failure-issue job contents permission and normalize dispatch versions

* test(ci): pin the failure-issue gate and retry step invariants

* fix(ci): gate the failure-issue job on the exported publish decision

* fix(ci): skip the failure-issue job for versionless publishing dispatches

* test(ci): pin the PUSH_IMAGE value and the login gate at the definition site

* test(ci): replay the image-build failure-issue script under a gh stub

* fix(ci): describe release build job failures without asserting a buildx cause

* fix(ci): preserve annotations and recorded runs when updating the failure issue

* test(ci): pin the dedup label on create and the open-state filter on lookup

* fix(ci): document the pre-first-step gap in the failure-issue gate

A build job that fails before its first step runs (runner provisioning
failure) never executes publish-decision, so push_image stays empty and
file-failure-issue is skipped despite failure() being true. Closing the
gap structurally would restate the publish predicate and re-introduce
the drift this PR removes, so document it on the job comment instead:
future "failed publish, no issue filed" investigations start here, and
a scheduled npm-vs-GHCR reconciliation remains the backstop.

* fix(ci): record build-and-publish-image.yml's shipped size in the workflow size baseline

The retry logic and failure-issue filing steps added by this PR grew the
workflow from 4638 to 8887 bytes, past the 4096-byte allowance. Record
the new size so the size gate passes.

* fix(ci): harden the image-build failure reporter per review round 4 (#9916)

- Replace GNU-only `head -n -1` with POSIX `sed '$d'` so the stranded-heading
  strip no longer corrupts the body on BSD userland (R4-1).
- Skip the bash replay suite on win32, where backslash RUNNER_TEMP and the
  ';'-separated PATH cannot express it; the YAML pins still run there (R4-2).
- Re-check head readability AFTER the normalization strip, which can itself
  empty the head and used to drop the narrative permanently (R4-8).
- Admit only recorded-run shapes into the machine block so a bullet-shaped
  human annotation is no longer reordered into it or clipped by the cap (R4-13).
- Remove the marker-restore branch: with the run shape pinned, every body that
  matched the dedup carries its marker in head+tail, so it was unreachable (R4-9).
- Cross-reference the sibling split/merge contract in both implementations (R4-5),
  disable SC2016 with rationale on the literal-backtick formats (R4-6), and
  document the label-removal residual gap on the job (R4-11).
- Behavioral witnesses: run-cap, stranded-heading, marker-survival, empty-head
  and empty-after-strip prose fallbacks, and the annotation shape; each guard
  mutation-probed red. Pin the dedup label on the list call too (R4-10).

* fix(ci): document the version-marker dedup gap on the failure-issue job (#9916)

Round 4 removed the unreachable marker-restore branch (R4-9) but left its
residual gap undocumented: the dedup lookup only finds the tracked issue
while the version marker survives in the body, so a human edit deleting
the marker orphans the issue and the next failure files a duplicate. Fold
the marker into the job's existing known-gap note alongside its sibling,
the scope/ci-cd label (R4-11), and record the workflow's new size.
2026-08-26 08:52:56 +00:00
..
ci fix(ci): retry sandbox image builds and file an issue when a release build fails (#9916) 2026-08-26 08:52:56 +00:00
dsw-swe-verified feat: chain Terminal-Bench release evaluation (#9120) 2026-08-17 05:53:06 +00:00
fixtures test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
assign-issue-owner.mjs feat(ci): auto-assign issues to area owners from labels (#8668) 2026-08-08 23:01:03 +00:00
assign-issue-owner.test.mjs feat(ci): auto-assign issues to area owners from labels (#8668) 2026-08-08 23:01:03 +00:00
auto-minimize-spam.test.mjs fix(ci): minimize new spam comments on creation (#9266) 2026-08-17 05:12:04 +00:00
autofix-push-and-report.sh fix(ci): neutralize legacy ##[ commands in autofix stdout echoes (#9871) 2026-08-25 02:17:46 +00:00
cap-release-notes.mjs fix(release): keep notes anchored and cap the release body (#8199) 2026-07-31 09:55:38 +00:00
cap-release-notes.test.mjs fix(release): keep notes anchored and cap the release body (#8199) 2026-07-31 09:55:38 +00:00
check-autofix-contracts.sh ci(autofix): add cross-package contract verification (#7642) 2026-07-24 05:13:04 +00:00
check-settings-schema.sh ci(autofix): recover from generated-artifact CI gates and stop silent stalls (#6998) 2026-07-17 03:26:43 +00:00
check-workflow-size.sh fix(ci): scope workflow-size ratchet to the PR that grew the file (#9931) 2026-08-25 01:46:34 +00:00
ci-flaky-rerun.mjs feat(ci): auto-open a deflake fix issue for confirmed flaky tests (#7231) 2026-07-19 16:49:29 +00:00
ci-runner-routing.test.mjs fix(ci): give the macOS and Windows lanes a trigger again (#9370) 2026-08-25 11:53:05 +00:00
classify-release-notes.mjs fix(ci): route workflow label mutations through REST (#8761) 2026-08-09 15:05:15 +00:00
classify-release-notes.test.mjs fix(ci): route workflow label mutations through REST (#8761) 2026-08-09 15:05:15 +00:00
create-desktop-update-manifest.mjs feat(desktop): add Aliyun OSS release mirror (#8976) 2026-08-12 10:59:10 +00:00
create-electron-bridge-manifest.mjs fix(desktop): bridge Electron users on Windows and Linux (#9079) 2026-08-13 15:42:31 +00:00
image-build-failure-issue.sh fix(ci): retry sandbox image builds and file an issue when a release build fails (#9916) 2026-08-26 08:52:56 +00:00
pr-safety-precheck.mjs fix(ci): limit fork PR precheck to safety signals (#6178) 2026-07-02 20:56:41 +08:00
pr-safety-precheck.test.mjs fix(ci): limit fork PR precheck to safety signals (#6178) 2026-07-02 20:56:41 +08:00
qwen-triage-workflow.test.mjs fix(triage): compute the flake-gate diff before the env -i re-exec (#9468) 2026-08-19 14:37:44 +00:00
resanitize-git-config.sh fix(ci): make autofix verification gates hermetic to runner git config (#8961) 2026-08-13 11:39:04 +00:00
resolve-owning-packages.sh fix(autofix): resolve owning package for nested paths; report verify-failed handoffs as not pushed (#7330) 2026-07-20 14:39:56 +00:00
resolve-sandbox-image.mjs fix(autofix): bind the sandbox image to its pulled digest (#9527) 2026-08-21 06:46:52 +00:00
resolve-sandbox-image.test.mjs fix(autofix): bind the sandbox image to its pulled digest (#9527) 2026-08-21 06:46:52 +00:00
run-autofix-review-verification.sh fix(ci): neutralize legacy ##[ commands in autofix stdout echoes (#9871) 2026-08-25 02:17:46 +00:00
serve-ab-diff.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
serve-ab-diff.test.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
serve-ab-drive.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
serve-ab-drive.test.mjs test(ci): stage on-disk session state in the serve A/B (#9444) 2026-08-20 14:09:03 +00:00
upsert-bot-comment.sh perf(ci): run docs-only automatic reviews at medium effort (#8648) 2026-08-07 17:00:32 +00:00
upsert-bot-comment.test.mjs perf(ci): run docs-only automatic reviews at medium effort (#8648) 2026-08-07 17:00:32 +00:00
upsert-deferred-issue.sh fix(ci): neutralize legacy ##[ commands in autofix stdout echoes (#9871) 2026-08-25 02:17:46 +00:00
web-shell-visuals-compose.mjs ci(web-shell): denoise cross-job font-AA so visual previews stop false-flagging (#7210) 2026-07-19 11:27:08 +00:00
web-shell-visuals-compose.test.mjs ci(web-shell): denoise cross-job font-AA so visual previews stop false-flagging (#7210) 2026-07-19 11:27:08 +00:00
web-shell-visuals-publish.mjs fix(ci): don't let one failing scenario sink the whole visual preview (#7511) 2026-07-23 02:34:07 +00:00
web-shell-visuals-publish.test.mjs fix(ci): don't let one failing scenario sink the whole visual preview (#7511) 2026-07-23 02:34:07 +00:00