mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-08 00:05:37 +00:00
* feat(autofix): direct takeover of maintainer-fork PRs Maintainer-approved v2: many maintainers work from personal forks, and adoption-snapshotting breaks their local workflow. A fork PR is now directly manageable when three live conditions hold — the takeover label, 'Allow edits from maintainers' (org-owned forks cannot enable it; adoption remains their path), and a fork author who holds write+ RIGHT NOW (the same live-privilege rule as the comment command, so an ex-member's fork can never summon secret-bearing runs). Plumbing: - Scan: fork takeover candidates are admitted per candidate (allow- edits + no-skip filtered in jq; the author's live write+ gate is one permission call each — a rare set); every matrix target now carries its head repo. - Address: prepare fetches the fork branch (origin has no copy) and checks out FETCH_HEAD with hooks already severed; the eligibility gate re-verifies takeover + allow-edits + author write+ live; the report step pushes back to the fork via the allow-edits grant. - Triggers: fork pull_request label events carry NO secrets, so the route notes them and the next scheduled scan engages (≤10m); the comment command now toggles fork PRs too (write+ senders only — fork authors stay silently dropped) and refuses only when allow-edits is missing, with the actionable ask. The scan posts a first-pickup engage ack (identity-verified, deduped on any existing ack, ic.json re-fetched so the same scan counts under the fresh window key) — closing the fork/manual-label ack gap and anchoring the round window. Behavioral coverage: fork-candidate admission jq (allow-edits, skip, in-repo exclusion, tsv rows), eligibility across fork+takeover+allow-edits+write / no-allow-edits / read-author, the toggle's fork split (refusal vs managed), plus plumbing pins (fork fetch/push forms, head_repo threading, first-pickup ack dedup). 60/60 + 12/12. * fix(autofix): strip stray patch-artifact quotes after two fi keywords Two inserted blocks ended 'fi"' — the quotes balanced against each other inside the same script, so bash -n stayed green while runtime would have lexed 'fi' as a command word and swallowed the span between them (the fork head-repo resolution tail and the engage-ack block) into one string. Removed both, and pinned the artifact class in the suite: a lone fi/done/esac followed by a quote now fails the tests. 61/61 + 12/12. * fix(autofix): author-filtered, re-armable first-pickup engage ack Reverse-audit findings on the scan-side ack: - Dedup was a raw grep over ic.json — a forged human comment carrying the engaged marker would have suppressed the real ack (and with it the window anchor). Dedup now selects bot-authored engaged acks via jq, same author rule as the window key itself. - Fork PRs get NO ack job (label events carry no secrets), so the documented re-arm gesture — remove and re-add the label to reset the round window — silently kept the old window: any historical ack blocked a fresh one. When a bot ack already exists, the scan now compares it against the takeover label's latest application time (issue events, fetched only in that rare case); a newer application posts a fresh ack, resetting window and cap as documented. Coverage: verbatim jq replays for both selections (forged-marker and released-marker exclusion, label-name filter, sort|last) plus the lexicographic re-arm gate pin. 61/61 + 12/12. * fix(autofix): review round 1 — ack ordering, dry-run, ghost-engage gate Addresses the maintainer review on #7213 (all findings confirmed): - Critical: the first-pickup ack read ic.json BEFORE the per-PR fetch — the first takeover candidate killed the whole scan step (missing file under -eo pipefail; every in-repo label-forced scan regressed), and later candidates dedup'd against the PREVIOUS PR's comments (bot PR ahead → fresh ack every 10min → window reset → cap never binds). The block now sits directly AFTER the fetch; its post-ack re-fetch keeps the downstream MARKERS/window-key reads fresh. A contract pin asserts the fetch precedes the first ack-timestamp read. - Medium: the ack now honors DRY_RUN (log only, window key untouched). - Medium: the command refused forks only for missing allow-edits — a below-write fork author was a silent ghost engagement (label sticks, no ack, nothing ever manages it). The command now mirrors the scan's author write+ gate with an actionable bilingual refusal. Found while fixing it: PR_INFO never fetched maintainerCanModify (or author), so EVERY fork toggle refused regardless of allow-edits — the test stub carried the field and masked the gap. Both engage-side fork gates are now also scoped to 'add': release is never blocked. - Low: the two new paginated jq reads are slurped (add-merged) so >100 comments/events cannot scramble the timestamp comparisons; replays now feed two concatenated page-documents. Fork fetch pins refs/heads/ (tag shadowing); HEAD_REPO_FULL guards each component (deleted fork = owner XOR name empty); fork-rotation caveat documented; forced-path refusal mentions the scheduled fork path. - Security caveat adopted: prepare proves fork push access with a --dry-run push right after checkout (allow-edits rides the classic-PAT grant only) and discards gracefully instead of 403ing after a full agent round. 61/61 + 12/12; YAML parses; every run block passes bash -n. * fix(autofix): fork targets keep base/branch invariants + 3 hardening follow-ups Blocking (yiliang114): the last fork elif ends the eligibility ladder for every eligible fork, so the LIVE_BASE/LIVE_BRANCH re-checks were unreachable for exactly the PR class the loop fetches and pushes — a labeled fork retargeted off main (or head-renamed) between scan and address would have had conflicts resolved against the wrong base. The base/branch invariants now sit ABOVE the fork chain (comment explains why the order is load-bearing), with replay cases pinning a retargeted and a renamed fork to the discard path. Follow-ups from the same review, all adopted: - PR_LIVE re-reads headRepositoryOwner/headRepository; a fork renamed or transferred since the scan discards at the live re-check (moved or unresolved, fail-closed) instead of fetching and token-pushing a stale path. The replay's fork fixture now carries its head repo and the harness provides the matrix HEAD_REPO to compare against. - The fork fetch failure (force-push/rename race) discards through the standard no-action path instead of a red run. - The first-pickup engage ack defers to the in-repo label event's DEDICATED ack job within a 3-minute grace after the label lands, so a concurrent ack job is never double-posted (which would shift the round-window anchor); a failed ack job is still healed by the next scan, and forks (no ack job) keep immediate pickup. Events are read once, before the branch split. Both hooks-order regex windows widened to span the new fork-arm guards (the assertions are about order; one hooksPath site genuinely covers both checkout arms). 61/61 + 12/12. * test: raise timeout ceiling for I/O-bound tests flaky under CI contention The self-hosted CI runners are heavily oversubscribed (core runs maxThreads: 16), and a recurring class of tests blows vitest's 5s default timeout purely under that contention — not from any logic fault. Observed repeatedly across unrelated PRs (#7213, #7219, and noted in prior sessions): - packages/core/src/utils/shell-ast-parser-lazy.test.ts — fully mocked, but the dynamic import + async coordination exceeds 5s when 16 threads contend. - packages/cli/src/serve/workspace-registration-store.test.ts — tempdir round-trip. - packages/core/src/extension/github.test.ts > extractFile — its waitForFileData helper polled a FIXED 1_000 setImmediate turns, which elapse in <100ms while the tar extraction I/O is still catching up, throwing 'Timed out waiting for extracted data'. Fixes: - testTimeout: 15000 in the core and cli vitest configs — 3x the default. Assertions still fail instantly; only the timeout ceiling grows, so this masks no logic bug (a real hang still fails, just later, and the job timeout still bounds it). - waitForFileData now polls a real ~10s wall-clock budget (2_000 x 5ms) instead of a fixed iteration count, so a slow extraction is awaited rather than raced. Stays under the 15s ceiling. These are the deterministic root-cause fixes for the flake class the autofix loop and CI Failure Patrol were papering over with reruns. --------- Co-authored-by: wenshao <wenshao@example.com> |
||
|---|---|---|
| .. | ||
| ai-release-notes-workflow.test.js | ||
| build-and-publish-image-workflow.test.js | ||
| check-build-status.test.js | ||
| check-i18n.test.ts | ||
| chrome-extension-package.test.js | ||
| ci-flaky-rerun-workflow.test.js | ||
| ci-flaky-rerun.test.js | ||
| clean-package-build-artifacts.test.js | ||
| cli-entry.test.js | ||
| comment-attachment-guard-workflow.test.js | ||
| dev.test.js | ||
| generate-changelog.test.js | ||
| generate-release-notes.test.js | ||
| get-release-version-python-sdk.test.js | ||
| get-release-version.test.js | ||
| install-script.test.js | ||
| issue-triage-ownership-workflow.test.js | ||
| lint.test.js | ||
| main-ci-failure-issue-workflow.test.js | ||
| no-ak-integration-ci.test.js | ||
| package-assets.test.js | ||
| package-scripts.test.js | ||
| pr-force-push-reminder-workflow.test.js | ||
| qwen-autofix-workflow.test.js | ||
| qwen-fleet-shepherd-workflow.test.js | ||
| qwen-resolve-workflow.test.js | ||
| qwen-triage-workflow.test.js | ||
| release-helpers.test.js | ||
| release-sdk-workflow.test.js | ||
| sandbox-command.test.js | ||
| serve-fast-path-bundle-check.test.js | ||
| start.test.js | ||
| test-setup.ts | ||
| upload-aliyun-oss-assets.test.js | ||
| vitest.config.ts | ||
| workspaces.test.js | ||