🐛 fix(commit-message): enforce one rule owner across skill and CI

CI ran .gitea/ci/commit_message_lint.py, an independent reimplementation
that parsed the type/emoji mapping out of docs/common/commit_message.md.
Its scope pattern accepted fix(-a), fix(a-), fix(a--b) and fix(_), and it
had no subject length check, so the gate that actually blocks merges
enforced weaker rules than the Validation this skill reports.

The CI entry is now a wrapper that locates the skill validator and
delegates to it with no arguments; commit_policy.json becomes the only
rule source and explanatory docs stop being a machine policy input.

The validator also learns the workflow_run event, whose payload carries
neither a PR title nor a before/after range. An upstream pull_request now
validates <integration-branch>..head_sha instead of HEAD alone, taking
the branch name from COMMIT_LINT_MAIN_BRANCH, and degrades to the
upstream head commit with a WARN rather than guessing a base.

Alongside: --help now documents the no-argument CI mode it had always
supported silently, CI wiring detail moves to references/ci-wiring.md,
and the description gains negative boundaries.

test/test_commit_message_policy.py asserts policy/spec-table equality and
uses ast to assert the CI entry imports no regex and reads no file, so a
second implementation cannot reappear unnoticed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
csh
2026-08-20 15:21:37 +08:00
co-authored by Claude Fable 5
parent 651c1f68d2
commit 7408c532f0
6 changed files with 476 additions and 208 deletions
+13 -17
View File
@@ -1,6 +1,6 @@
---
name: commit-message
description: "当用户需要撰写或审查提交信息、检查已暂存改动、判断是否拆分提交,或使用 emoji 与提交类型(作用域)格式时使用。"
description: "当用户需要撰写或审查提交信息、检查已暂存改动、判断是否拆分提交,或使用 emoji 与提交类型(作用域)格式时使用。不用于交互式起草 PR 标题、发布说明或变更日志,不用于照原文执行用户已经给定的提交,也不用于诊断 CI 为什么失败(改用 gitea-fix-ci)。"
---
# Commit Message(提交信息)
@@ -14,10 +14,14 @@ description: "当用户需要撰写或审查提交信息、检查已暂存改动
- `references/commit_policy.json`:提交信息格式策略。
- `scripts/validate_commit_message.py`:候选信息和 CI 输入校验器。
- `references/ci-wiring.md`:把 validator 接到 CI 的方式与事件覆盖范围。
以包含本文件的目录作为 skill 根目录解析上述路径。不要假设存在 Playbook checkout、
仓库 `docs/` 目录或特定的当前工作目录。
validator 是提交信息规则的唯一实现。CI 入口只能调用它,不得自行实现校验,也不得
从说明性文档解析 type/emoji 等规则;说明性文档是给人读的,不是机器策略来源。
## 适用场景
以下情况使用本 skill:撰写提交信息、审查已暂存边界、判断是否拆分提交,或处理
@@ -110,24 +114,16 @@ policy 的 `emoji.requirement_env` 未设置时使用 `required_by_default`
index 也不等于授权提交。未获得相应授权时,不运行 `git commit`,不暂存文件,
不修改 index。
## CI 输入校验(仅无参数模式)
## CI 输入校验
无参数运行 validator 时检查 CI payload;只有未识别事件或本地调用才回退 `HEAD`。
已识别的 push/PR 事件缺失或损坏 payload 时必须失败
无参数运行 validator 即进入 CI 输入校验:从事件 payload 取回全部待校验主题,只有
未识别事件或本地调用才回退 `HEAD`。已识别事件缺失或损坏 payload 时必须失败
shallow repository 一律失败;不能用可能截断的 payload `commits` 数组或计数字段
证明范围完整。
- **Pull request**:同时校验 `pull_request.title` 和本地 Git 中
`base.sha..head.sha` 的完整提交范围;遇到 shallow repository、缺失范围元数据或
Git 对象时失败。workflow 编排必须来自可信 base/default branch:直接触发使用
`pull_request_target`,或先由 `pull_request` 准备输入、再由默认分支的
`workflow_run` 执行。普通 `pull_request` 中来自 PR head 的 workflow 即使切到 base
worktree,仍可被待审改动删除或绕过。可信 workflow 必须从 `base.sha` 的可信 base
worktree 运行 wrapper、validator 和 policy;只能读取 PR head 的 Git 对象,不能在
持有 secret 的步骤 checkout 或执行 PR head 内容。
- **Push**:校验本地 Git 中 `before..after` 的完整范围。新分支 push 的 `before` 为
零对象时,使用 payload 的目标 `refs/heads/*` 和本地分支图计算该分支相对其它分支
新增的完整提交集合。缺少有效范围元数据、目标引用或所需 Git 对象时失败;shallow
repository 也必须失败。不能用可能截断的 payload `commits` 数组或计数字段证明
范围完整。
覆盖哪些事件、每种事件取回什么范围、以及可信编排要求见
`references/ci-wiring.md`。接线或排查前先运行
`validate_commit_message.py --help`,以脚本当前输出为事件覆盖范围的权威。
## 输出约定