Repository navigation
fix(ci): run the autofix scan lane on the persistent pool #10055
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
2e7c750
fix(ci): run the autofix scan lane on the persistent pool
wenshao 3bc6ade
fix(ci): harden the scan lane for the persistent pool
wenshao 61bd03f
Merge branch 'main' into fix/autofix-scan-starvation
wenshao f9e56f4
fix(ci): close the scan workdir's remaining pool-hygiene gaps
ad784af
fix(ci): pin the age-sweep reclaim consumer and re-bump the size base…
qwen-code-ci-bot 590c32a
fix(ci): pin issue_comment in the scan-lane routing tests
qwen-code-ci-bot 4bcd1ca
Merge branch 'main' into fix/autofix-scan-starvation
qwen-code-dev-bot 36f880b
fix(ci): fail loud when the scan lane's gh config dir cannot be minted
qwen-code-ci-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -200,7 +200,10 @@ jobs: | |
| # Full rationale → qwen-autofix.md#af-004 | ||
| if: |- | ||
| ${{ github.repository == 'QwenLM/qwen-code' && (github.event_name != 'issue_comment' || (github.event.issue.pull_request && (startsWith(github.event.comment.body, '@qwen-code /takeover') || startsWith(github.event.comment.body, '@qwen-code /retry')))) && (github.event_name != 'pull_request' || github.event.label.name == 'autofix/takeover') && (github.event_name != 'pull_request_review' || github.event.pull_request.state == 'open') }} | ||
| runs-on: 'ubuntu-latest' | ||
| # Persistent pool, not hosted: a hosted backlog queued route past the cron | ||
| # period, and af-005's supersede then starved every scan round. | ||
| # Full rationale → qwen-autofix.md#af-148 | ||
| runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'' && (github.event_name != ''pull_request'' && github.event_name != ''pull_request_review'' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON(''["OWNER","MEMBER","COLLABORATOR"]''), github.event.pull_request.author_association))) && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}' | ||
| timeout-minutes: 5 | ||
| concurrency: | ||
| # Concurrency is keyed by TARGET, not shared and not fully unique: | ||
|
|
@@ -256,6 +259,15 @@ jobs: | |
| COMMENT_PR_AUTHOR: '${{ github.event.issue.user.login }}' | ||
| HAS_PR_URL: '${{ github.event.issue.pull_request.url }}' | ||
| run: |- | ||
| # gh has its own reroute channels: pin the host, drop planted tokens, | ||
| # and point gh at a fresh empty config dir — on the persistent pool | ||
| # the shared ~/.config/gh is attacker-writable (config.yml can carry | ||
| # http_unix_socket transport reroutes), and a forged collaborator- | ||
| # permission response here would open the /takeover and /retry gates. | ||
| # Mirrors the heavy jobs' preamble. Full rationale → qwen-autofix.md#af-148 | ||
| export GH_HOST=github.com | ||
| unset GH_ENTERPRISE_TOKEN GH_TOKEN | ||
| export GH_CONFIG_DIR="$(mktemp -d "${RUNNER_TEMP}/autofix-gh-config.XXXXXX")" | ||
| DO_ISSUE=false | ||
| DO_REVIEW=false | ||
| TAKEOVER_ACK='' | ||
|
|
@@ -2054,7 +2066,8 @@ jobs: | |
| needs: 'route' | ||
| if: |- | ||
| ${{ needs.route.outputs.do_review == 'true' }} | ||
| runs-on: 'ubuntu-latest' | ||
| # Same pool decision as route. Full rationale → qwen-autofix.md#af-148 | ||
|
wenshao marked this conversation as resolved.
wenshao marked this conversation as resolved.
|
||
| runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'' && (github.event_name != ''pull_request'' && github.event_name != ''pull_request_review'' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON(''["OWNER","MEMBER","COLLABORATOR"]''), github.event.pull_request.author_association))) && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}' | ||
| timeout-minutes: 15 | ||
| # A forced scan can write the same status comment as review-address. | ||
| # Share its per-PR lock so neither writer can erase the other's state. | ||
|
|
@@ -2072,6 +2085,11 @@ jobs: | |
| enum_failed: '${{ steps.scan.outputs.enum_failed }}' | ||
| env: | ||
| REPO: '${{ github.repository }}' | ||
| # Per-run home for the scan's API dumps. A fixed autofix* name (not | ||
| # mktemp's tmp.*) so the age sweep in the heavy jobs can reclaim it | ||
| # after a hard runner kill; cleaned normally by the always() step. | ||
| # Full rationale → qwen-autofix.md#af-148 | ||
| WORKDIR: '/tmp/autofix-scan-${{ github.run_id }}' | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Applied in f9e56f4 — the exact value WORKDIR: '/tmp/autofix-scan-${{ github.run_id }}' is pinned beside the other scan-lane pins, with a comment naming the autofix* prefix as the age-sweep contract. Flip-checked: the /tmp/scan- prefix mutant now fails the suite. |
||
| steps: | ||
| - name: 'Scan for PRs with new feedback' | ||
| id: 'scan' | ||
|
|
@@ -2083,6 +2101,16 @@ jobs: | |
| REVIEW_SENDER: '${{ needs.route.outputs.review_sender }}' | ||
| DISPATCH_SOURCE: "${{ github.event_name == 'workflow_dispatch' && inputs.source || '' }}" | ||
| run: |- | ||
| # gh reroute hardening, mirroring the heavy jobs: pin the host, drop | ||
| # planted tokens, and use a fresh empty config dir — the pool's | ||
| # shared ~/.config/gh is attacker-writable, and a config.yml with an | ||
| # http_unix_socket reroute would swallow this step's gh calls, | ||
| # CI_DEV_BOT_PAT in the Authorization header included. | ||
| # Full rationale → qwen-autofix.md#af-148 | ||
| export GH_HOST=github.com | ||
| unset GH_ENTERPRISE_TOKEN GH_TOKEN | ||
| export GH_CONFIG_DIR="$(mktemp -d "${RUNNER_TEMP}/autofix-gh-config.XXXXXX")" | ||
|
|
||
| # Every lane that reaches this scan is supposed to hold the PAT: | ||
| # route now declines the one event GitHub is known to run without | ||
| # secrets (a fork PR's own review) before it can set do_review. | ||
|
|
@@ -2092,17 +2120,28 @@ jobs: | |
| exit 1 | ||
| fi | ||
|
|
||
| # Pre-clean before create, mirroring the heavy jobs: run_id is | ||
| # public and sequential, and mkdir -p alone would succeed over a | ||
| # dir or symlink pre-planted on the shared pool /tmp — the scan's | ||
| # redirects would then land in an attacker-chosen place, and a | ||
| # planted bot-prs.json would feed the forced-PR guard below. | ||
| rm -rf "${WORKDIR}" | ||
| (umask 077; mkdir -p "${WORKDIR}") | ||
|
|
||
| # Fleet visibility: every per-PR decision below also records a row so | ||
| # the run summary shows the WHOLE managed fleet in one table. | ||
| # Reconstructing this by hand (list bot PRs, regex each one's eval | ||
| # markers, cross-check checks and fork state) was the only way to see | ||
| # a stall, so stalls stayed invisible until someone went looking. | ||
| FLEET_FILE="$(mktemp)" | ||
| trap 'rm -f "${FLEET_FILE}"' EXIT | ||
| # Inside WORKDIR, not mktemp's /tmp/tmp.*: on a cancelled run the | ||
| # EXIT trap never fires, and only the always() step and the heavy | ||
| # jobs' autofix* age sweep reclaim what this step leaves — neither | ||
| # can reach a tmp.* name. | ||
| FLEET_FILE="${WORKDIR}/fleet.tsv" | ||
| trap 'rm -f "${FLEET_FILE}"; rm -rf "${WORKDIR}"' EXIT | ||
| fleet_row() { | ||
| printf '%s\t%s\t%s\n' "$1" "$2" "$3" >> "${FLEET_FILE}" | ||
| } | ||
| WORKDIR="$(mktemp -d)" | ||
|
|
||
| read_forced_pr_meta() { | ||
| local attempt meta | ||
|
|
@@ -3264,6 +3303,16 @@ jobs: | |
| echo "targets=${TARGETS}" >> "${GITHUB_OUTPUT}" | ||
| echo "has_targets=$([[ "${COUNT}" -gt 0 ]] && echo true || echo false)" >> "${GITHUB_OUTPUT}" | ||
|
|
||
| # Nothing else removes the per-run WORKDIR; on the persistent pool | ||
| # every scan would leave its API dumps behind forever. always() covers | ||
| # cancellation (the in-step EXIT trap does not fire on a killed run); | ||
| # only a hard runner kill abandons the dir, and the autofix* age sweep | ||
| # in the heavy jobs reclaims it. Mirrors issue-autofix's cleanup step. | ||
| # Full rationale → qwen-autofix.md#af-148 | ||
| - name: 'Clean up scan workdir' | ||
| if: 'always()' | ||
| run: 'rm -rf "${WORKDIR}"' | ||
|
|
||
| # =========================================================================== | ||
| # REVIEW PHASE (build) — compile the trusted-base CLI bundle ONCE per scan | ||
| # and fan it out to the address legs as an artifact. Each leg otherwise | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking nit: this records
404284, butqwen-autofix.ymlat the head commit is 405,204 bytes — the final "fail loud when the scan lane's gh config dir cannot be minted" commit grew the file by 920 bytes without re-bumping (verified via the contents API:404284at both590c32aand the merge4bcd1ca,405204at36f880b). Well within the 4,096-byte growth allowance, so the ratchet stays green — but since the previous commit made this baseline exact again, a re-bump to405204would keep it tight and preserve the full allowance headroom for the next PR that touches this file.非阻断小问题:这里记录的是
404284,但 head 提交上qwen-autofix.yml实际为 405,204 字节——最后一个"fail loud"提交让文件涨了 920 字节却没有同步 bump(经 contents API 核实:590c32a与合并提交4bcd1ca均为 404284,36f880b为 405204)。远在 4,096 字节增长容差之内,ratchet 保持绿色——但既然前一个提交刚把基线调回精确值,顺手 re-bump 到405204能保持基线收紧,也给下一个改这个文件的 PR 留足容差。