mcpField
C
ci-score

ci-score

github.com/starslingdev云与 DevOps4580 次安装今天更新
代码仓库

关于 ci-score

用于检查代码仓库 CI 工作流配置是否符合最佳实践的技能,面向希望审查 CI 配置的仓库维护者。它从本地仓库计算通过项比例,并生成带有改进建议的报告;分数衡量实践遵循度,而非速度或整体安全性。

主要功能

  1. 01检查 11 项 CI 配置事实
  2. 02读取本地工作流与构建配置
  3. 03计算适用检查的通过比例
  4. 04生成排序的改进建议与报告
  5. 05验证报告与发现数据一致

适用场景

  1. 01审查仓库的 CI 配置实践
  2. 02定位工作流中未通过的检查
  3. 03生成并验证 CI 评分报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/starslingdev/skills --skill ci-score

安装后在 Claude Code 中输入/ci-score确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CHANGELOG.md
evals/
evals.json
prompt-routing.json
references/
ci-score-methodology.md
ci-score-spec.json
close-contract.md
scripts/
ci_score.py
collect_config.py
practice_facts.py
render_card.py
render_report.py
verify_report.py
tests/
_fixture_checkouts.py
tests/fixtures/
checkouts-manifest.json
tests/fixtures/checkouts-src/better-auth/dot-github/actions/setup-playwright/
action.yml.fixture
tests/fixtures/checkouts-src/better-auth/dot-github/workflows/
auto-changeset.yml.fixture
auto-label.yml.fixture
auto-retarget.yml.fixture
backport.yml.fixture
ci.yml.fixture
claude.yml.fixture
demo.yml.fixture
e2e.yml.fixture
lock-threads.yml.fixture
npm-dist-tag.yml.fixture
preview.yml.fixture
promote.yml.fixture
release.yml.fixture
semantic-pull-request.yml.fixture
verify-changesets.yml.fixture

详细介绍

ci-score

**CI Score 用于衡量对 CI 速度和门禁规范最佳实践的遵循情况:根据仓库的工作流配置计算一套简单明了的通过/未通过检查清单。**包含 11 项配置事实,每项都可在不到一分钟内通过仓库自身的 YAML 验证;得分 = 通过的检查项 / 适用的检查项;有一种情况会拒绝评分(没有可检查的工作流)。注册表: references/ci-score-spec.json(冻结版本 v0.1.4);评分标准说明: references/ci-score-methodology.md。

该分数衡量的是遵循情况,而非速度——实测速度更快的仓库也可能得分更低。报告会在评分卡旁说明这一点;切勿让用户将分数解读为速度评判。它也不是安全审计:评分标准评估的是最佳实践,其中 11 项检查里恰有两项(操作固定版本、作业范围的 OIDC 令牌)与安全相关——它不会对工作流安全性作出任何进一步的声明。

要求

  • **目标仓库的完整本地检出副本。**评分会读取三类输入——工作流 YAML、本地复合操作和仓库根目录中的构建工具配置——因此,视野不完整(例如仅通过 API 获取工作流)会悄悄抬高得分。收集器会拒绝在 git 检出目录之外运行。自行完整克隆是有效方式(它包含全部输入内容——禁止的是不完整获取,而非克隆):克隆前先征求同意(会使用网络和磁盘空间);对用户并不拥有的仓库评分,结果只能供用户本人查看——绝不发布或分享。
  • PyYAML(pip install pyyaml)。如果缺少该依赖,脚本会明确退出并给出安装提示。
  • 不需要也不会使用网络;所有内容都从本地目录树读取。

流程

以下所有路径均相对于此技能目录。

交互约定(步骤 0 和 4)。面向用户的两个问题都必须是单个结构化问题——一个问题、固定顺序的选项、不含开放式问题、不叙述背后的机制——在平台提供结构化提问工具时,通过该工具提问:Claude Code 使用 AskUserQuestion;Codex 使用其内置的用户输入请求工具(request_user_input / tool/requestUserInput,实验性功能——如已提供就调用;检查该工具并尝试调用,之后才能考虑回退,做法必须与 ci-speedup 完全一致——有一次实际运行 ci-score 的 Codex 任务因为认为该工具不会提供而直接跳到了普通消息分支,没有先尝试调用)。只有在工具确实不存在或调用失败时,才用一条普通消息提出相同的问题——选项相同、顺序相同,收尾处的保存选项仍须放在最后,并逐字保留(None, just save the report (.md));目标确认仍须只需一个按键回复(“回复 y 为 <owner/repo> 评分,或指定其他仓库/路径”)。只有传递方式会变;此约定不依赖 Agent。这整套约定与 ci-speedup 的交互约定一致——使用相同工具、相同回退方式和相同的保存选项原文;任一约定发生变化时,都要保持二者同步。 0. 评分前确认目标。 默认目标是当前所在的仓库:git rev-parse --show-toplevel 是检出根目录;如果 origin 远程指向 GitHub,则其名称为 <owner/repo>。按照交互约定提出一个结构化问题——至少 2 个选项:一个用于确认检测到的 <owner/repo>(如果没有 GitHub 远程,则确认路径);另一个是“其他仓库或路径”(用户选择该选项或“其他”即可提供目标)。如果当前工作目录不是 git 检出目录(git rev-parse 失败),则没有可供确认的本地默认目标——以普通消息提问,或仅提供“其他”选项(需要检测到默认目标才能使用“确认/不同目标”这种至少 2 个选项的形式),并请用户提供目标(<owner/repo> 或路径)。如果用户已经指定目标,只有目标不明确时才重新确认(指定目标无法唯一对应某个本地检出目录或某个可克隆的 <owner/repo>)。确认目标至关重要,尽管评分在本地进行、速度快且免费:任何应用的修复,以及保存后的报告,都会落在评分仓库的根目录中,因此工作目录错误就会操作错误的项目。选择其他本地检出目录时,直接对其评分;选择尚未下载到磁盘的 <owner/repo> 时,遵循 Requirements 中的先克隆再评分规则(通过 gh repo view 确认访问权限——在沙盒化的 Agent Shell(Codex)中,密钥环凭据可能无法访问,导致 gh 错误地失败:在将失败视为无访问权限之前,先重试并启用主机访问,参照 ci-speedup 的 gh 检查——然后在克隆前征求用户同意,因为这会使用网络和磁盘)。目标确定之前,不要运行收集器。

  1. 收集并评分(一个命令,写入结果文档): python3 scripts/collect_config.py --repo <checkout-root> --out <workdir>/findings.json。<workdir> = 目标检出目录之外的临时目录——如果有会话临时目录就用它,否则使用 mktemp -d;使用每个仓库各自的子目录(<workdir>/<repo-name>/),确保第二个仓库或重新运行时不会覆盖之前运行的文件;绝不能默认使用当前工作目录(仓库内未跟踪的 findings.json 会使下一次运行的来源标记变成 -dirty)。 退出码 0 = 已评分,或在标记中如实说明拒绝评分;退出码 2 = 拒绝收集(不是检出目录/没有可解析的工作流);退出码 3 = 评分失败(data_sources.ci_score_error 会记录原因)。文档会标记每种结果——请阅读文档,不要猜测。
  2. 在临时目录中生成报告: python3 scripts/render_report.py --findings <workdir>/findings.json --out <workdir>/report.md——评分卡、说明评估的是遵循程度而非速度,然后针对每项未通过的检查给出一条建议,按影响 × 风险排序,每条建议包含修复步骤、对应的最佳实践页面,以及交给 Agent 的提示词。渲染后的文件留在 <workdir> 中,直到用户提出要求(遵循 ci-speedup 的惯例,见其中的 issue #18):只有用户在结束时选择 None, just save the report (.md),才将报告写入目标仓库——将 <workdir>/report.md 复制到 ./ci-score-report.md(目标仓库根目录),并用一句话说明文件保存位置(这是生成的文件,用户可以将其加入 gitignore 或删除;绝不能自动提交,也不要编辑用户的 .gitignore)。 其他任何选择都不会将报告写入工作树。 这样也能保持本次运行干净:未保存的报告不会留下未跟踪文件,避免导致下一次运行的来源标记变成 -dirty。原始的 findings.json 始终保留在 <workdir> 中。
  3. 展示前验证: python3 scripts/verify_report.py --findings <workdir>/findings.json --report <workdir>/report.md 必须输出 report: OK。如果验证失败,则重新执行第 2 步并再验证一次(常见原因是 report.md 已过时,或 findings 与 report 不匹配)。如果仍然失败,渲染后的报告不宜展示:告知用户验证失败(这是技能缺陷,不是其仓库的问题),直接从 ci_score 标记中读取评分结果并告知用户,同时不要提供建议;只有用户提出要求时才展示违规行。
  4. 按结束/启动流程完成结束环节——首先阅读 references/close-contract.md(下方的“结束约定——不变项”是供实际操作时快速参考的摘要,并非完整流程)——两个部分都必须在同一轮完成: (a) 结束文本(横幅 → 说明 → 建议 → 报告备注),作为普通消息发送,绝不能塞进提问调用;然后 (b) 按照上述交互约定提出启动问题——在支持结构化问题工具调用的平台上,使用单独的结构化问题工具调用(如 Claude Code 上的 AskUserQuestion);不支持的平台上(大多数 Codex 运行),问题必须是该消息的最后一块内容:直接列出编号选项,选项固定、顺序固定,保存选项排在最后且原样保留,并以此结束本轮。**在任何平台上,仅发送结束文本都不算完成结束环节,只有提问才算完成(工具调用或消息末尾打印的选项列表)。**发送 (a) 后就结束本轮,会让用户完全没有可选项(实际漏项 #2,quasar 2026-07-29:结束文本提到了“下方最后一个选项”,随后却直接结束,始终没有出现问题;用户只好自行输入选项)。 调试跟踪:设置 STARSLING_LOG_LEVEL=DEBUG(记录计数、文件名和检查状态——绝不记录文件内容)。

结束约定 — 不变量

完整的结束/启动流程见 references/close-contract.md。这些 不可妥协的规则必须保留在这里,放在实际使用的位置,因为之前曾因将它们埋得太深而导致 线上运行出错——在此技能中,文本位置会影响行为。每条规则都附有一行事故说明;遵循流程时 请牢记这些规则:

  • 横幅:从收集器的 stdout 原样复制——绝不能手工重画、重新填充空格或调整(一次线上运行中,手绘横线导致 30 个区块中有 29 个计数错误)。拒绝执行或记录了评分错误时,不打印横幅,并保持纯句子的结束语——绝不能使用空横线或虚构横线的横幅。直接读取 ci_score 标记中的分数;绝不能捏造分数来填补空缺。
  • **结束语 = 结束文本,然后是问题,且必须在同一轮中。**仅写出结束文本并不算完成结束流程——无论在哪个平台,只有提出问题才算完成。选项只能出现在问题中:平台提供结构化提问工具时使用该工具(Claude Code 中为 AskUserQuestion);平台未提供时,则在最后打印选项列表(大多数 Codex 运行)。绝不能在提问前用散文描述选项菜单(三次线上遗漏——quasar 在 2026-07-29 两次,另有一次 Codex 运行——内容都完全正确,却完全没有提问)。
  • 菜单形式。首次结束:最多 两个修复选项(一次编辑即可同时关闭两个问题的组合算作一个选项;每个选项都要说明该修复的授权范围和风险),然后给出另一项建议,最后必须逐字写出 None, just save the report (.md)。应用后重新提供选项时,第一项必须是 “Commit this branch and open a PR”——该选项就是提交 + 推送 + 发起 PR 的请求(负责人在 2026-07-30 指出:开发者应先交付工作,再开始更多工作)。**选择交付即结束流程;绝不能合并。**报告显示已合并时,必须开启新一轮以横幅开头——重新评估合并后的基线,并像首次结束一样完整呈现,绝不能只附带一句“已重新评分,N/100”(线上遗漏,2026-07-30)。
  • 只有选择保存才会将报告写入工作树(将 <workdir>/report.md 复制到 ./ci-score-report.md);其他选项都不会写入。
  • **每次批准只给出一项建议;到差异处即停止。**对应用操作的“yes”只授权编辑——绝不因此提交、推送或发起 PR(曾有一次线上会话将应用操作当成了提交许可)。重新评分检查是完成判定的依据;绝不能捏造分数,也绝不能仅为强行通过而修改 YAML。

每次编写结束语之前,都要先阅读 references/close-contract.md——其中载有可执行流程(授权范围规则、对有意缺失内容的判断、交付与合并后轮次、拒绝执行时的结束语以及 PR 请求规则);上面的不变量是在遵循流程时必须牢记的要点。

注意事项

  • 切勿将 findings.json 或未保存的报告写入目标仓库——未跟踪文件会让下一次运行的来源标记变为 -dirty(而已发布的配置档案不允许 dirty)。两者都会渲染到 <workdir>;只有用户明确选择保存时,报告才会复制到 ./ci-score-report.md。已保存但仍未跟踪的报告会在后续运行中如实显示为 -dirty;如果需要干净的来源记录,请先提醒用户将其加入 gitignore 或删除。
  • 分数不代表速度表现——经测量,相关性恰好相反(在校准中,得分最低的仓库拥有最快的门禁)。 卡片旁的披露说明正是为此而设;请保持其可见。
  • 路径过滤器是唯一有风险的建议——错误的过滤器可能会跳过本应运行的 CI,而跳过必需检查会阻止合并。报告中的风险说明已指出这一点;应用此修复时请再次说明。
  • 子目录路径仍会对整个仓库评分——采集器以 git 顶层目录为锚点(局部视图会虚增分数),因此,在检出目录内的任何位置使用 --repo 都等效。
  • -dirty 来源标记采用保守判定——未跟踪文件也计入;如果无法验证工作树(git status 失败),则标记为 dirty,而绝不会标记为 clean。

范围限制

ci-score 评估配置卫生状况。它绝不测量速度、估算节省,也不显示金额。**这项禁令是操作要求,而不只是描述:**如果用户在任何时候询问速度、成本或实际耗时——包括刚看到分数后追问“那我们的 CI 为什么这么慢?”——不要根据配置事实临时作答(缺少缓存并不代表测量结果);请用一句话说明这一点,并引导至 ci-speedup。对于实际耗时和运行器分钟数的测量结果,应使用 ci-speedup——这是一个独立技能;ci-speedup 运行绝不会显示分数,而此技能也绝不会声称进行了测量。提示词路由约定(各技能负责回答什么): evals/prompt-routing.json。

评论

支持 Markdown