GitHub Actions 变慢时,表面上最容易看到的是某个 job 花了十几分钟。但真正要优化时,这个粒度往往不够:慢的是 checkout、依赖安装、缓存恢复、某个 composite action,还是脚本里的某个分组?如果团队只看 workflow run 的总耗时,很容易把时间花在不该优化的地方。

今天推荐的 suzuki-shunsuke/ghaperf 正好解决这个更细的观察问题。它是一个 Go 编写的命令行工具,通过 GitHub API 获取 workflow run、job 和原始 job log,再从日志中解析 step 和 log group 的耗时,输出 Markdown 性能报告。GitHub 搜索结果当前显示项目约有 32 stars0 forks,主要语言是 Go,许可为 MIT。仓库创建于 2025 年 10 月 26 日,最近仍在 2026 年 5 月 29 日更新;README 和 tag 信息显示最新版本为 v0.1.1

项目概览

属性详情
仓库suzuki-shunsuke/ghaperf
Stars约 32
Forks0
主要语言Go
许可MIT
创建时间2025 年 10 月 26 日
最近更新2026 年 5 月 29 日
最新 releasev0.1.1

把 CI 性能问题拆到 step 级别

ghaperf 的核心价值不是替代 GitHub Actions 的页面,而是把“哪个地方慢”拆得更细。README 里最强调的一点是:它可以通过解析 job log,看到 composite action 内部的瓶颈。很多 Actions 性能工具能展示 job 或 step 的时间线,但 composite action 往往会被压成一个大 step;如果这个 step 里又执行了安装工具、拉依赖、跑脚本,就很难知道到底是哪一段拖慢了 CI。

ghaperf 会读取原始日志里的时间信息,并把超过阈值的慢步骤整理出来。它也支持 GitHub Actions 的 log group。如果 action 或脚本里使用 ::group:: / ::endgroup:: 把内部阶段分组,ghaperf 就能继续向下分析这些 group 的耗时。

这对维护 CI 的人很有用。很多流水线并不是被一个明显的命令拖慢,而是被几个“看起来正常”的小段反复累积:缓存没有命中、安装器每次都重新下载、某个平台的 runner 初始化特别慢、某个矩阵组合偶尔变成异常值。把这些信息汇总成报告,比逐个点开 job log 手动读时间戳更可靠。

三种分析入口

ghaperf 提供了几个常见入口。

最常用的是按 workflow 分析多次 run:

ghaperf \
  --repo suzuki-shunsuke/ghaperf \
  --workflow test.yaml \
  --count 10 \
  --threshold 2s

这种模式适合找稳定瓶颈。单次 CI 可能受网络、runner 调度和缓存状态影响,噪声很大;看最近 10 次或 100 次 run,才能判断某个步骤是长期慢,还是偶发慢。

第二种是分析单个 workflow run:

ghaperf \
  --repo suzuki-shunsuke/tfaction \
  --run-id "<workflow run id>"

这适合排查一次具体失败或一次异常慢的构建。第三种是直接按 job id 分析某个 job:

ghaperf \
  --repo suzuki-shunsuke/tfaction \
  --job-id "<workflow job id>"

如果你已经在 GitHub 页面里定位到一个 job,这种入口最直接。除此之外,ghaperf 还支持 --log-file,可以分析本地保存的 job log。这个模式很适合调试解析行为,也适合在不想重复请求 GitHub API 时复现问题。

Markdown 报告适合贴进 PR 或 issue

ghaperf 的输出是 Markdown 报告。报告里会列出分析对象、阈值、workflow run 数量、每个 job 的平均耗时、最慢 job 链接,以及慢 step 的聚合结果。README 示例中,它会把同一类 job 的耗时汇总,并列出例如 Run aqua i --testrustup updateactions/checkout 这类慢点。

这个格式很适合团队协作。CI 优化经常需要先说服别人:“我们不是凭感觉觉得慢,而是最近 N 次 run 里某个阶段平均消耗了这么多时间。”Markdown 可以直接贴进 PR、issue、Slack 或内部文档,链接又能回到具体的 GitHub job。

对自动化也友好。它不是一个需要长期跑着的 Web 服务,也不需要先搭指标库。你可以在本地或 CI 里按需执行一次,把报告作为构建产物或评论输出。对于小团队来说,这种一次性分析工具的维护成本很低。

配置:过滤和归一化 job 名称

GitHub Actions 的矩阵 job 名称经常很长,而且参数变化会让同一类任务看起来像不同 job。ghaperf 提供配置文件来处理这个问题。

配置可以用 ghaperf --init 生成,主要字段包括:

job_names:
  - "test / test / test .*"

excluded_job_names:
  - "experimental .*"

job_name_mappings:
  "test / test / test .*": "test / test / test"

job_names 用来只分析匹配的 job,excluded_job_names 用来排除不关心的 job,job_name_mappings 则把矩阵或历史改名后的 job 归一化到同一个名称下。项目还提供 JSON Schema,可以在编辑器里启用补全和校验。

这类配置看起来不显眼,但对 CI 性能分析很关键。没有过滤时,报告可能被大量无关 job 淹没;没有归一化时,同一条测试流水线在不同平台、不同参数下会分散成很多条记录,难以看出整体趋势。

不需要指标存储,但需要 token

ghaperf 的另一个特点是“不需要后端”。它通过 GitHub API 和 job log 当场分析,不要求用户搭 Prometheus、BigQuery、OpenTelemetry collector 或自定义数据库。对只想排查一次瓶颈的人来说,这个门槛很低。

不过它确实需要 GitHub access token。README 明确说明,即使是公开仓库,下载 action logs 也需要 token;私有仓库至少需要 Actions: Read 权限。ghaperf 支持从 GITHUB_TOKENGHAPERF_GITHUB_TOKEN 读取 token,也可以启用作者另一个工具 ghtkn 的集成。

它还会缓存已完成 workflow run 和 job 的 API 响应,默认位置在 ${XDG_CACHE_HOME:-${HOME}/.cache}/ghaperf/。这可以减少重复请求,也能降低多次分析同一批 run 时的等待时间。

安装路径偏 CLI 用户

ghaperf 是 Go 项目,安装方式比较直接。官方文档列出 Homebrew、aqua、GitHub Releases 和 go install 四种方式:

brew install suzuki-shunsuke/ghaperf/ghaperf --cask
aqua g -i suzuki-shunsuke/ghaperf
go install github.com/suzuki-shunsuke/ghaperf/cmd/ghaperf@latest

官方支持的二进制平台目前包括 Linux amd64/arm64 和 macOS arm64,其他平台可以从源码构建。Release 资产还提供了 GitHub CLI、slsa-verifier 和 Cosign 的验证说明。对于会关注 CI 性能的用户,这种供应链验证文档是加分项。

适合什么场景

ghaperf 适合几类非常具体的场景:

  • 你维护的 GitHub Actions workflow 越来越慢,但页面上的 job 总时长不够解释问题;
  • 你大量使用 composite actions,想知道 action 内部到底哪一段慢;
  • 你希望按最近 N 次 run 汇总慢步骤,而不是只看一次偶发结果;
  • 你需要把 CI 性能报告贴到 PR、issue 或内部复盘文档里;
  • 你不想为了偶尔分析 CI 性能而维护一套指标存储;
  • 你愿意在脚本里用配置文件过滤 job、归一化矩阵名称。

如果你要做的是长期趋势监控、跨仓库仪表盘或成本报表,ghaperf 可能不是完整方案。它更像一个诊断工具:当你怀疑某条流水线变慢时,快速把日志拆开,找出最值得先看的环节。

需要注意的边界

ghaperf 依赖 GitHub job log,而 GitHub 的日志格式并不是一个正式稳定的公开协议。README 也提醒,解析逻辑基于观察到的格式,如果 GitHub 改变日志格式,工具可能需要跟进修复。

日志也有保留期。GitHub Actions 的日志默认保留 90 天,组织可以调整这个时间。太旧的 run 如果日志已经被清理,ghaperf 就无法分析。刚完成的 job 也可能需要等 GitHub 处理完日志后再重试。

另外,ghaperf 能指出“哪里耗时”,但不会自动判断“怎样优化”。发现 rustup update 慢之后,下一步可能是缓存、固定 toolchain、预装 runner,或者只是接受它。工具提供证据,具体改法仍要结合项目上下文。

总结

suzuki-shunsuke/ghaperf 是一个很窄但很实用的 CI 诊断 CLI。它不试图建立一整套观测平台,而是专注于从 GitHub Actions 的 API 和 job log 里提取 step、log group 和 job 的耗时,把“CI 慢”这个模糊问题拆成可以讨论的报告。

对经常维护 GitHub Actions 的团队来说,它最有价值的地方在于看见 composite action 内部。很多时间浪费就藏在这些封装步骤里;ghaperf 把它们摊开,让优化从猜测变成证据驱动。

项目地址:https://github.com/suzuki-shunsuke/ghaperf