Skip to content

fix(ci): retire closed-PR Python runs to free runner capacity - #6269

Open
loopx-agent wants to merge 2 commits into
mainfrom
codex/ci-closed-pr-capacity-20261012
Open

loopx-agent wants to merge 2 commits into
mainfrom
codex/ci-closed-pr-capacity-20261012

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Closing or merging a PR can leave queued Python qualification behind: the merged close event changes github.ref, and ordinary cancellation can preserve always() aggregates. These obsolete jobs compete with current validation and release publication for runner capacity.

Use a stable PR-number concurrency lane, skip qualification on close, and run a trusted base-branch cleanup job for remaining runs. It checks current PR state, source repository/branch, close time and PR/head association; preserves reopened PRs and other open PRs on the branch; and force-cancels only runs that remain nonterminal after ordinary cancellation, with terminal readback. actions: write is confined to that job, which never checks out PR code. Open-PR required checks and their failure/cancellation rules remain intact. This reduces obsolete demand; GitHub shared-pool release priority is not guaranteed.

Validation:

  • CI contract suite: 11 tests passed, including executing the actual cleanup script against lifecycle/provider fixtures and preserving required-check rejection semantics.
  • Ruff and git diff --check passed. Semantic inventory advisory found no supported new vocabulary carriers; GitHub lifecycle literals remain provider-local.
  • The shipped script completed read-only against a real closed PR and its workflow inventory; the force-cancel API was separately verified against obsolete runs with terminal readback.
  • Workflow activation and full GitHub CI await review/merge. No first-screen or packaged product UI changes.

Future-facing pass: keep the cleanup in its existing workflow owner and reuse the existing gate suite; no parallel scheduler or general abstraction is introduced. Maintainer review is required for the new Actions write boundary.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | xhigh

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

APPROVE — 完整精确 head 0adf05ee5e57ba6654b158166f3142bd290f640d 未发现阻断问题。

动机

维护者关闭或合并 PR 后,需要过期验证释放 runner,让当前验证与发布继续取得执行机会。

基线在合并后的关闭事件中使用变动后的分支引用,且普通取消可能留下始终执行的汇总;候选按 PR 编号保持并发范围,并核验关闭状态后取消确属该 PR 的旧运行。

独立执行实际工作流脚本,确认旧运行取消后必须读回结束,重新打开、换 head、同分支开放 PR、外仓库和关闭后的新运行均保留。

本次只回收已关闭 PR 的 Python 验证,不保证共享 runner 池优先级或发布预留容量,也不改开放 PR 的必需检查。

改动思路

复用既有 Python Tests 工作流和 review_gate 契约测试;可信关闭事件在同一 owner 内完成选择与副作用,不新增通用调度器或第二套合并规则。 本次交付有范围核验和结束读回的关闭 PR 清理,开放验证继续沿用原分类与失败规则。 正常关闭事件按原 PR 编号取消并发 lane;另由目标分支的可信关闭任务处理普通取消后残留的汇总。PR 内容只作为身份数据,不被检出或执行。不可验证来源或时间会失败,重新打开、换 head 或关闭时刻变化会停止,范围外的运行继续保留。副作用后的结束读回是必要判断;HTTP 接受不能代替结束。

具体改动

完整三文件包含工作流 +81/-5、文档 +25/-2、既有契约测试 +116。新任务仅自身持有 actions:write,contents 和 pull-requests 为 read;全局权限仍是 contents:read。选择限定该工作流、pull_request 事件、源仓库与分支、关闭前创建时间,以及原 PR 关联。合并后关联缺失时只接受确切关闭 SHA;有明确关联的旧 head 仍可回收。每次取消前读回当前关闭 head 与关闭时刻。普通取消后先等并读状态,仍未结束才强制取消,并有界等待十次结束读回;403 或持续非结束均失败,409 只有实际结束才视为竞态成功。开放 PR 的必需任务和原失败规则不变。

关键代码讲解

  • concurrency(.github/workflows/python-tests.yml:37):Keep close event in original PR-number lane,retain non-PR event lanes。
  • readPR and run eligibility(.github/workflows/python-tests.yml:60):Fresh exact closed source/epoch,association/cutoff and open-branch protection。
  • cancel/force terminal readback(.github/workflows/python-tests.yml:87):Distinguish accepted effect from completed state and fail nonterminal cleanup。
  • test_closed_pr_cancels_same_lane_and_skips_qualification(scripts/ci/test_review_gate.py:38):Execute actual configured JavaScript through synthetic API lifecycle,retain existing strict gate tests。

规格映射:docs/development/testing-and-quality.md,spec_revision 43173c0b8c8761abee4cdddc665f0f0f20f194f7;strict-open-gate、bounded-concurrency、trusted-effect、terminal-readback 均 implemented。基线必需合并检查及 impact-selection 先于 diff 读取。官方说明佐证关闭/合并事件、force-cancel 的接受与 always() 语义,没有以当前作者测试倒推预期。

对主干的风险

风险集中于过度取消与把接受误当结束。独立运行实际 YAML 内的 JavaScript,固定 16 种合法/非法预期:重开、同源分支其他开放 PR、换 head/关闭时刻、外仓库、关闭后新运行、错误关联、缺关联且错误 SHA 均不被取消;普通结束不 force,非结束走 force,202 后仍未结束必须失败,403 失败,409 非结束失败。传输与等待是合成 fixture,没有取消线上运行或证明实际释放容量。正常生产 caller 是 GitHub 关闭事件工作流,无新增 LoopX frontend/Lark/CLI 产品入口。

语义与 CI 对齐

独立当前工作流契约 11 项、不可变基线 9 项均通过,原 review_gate.py 和 impact_plan.py 字节相同。Ruff、diff、changed-diff semantic advisory 后的完整 semantic drift 检查通过;既有未解析 producer 保留,空 advisory 不覆盖动态 YAML/JavaScript。复用 GitHub 的本地事件/状态词汇,不新建通用状态 owner。CI 未查询、轮询或等待。关闭事件不再启动分类和最终门是明确默认变化;开放与其他事件保留原检查,取消/缺失/意外 skip 不能成为通过证据。

我的整体评价

长期继续路径改善:清理过期工作同时保留重新打开和后续运行,持续非结束会有界失败。用户体验保留:开放验证不增加必填操作、重录信息或授权。复用既有 Python Tests 工作流和 review_gate 契约测试;可信关闭事件在同一 owner 内完成选择与副作用,不新增通用调度器或第二套合并规则。 本次交付有范围核验和结束读回的关闭 PR 清理,开放验证继续沿用原分类与失败规则。 future-facing pass 已检查既有工作流/合并门边界,无需新调度框架;关联缺失时保留保守兼容。当前实际脚本与独立负例覆盖足以批准这个有界变更;线上生效、共享池收益和发布优先级未验证。COMMENTED 记录作者同账户批准结论,平台 Code Owner 与维护者 merge 是另一个边界,本评审不合并。

English verdict: APPROVE

@loopx-agent

Copy link
Copy Markdown
Collaborator Author

Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | xhigh

English verdict: APPROVE - exact head 0adf05ee5e57ba6654b158166f3142bd290f640d;no blocker in the complete3-file diff.

The existing Python workflow retains a stable PR-number lane on merged close,then a trusted base-branch close job retires only verifiable obsolete runs. It never checks out PR code;actions:write is job-local. Repository/ref/cutoff/PR association(or exactSHA when absent),open branch protection and fresh head/close-epoch checks retain current,foreign and future work. Ordinary cancellation is followed by terminal readback;force only follows a nonterminal read,and persistent nonterminal/403 fail.409 is benign only with actual completed readback.

Independent head11/base9 CI-contract cases passed;the strict open classification/gate owners are byte-identical.16 independently specified cases execute the actual shipped JavaScript with synthetic API transport,including reopen,new head,foreign same ref,future run,missing/wrong association,202 without terminal and409/nonterminal. Ruff,diff,advisory then full semantic checks passed. No CI status fetched,polled or awaited;no live Actions cancellation or capacity/priority improvement claimed.

Accepted pre-change testing-and-quality required-check contract at 43173c0b8c8761abee4cdddc665f0f0f20f194f7 maps strict-open-gate,bounded-concurrency,trusted-effect,terminal-readback to implemented. Open/nonPR requirements remain;closed qualification retirement is disclosed in both languages. Existing CI owner reused and bounded future-facing simplification needs no new scheduler. Maintainer merge/platform approval remain separate from this author-owned COMMENTED approval conclusion.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant