mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-11 04:02:45 -10:00
* fix(ci): report timed-out main CI runs instead of letting cancelled hide them
main-ci-failure-issue.yml only admitted `failure` conclusions, but a job that
hits its execution cap concludes `cancelled` — so timed-out main runs never
filed an issue. That is how #16214 (the E2E docker leg rebuilding the sandbox
image past its 60-minute cap on cold mainland hosts) hid for weeks (#16272).
Admit `cancelled` at the trigger, then discriminate in the live step: a
cancelled run is reportable only when a job carries the execution-time-timeout
annotation; a plain concurrency supersede is skipped, and an unreadable
annotation fails safe toward not reporting. The download projections include
cancelled jobs so the timed-out leg is named in the report. The infra
classifier is unchanged, so a pure-timeout run (no failure jobs) files rather
than reruns, and normal failure handling is untouched.
Meta-tests: the trigger pin and routing matrix now reflect the admitted
cancelled conclusions; three new live-step tests witness timeout→report,
concurrency→skip, and unreadable→skip; the download-selector and jobs-fetch
pins are updated, as is the ci-platform-lanes trigger pin.
* fix(ci): classify cancelled runs by positive evidence, fail open when unknown
Review on #16280: real concurrency cancels carry the runner shutdown / higher-
priority / operation-canceled annotations, not just "operation was canceled",
and a timed-out job can carry a shutdown annotation alongside the timeout. The
previous discriminator only looked for the timeout text and skipped everything
else, so it rested on "absence of timeout = concurrency" and dropped unreadable
cancellations — re-creating the hiding problem #16272 fixes.
Classify by positive evidence on both sides instead: a timeout annotation
reports (even with a coexisting shutdown annotation); a concurrency annotation
with no timeout skips; neither, or unreadable jobs/annotations, fails open and
reports like the rest of the live step. Fixtures cover the shutdown and
higher-priority concurrency forms, timeout+shutdown coexistence, and the
fail-open paths; breaking the concurrency signature reddens the skip tests.
* fix(ci): address #16280 review — trust gate, renderer, successor dedup, docs
R1-4 (security): only trusted triggers (push/schedule/dispatch on main) run the
cancellation classifier; PR-triggered cancellations stay on the supersede path
so contributor-authored annotation text cannot drive the PAT-backed reporter.
R1-1: renderFailureComment now keeps cancelled jobs, so a timed-out leg is named
in the issue/PR comment even when no job concluded failure (the #16214 shape).
R1-2: factor the classifier into cancelled_class with a total_count receipt and
explicit unreadable handling; unknown fails open with a warning instead of
asserting a supersede it never established.
R1-3: a timeout-backed cancelled successor owns the older run's result (same
shared classifier), preventing a duplicate report; log wording corrected.
R1-6: the classifier runs after the stale-attempt check so a stale event is
attributed to staleness, not to a cancellation cause.
R1-7: the test stub resolves the check-run id (job id != check-run id) and
applies the caller's --jq with real jq; RUN_CONCLUSION env is pinned; fixtures
cover shutdown / higher-priority / coexisting timeout / unreadable / PR arms.
R1-5: sync the two design docs (both languages) with the new behaviour.
* fix(ci): move the cancelled-run classifier out of the workflow body
main-ci-failure-issue.yml grew to 63933 bytes, 6793 over its recorded
57140 (allowance 4096), so the workflow-size ratchet failed. Move the new
cancelled_class helper into .github/scripts/ci/classify-cancelled-run.sh,
which is what the ratchet asks for ("long steps into .github/scripts/"),
and trim review-narrative prose to the load-bearing why. Behaviour is
unchanged: both call sites invoke the script.
The workflow-shape pin that read the classifier's attempt-jobs fetch out
of the workflow now reads the script.
Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmw1wuw3xco
* fix(ci): do not report a cancelled run that ran no job (#16280 R1-2, R2-1, R2-4)
Critical R1-2: the classifier returned unknown (fail-open report) for a
cancelled run whose attempt has no cancelled job at all — a run displaced while
queued certifies 0==0 and reads no annotation, so it filed a "Main CI failed"
issue for a run that tested nothing. Track whether any cancelled job was seen;
none means supersede (concurrency), while unknown now only covers cancelled jobs
whose annotations are unreadable/unmatched or uncertifiable pages.
R2-1: tests for the certification false branch (partial pages -> unknown) and
the no-jobs case (-> concurrency). R2-4: a negative successor case with a real
id whose cancelled job is a supersede, exercising the == 'timeout' false branch.
* fix(ci): report a cancelled run that also carries a failed job (#16280)
R3-1 (Critical): the classifier read only `cancelled` jobs, so a run whose
job already concluded `failure` before the rest was cancelled classified as a
deliberate supersede and dropped the regression. Read `failure`/`timed_out`
jobs first and fail open on them.
R1-2 (Critical): a cancelled run whose jobs all stopped before their first
step still fell through to `unknown`, which reports. Treat "no cancelled job
ran a step" as nothing-executed, preserving the zero-job behaviour.
R3-2: give that outcome its own token and case arm, so the caller's notice no
longer claims an annotation this path never read.
R3-4: the annotation-error test now uses two cancelled jobs, because with one
the fall-through prints the same `unknown` as the guard and cannot see it
removed.
Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmw2mktggdp
* test(ci): correct successor-gate comment and pin the classifier's full fetch
R3-3: the comment no longer claims the gate admits only failures. R2-4: pin the
classifier fetch including ?per_page=100 and --paginate so flag-stripping reddens.
* fix(ci): keep a failed cancel-classification read from deferring the report
The classifier printed `unknown` both for a run it read and could not match
and for a read that failed. Crediting `unknown` as the successor's own
verdict would then let a transient API failure drop the only report of a
regression, because the successor's gate may have read the same run as
concurrency and skipped. Print `unreadable` for those read failures and
keep the ownership arm on `timeout`/`unknown`.
Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmw4alb71g0
* fix(ci): keep a confirmed timeout over a sibling's failed annotation read (#16280 R5-1)
The per-job annotation read exited unreadable before the verdict block, so
a sibling job's failed read buried timeout evidence another job already
carried — the same hiding this PR removes, one layer over. Remember the
failed read, keep scanning, and fall back to unreadable only when no
timeout was confirmed; a concurrency supersede is likewise not certifiable
over an unread sibling. Adds real-script regression tests (stubbed gh)
that go red on the pre-fix script.
* test(ci): exercise the successor jq projection end to end (#16280 R5-5)
The cancelled-successor deferral binds successor_id/successor_attempt from the
workflows/runs --jq projection, but every stub handed back a pre-formatted
string, so dropping the id field stayed green while production bound the
attempt number as the id. The new case returns raw JSON and applies the
caller's filter with real jq (verified red with the id field dropped), plus a
shape pin on both projected fields.
* docs(ci): align the design docs with the cancelled-run verdicts (#16280 R4-1)
The R4-1 fix widened the successor-ownership rule from `timeout` to
`timeout | unknown`, and the classifier now skips on `nothing-executed` as
well as `concurrency`, but both design docs this PR touches still described
the pre-fix rule: only a timeout-backed cancelled successor owns the result,
and a cancelled run reports only when a job carries a timeout annotation.
Restate the shipped rule in all four files (both languages): the two verdicts
that stay silent, the fail-open `unknown`/`unreadable` reports, a cancelled
run that also carries a `failure`/`timed_out` job, and the `unreadable`
successor that deliberately does not take ownership because a failed read
certifies nothing about what that run concluded.
Docs only — no workflow or script bytes change, so the workflow-size ratchet
is unaffected.
* ci: record main's 501-byte growth of main-ci-failure-issue.yml (#16280)
Merging main into this branch brought in 7cb46d9f (#13969), which added a
seven-line comment — 501 bytes — to main-ci-failure-issue.yml. The merged file
is 61381 bytes, 145 past the 57140 + 4096 ratchet, so the workflow-size gate
fails on growth this PR did not author.
This PR's own contribution to that file is untouched: the merge's diff on it is
exactly main's seven added lines and nothing else. Record the merged size so
the ratchet reflects the tree this branch now carries.
---------
Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: yiliang114 <[email protected]>
Co-authored-by: Shaojin Wen <[email protected]>