关于 running-ci-preflight
供 PostHog 贡献者推送前检查 CI 的技能。`hogli ci:preflight` 根据变更文件选择检查,并在完整 CI 运行前报告失败、警告和建议。
主要功能
- 01按变更范围执行检查
- 02自动格式化与安全修复
- 03分支新鲜度检查
- 04提供 JSON 输出选项
- 05Semgrep 与快照建议
适用场景
- 01推送前检查分支
- 02修复预推送钩子报告的问题
- 03查看机器可读的检查结果
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ posthog/ posthog --skill running-ci-preflight安装后在 Claude Code 中输入/running-ci-preflight确认已加载。
详细介绍
运行 ci:preflight
hogli ci:preflight 将一组精选检查限定在你的分支所触及的文件上——每个文件都映射到一类曾导致 master 挂掉的
CI 失败——外加一项始终开启的分支新鲜度检查。它是 hogli ci:insights(master 上_已经_坏了什么)的
推送前对应工具。
pre-push 钩子会自动运行 ci:preflight --strict,并在检查失败时阻止推送。
绝不要用 --no-verify 绕过它——而是修复它报告的问题。
循环(当钩子阻止推送时,或在报告完成之前)
hogli ci:preflight --fix
- 使用
--fix运行——它会格式化、lint 并自动修复安全的部分。 - 逐行阅读:
✓ pass、✗ fail、⚠ warning(非阻塞性发现)、→ advisory(自己动手做)、· skipped(能力缺失)。 - 解决每一个
✗ fail——这些是--fix无法处理的(真正的 lint 错误、损坏的 lockfile、迁移冲突)。它们会阻止推送。 - 对每一个
→ advisory采取行动——例如openapiadvisory → 运行hogli build:openapi并提交漂移;stalenessadvisory →git merge origin/master。Advisory 从不阻止推送,但忽略它们会把失败送到 CI。在推送前解决它们,包括不是你引入的漂移——你推送的分支状态由你负责。 - 重新运行直到干净,然后推送。
说明
- Strict = 仅失败。
--strict(hook 运行的模式)仅在✗ fail时以非零状态退出 —— advisory 属于本地无法验证的类别,因此只警告而不阻塞。干净退出意味着“没有需要修复的内容”,而不是“CI 会通过” —— CI 始终是权威关卡。不阻塞是机制限制,不是跳过的许可。 type-check是提醒,不是运行。 只有全仓库范围的 mypy 运行才与 CI 一致(mypy 会跟踪 import,因此仅检查变更文件的子集无法发现反向依赖破坏),而冷启动需要几分钟 —— 每次 push 都付出这个代价太高。因此 preflight 只给出命令而不运行它:自行判断你的改动是否有类型风险,然后自己运行。CI 会在同一命令上阻塞,因此你在此跳过的类型错误会以完整重跑的形式回来。complexity只警告。 变更文件中圈复杂度超过 10 会显示为⚠ warning,永不阻塞;CI 会标注同样的警告并将其发布到 CI 报告评论中。下次接触该函数时再简化它,而不是去凑数字。semgrep-devex针对你分支引入的发现给出建议。 它在 15 秒预算内扫描变更文件及其 merge-base 副本。两次扫描都使用.github/workflows/ci-security.yaml中SEMGREP_IMAGE固定的缓存版本,并禁用网络访问。缺少工具时会跳过扫描并在后台开始下载,以便下次运行能扫描。云任务或 CI 作业不会启动该下载:请在有网络访问的情况下在那里运行hogli ci:preflight --prepare-semgrep。不完整的扫描会带原因跳过。已在 master 上的发现不会被报告。CI 会因新发现而阻塞,因此在 push 前修复它。advisory 会打印显示该规则的命令。snapshot-baselines在frontend/snapshots.yml丢失了你分支未更改的 story 条目时给出建议。 这正是错误的合并冲突解决方式的表现。当这些 story 仍能渲染时,合并队列会使承载该文件的批次失败。运行该检查打印的git diff,并恢复你本不打算删除的条目。你在同一分支中删除、重命名或改标题的 story 的条目会通过。merge-queue-lane只警告,且 pre-push hook 会跳过它。 当少数横切文件(一个 CI 工作流、一个 lane 脚本)使整个 PR 声称占用每个合并队列 lane 时,它会触发,这会导致队列在其后面串行合并。当其他更改不需要这些文件时,把它们移到单独的 PR 中。- 陈旧性是基于风险的。 当 现在 合并 master 确实会破坏某些东西时它会触发 —— 文本合并冲突(通过
git merge-tree计算,工作树不受影响)、双方都添加了迁移、双方都更改了生成文件的输入,或 master 上更改了 CI 工作流 —— 外加一个落后/时长的兜底阈值,默认很激进(5 个提交 / 2 天;可通过环境变量HOGLI_PREFLIGHT_STALE_COMMITS/HOGLI_PREFLIGHT_STALE_DAYS调整),以便我们一开始过度警告,再根据遥测逐步收紧。触发时合并 master。仅作建议,永不自动合并。 · skipped (needs …)在裸检出或沙箱中是预期行为。needs stack/needs clickhouse需要运行中的开发栈(hogli start),needs node需要pnpm install,needs desktop-node需要pnpm --dir products/desktop install,needs agent-node需要pnpm --dir packages/agent install(两个嵌套工作区都被排除在根安装之外并拥有各自的 lockfile),needs python-env需要uv sync,因此同步的项目环境是 PATH 上的python。尽可能满足你能满足的,其余的交给 CI。你的环境中没有 hook(没有node_modules)?在 push 前自己运行这个循环。- 标志。
--against <ref>针对显式基线进行 diff;--json输出机器可读的摘要。 - 关闭开关。
HOGLI_PREFLIGHT_DISABLED=1使该命令(以及 hook)成为退出码为 0 的空操作。它是发布/紧急情况的杠杆 —— 请尊重它;切勿取消设置以强制运行。
为什么这很重要
草稿已经运行了一个精简的 CI 子集;真正昂贵的浪费是一个已经就绪的 PR 因某个确定性问题在完整矩阵上失败,被修复后又重新运行整个矩阵。在本地捕捉到这个问题是最省成本的 CI 节省方式。
评论
支持 Markdown