fix(ci): reap release integration containers - #11330
Conversation
|
Dry-run validation is queued: https://github.com/QwenLM/qwen-code/actions/runs/34194126628. The decisive check is that |
|
Dry-run verification passed: https://github.com/QwenLM/qwen-code/actions/runs/34194126628. |
|
✅ Qwen Triage finished — CI landed green on ✅ Qwen Triage 已完成 —— |
ff686d6 to
52f54b0
Compare
|
Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. 中文请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。 |
|
Main changed the release job to execute an extracted script while the first dry-run was running. I rebased the fix onto that refactor, kept the cleanup in the extracted runner, and re-ran the local release workflow suite (62 passed, 1 skipped). Current-head dry-run: https://github.com/QwenLM/qwen-code/actions/runs/34200135053. |
|
Thanks for the PR! Template looks good ✓ — every required section is filled in, including the before/after evidence and the full Chinese translation. A note on history, since it shapes this review: my first pass landed on Problem: observed, not theoretical. Release run 34162336173 finished green and still left eight Direction: aligned. The release lane is the one Docker-sandbox lane #11264 did not cover, and leaving it uncovered means every scheduled release keeps leaking containers onto a shared self-hosted pool. No CHANGELOG signal applies — this is CI plumbing, not user-facing behaviour. Size: not applicable. The three changed files are Approach: the scope feels right, and it is the reuse-first answer on two axes at once. It ports the mechanism already proven in Risk: no elevated risk signals — none of the three changed files matches the revert-correlated path list. Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ —— 所有必填部分都写了,包括前后证据和完整的中文翻译。 先说明一下历史,因为它影响本次审查的读法:我的第一轮审查落在 问题: 是已观测到的问题,不是理论性加固。Release 运行 34162336173 成功结束,但仍在 方向: 对齐。Release 通道是 #11264 唯一没有覆盖的 Docker sandbox 通道;不补上,每次定时发布都会持续在共享 self-hosted 资源池上泄漏容器。CHANGELOG 无对应信号 —— 这是 CI 管线,不是面向用户的行为。 规模: 不适用。改动的三个文件是 方案: 范围合理,而且在两个维度上都是"优先复用"的做法。它移植了 风险: 无升级风险信号 —— 三个改动文件都不匹配与 revert 相关的路径列表。 进入代码审查 🔍 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
Code reviewMy independent proposal first. Reading only the title and the "why" — release-lane Docker integration containers leak on self-hosted runners because they are unlabeled — I would have done exactly one thing: reuse the reaper #11264 already proved on the E2E lane. Label each runtime container with a run-scoped owner through the existing The mechanism is real, not a dead switch. I traced the chain rather than trusting the variable name: The rebase resolved both blockers, and the trap ordering is right. The subtle bit I was watching for is that the trap must be installed before the Better than what I suggested: rather than duplicating the reap shell inline in a second workflow step, the cleanup step calls the same extracted script with a Two ordering details I checked because they are easy to get wrong and both are fine:
The test adaptation is correct, not a weakening. The four assertions moved off Two nits, neither blocking:
CI evidenceThis is an unattended CI run, so per the gate rules I did not build, run, or test any PR-derived code. Everything below is read from the check-runs on
Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 Two of these are the ones that matter for this diff, and both are still in flight. Separately, Not verified: that a running release container actually carries the owner label. This is the one gap I could not close by reading. A structural test asserts script and YAML text, so it would pass identically if Sandboxed verification would settle this, with an honest caveat about which lane. 中文说明代码审查先说我自己的独立方案。 只看标题和"为什么需要"——发布通道的 Docker 集成容器因为没有标签而在 self-hosted runner 上泄漏——我会做的就是一件事:复用 #11264 已在 E2E 通道验证过的回收机制。通过现有的 这套机制是真实生效的,不是死开关。 我没有只看变量名就相信,而是完整追了链路: rebase 解决了两个阻塞项,而且 trap 的顺序是对的。 我特别留意的细节是 trap 必须安装在 比我建议的更好的一点: 清理步骤没有在第二个 workflow 步骤里重复内联回收 shell,而是用 有两个容易写错、但这里都正确的顺序细节我确认过:
测试的改动是正确的,不是放松断言。 四处断言从 两个小问题,都不阻塞:
CI 证据这是无人值守的 CI 运行,因此按 gate 规则我没有构建、运行或测试任何 PR 派生代码。下面全部内容都是通过 API 读取
其中两项对本 diff 最关键,而且都还在跑。 另外, 未验证:运行中的 release 容器是否真的带有 owner 标签。 这是我无法靠阅读关闭的唯一缺口。结构测试断言的是脚本和 YAML 文本,所以即使 沙箱验证可以定这件事,但要诚实说明该用哪条通道。 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
|
Confidence: 4/5 — solid and ready to ship once CI lands; the two nits are named below and neither blocks, and the only reason this is not 5/5 is that the suite has not yet executed against the rebased script. Stepping back, the thing that stands out is how the rebase went. A conflicting PR is where most contributions get sloppy — the easy move is to re-inline the old shell into the new YAML and force the test green by loosening it. You did the opposite: the reap logic went into the extracted script where #11165 wanted it, the residue step calls that same script with a Back to my independent proposal: it was the same proposal, which is the strongest signal I have that the direction is right. Reusing #11264's reaper rather than inventing a second one, and dropping the Does it solve something people care about? Yes. A scheduled release silently leaving eight containers on a shared self-hosted pool is how a runner eventually wedges for everyone, and #11264 already established that we care enough to reap the E2E lane; leaving the release lane uncovered was an inconsistency, not a decision. Is the code straightforward? Very — 68 lines across three files, no new abstraction, no new label namespace. Would I curse whoever wrote this in six months? No. The two things I flagged are a The reservation I am holding, and the reason for 4 rather than 5: nothing has yet executed the rebased script. Am I approving because it is genuinely good, or because I ran out of reasons to say no? The first. My earlier pass found two real blockers and both were fixed properly rather than papered over, the design matches what I would have written, and the change is minimal and idiomatic to the structure it now lives in. So: approval is deferred until CI lands green on 中文说明Confidence: 4/5 —— 改动扎实,CI 落地后即可合并;下面点名的两个小问题都不阻塞;之所以不是 5/5,唯一原因是测试套件还没有在 rebase 后的脚本上执行过。 退一步看,最突出的是这次 rebase 的处理方式。冲突的 PR 正是最容易敷衍的场合——省事的做法是把旧的 shell 重新内联进新的 YAML,再靠放松断言把测试弄绿。你做的恰恰相反:回收逻辑进了 #11165 希望它去的抽取脚本,残留检查步骤用 回到我的独立方案:那是同一个方案,这是我能给出的、说明方向正确的最强信号。复用 #11264 的回收机制而不是另造一套、去掉 E2E 版本需要的 它解决的是大家在意的问题吗?是。一次定时发布在共享 self-hosted 资源池上静默留下八个容器,正是 runner 最终对所有人卡死的成因;#11264 已经确立了我们愿意为 E2E 通道做回收,把 release 通道留在外面是一个不一致,而不是一个经过权衡的决定。代码是否直白?非常直白——三个文件 68 行,没有新抽象,没有新的标签命名空间。六个月后我会骂写这段代码的人吗?不会。我提出的两点,一是与 #11264 以来生产运行版本逐字节相同的 我保留的顾虑,也是给 4 分而不是 5 分的原因:目前还没有任何东西真正执行过 rebase 后的脚本。 我批准是因为它确实好,还是因为我说不出拒绝的理由了?是前者。我上一轮审查发现了两个真实的阻塞项,两者都被正确修复而不是掩盖;设计与我自己会写的方案一致;改动最小,并且符合它现在所处结构的惯用写法。 所以:批准延迟到 CI 在 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship — CI landed green after the review. ✅
|
Released in v0.23.1. |
What this PR does
Labels every container started by the Docker release-validation job with a run-scoped owner and removes only those containers when the test command or job finishes. The final cleanup checks for residue and fails the job if owned containers remain.
Why it's needed
The scheduled release run 34162336173 completed successfully but left eight
qwen-code-integration-test-*containers running onecs-qwen-hk4-10. Those containers had only the shared sandbox-image label, so the E2E cleanup added in #11264 could not identify or remove them.Reviewer Test Plan
How to verify
dry_run=trueandforce_skip_tests=false.Integration Tests (Docker)completes andRemove job-owned release containerssucceeds on the self-hosted runner.org.qwen-code.ci.owner=<run-id>-<attempt>-release.Evidence (Before & After)
Before: release run 34162336173 left eight running containers after its Docker integration job completed.
After: dry-run 34194126628 completed successfully. Its Docker integration cleanup step succeeded on
ecs-qwen-hk4-25, and a post-job SSH check found zero containers carryingorg.qwen-code.ci.owner=34194126628-1-releaseand zero remaining containers created during the job window.Tested on
Environment (optional)
Local workflow parsing and structural regression test with Node.js 22.
Risk & Scope
Linked Issues
Follow-up to #11264.
中文说明
这个 PR 做了什么
为 Docker 发布验证任务启动的每个容器增加按运行隔离的 owner 标签,并在测试命令或任务结束时只删除这些容器。最终清理步骤会检查是否仍有残留,若存在则让任务失败。
为什么需要
定时发布运行 34162336173 虽然成功结束,但在
ecs-qwen-hk4-10上留下了八个仍在运行的qwen-code-integration-test-*容器。这些容器只有共享的 sandbox 镜像标签,因此 #11264 增加的 E2E 清理无法识别和删除它们。Reviewer 测试计划
如何验证
dry_run=true、force_skip_tests=false。Integration Tests (Docker)完成,并且 self-hosted runner 上的Remove job-owned release containers成功。org.qwen-code.ci.owner=<run-id>-<attempt>-release标签的容器。前后证据
修复前:Release run 34162336173 的 Docker 集成任务结束后留下了八个运行中的容器。
修复后:dry-run 34194126628 全部成功。Docker 集成清理步骤在
ecs-qwen-hk4-25上成功,任务结束后的 SSH 检查确认org.qwen-code.ci.owner=34194126628-1-release标签容器为零,并且任务运行期间创建的容器没有残留。测试环境
本地使用 Node.js 22 完成 workflow 解析和结构回归测试。
风险和范围
关联事项
#11264 的后续修复。