✏️

actions-timelineがcomposite actionsを展開してタイムライン表示可能になった

に公開

actions-timelineがcomposite actionsの展開をサポートしました

GitHub Actionsの各ステップにどれだけ時間がかかっているかをタイムライン形式で表示できるKesin11/actions-timelineというOSSを開発しています。actions-timelineのリリース当初から要望をいただいていたものの、今まで実現できなかった機能の1つに、composite actionsを実際に実行されている各stepへ分解する機能がありました。先日リリースしたv3.1.0で、ようやくそれを実装できました。

以下のオプションを指定すると、composite actionsを展開してタイムライン上に表示できます。

- uses: Kesin11/actions-timeline@v3.1.0
  with:
    expand-composite-actions: true
    expand-composite-actions-threshold: 10  # 10秒以上のcomposite actionsのみ展開。デフォルトは20秒

composite actionsを展開した例
actions-timelineの例。composite actionsが展開されている箇所を赤線で示しています

actions-timelineだとcomposite actionsの時間が短すぎてタイムライン表示が分かりにくいため、もう少し分かりやすい例としてdirectus/directusというリポジトリの例を紹介します。

directus/directusの例
directus/directusの例。Prepareというcomposite actionが展開されている箇所を赤線で示しています

Prepareというcomposite actionにnpmのインストールなどの処理がまとめられており、それが展開されているため、どのstepに時間がかかっているのかが分かりやすくなっています。

expand-composite-actions: trueを指定するともともとのcomposite actionsの時間に加えて、中身のstepごとの時間も表示されるようになります。展開後のstepと区別できるように (sub) という名前がprefixについています。スクショの例では Run ./.github/actions/setup-deno-with-cache が元のcompositeで、その下の(sub)がついている3つのstepがcompositeから展開されたものです。

すべてのcomposite actionsが展開されるとタイムライン全体がごちゃついて見にくくなってしまうため、デフォルトでは20秒以上かかっているcompositeのみが展開されるようになっています。これは、短時間のcompositeを展開しても、actions-timeline本来の目的である「CIのどこに時間がかかっているかを見つける」という点では得られる情報が少ないと判断したためです。このしきい値はexpand-composite-actions-thresholdで変更できます。

複雑なワークフローを組んでいる場合は共通処理をcomposite actionsにまとめているケースが多いと思いますが、そこに時間がかかっていても今までのactions-timelineでは可視化できませんでした。v3.1.0のアップデートでその展開が可能になったので、今までお困りだった方はぜひ試してみてください。

技術的な話

composite actionsの展開が今までなぜ難しかったのかというと、actions-timelineはGitHub ActionsのList jobs for a workflow run attempt というAPIから得られる情報を使っていました。このAPIではjobに含まれる各stepのそれぞれにどれだけ時間がかかったかを取得できるのですが、composite actionsはstepの1つとして扱われてしまうため、中身のstepの情報は取得できません。それが理由で今までは諦めていました issue#37

しかしあるとき、Shunsuke Suzuki氏が公開していたghaperfを見て、Composite Actionsの分析まで可能にしていることを知りました。

https://zenn.dev/shunsuke_suzuki/articles/ghaperf-github-actions-performance-analysis

ghaperfはAPIから取得できるstepの時間ではなく、ジョブの生ログのlog groupを使ってcomposite actionsの中身のstepの時間も計算したとのことでした。

actions-timelineでも同様に自前でジョブの生ログをパースすれば実現できそうだったものの、自前でやるにはさすがに気合が必要で二の足を踏んでいたのですが、Claude CodeのOpus 4.6がやってくれました。AI様様です。

composite actionsの展開はできたとはいえ、展開後のstepの見せ方は正直あまり納得できていないのですが、mermaidの制約上これ以上は難しそうです。本当は展開後のstepのバーの色を変えたり、枠を点線にしたりとか視覚的に分かりやすくしたかったのですが無理でした。もともとmermaidのガントチャート機能で無理やりそれっぽいタイムライン表示にしているのでそろそろ限界か。

AIに実装してもらった話

2025年はClineから始まり、GitHub Copilot、Claude CodeとAIコーディングツールを試していたので、そこで得たノウハウを使いました。この機能を実装した頃はClaude Code + Opus 4.6が主力だったころです(この記事の執筆時点では後継のOpus 4.7が登場し始めました)。

この頃のテクニックとして、単に指示を与えてコードを書かせるだけではなくて、エージェントが自分で検証して修正を繰り返せるような仕組みを用意してあげることで自律的に完了条件を満たすまで粘り強く実装を続けてくれるという方法が知られていました。

actions-timelineはもともとGitHub Actions上で動くactionですが、実はCLI版もあります。CLI版はGitHub Actions版と同じロジックで時間の集計をしますが、最終的に生成されたmermaidを.mdファイルとしてローカルに出力してくれます。今までも自分のデバッグ用に活躍していましたが、これをエージェントにも活用してもらいました。
ジョブの生ログからパースする処理の実装 <-> CLIから生成されたmermaidが正しいかを検証 のループを繰り返す指示を与えること、エージェント自身が正しいmermaidを生成できたと判断するまで、自律的に修正を繰り返してくれました。
実際にはプランモード中に以下のような指示を与えました。

最後にこの後の実装で正しく実装できているかの検証として、 cli.ts を利用して実際にactions-timelineのCIの結果からmermaidのガントチャートを作成し、それをGitHubの/repos/{owner}/{repo}/actions/jobs/{job_id}/logsのAPIで取得できるログと突き合わせて、composite actions内のステップの時間を正しくガントチャートに描画できているかを検証してください。
正しく描画できていなかった場合は正しく描画できるまで実装の問題点を考えて繰り返してください。

生成されたプランがissue#285で、最終的にこの検証についての記述になったようです。

Verification plan (manual)

Use this repo’s CI and the CLI:

  1. Pick a CI run URL from actions-timeline.
  2. Run CLI with --show-composite-actions=true and save Mermaid output.
  3. For the job that runs ./.github/actions/setup-deno-with-cache, download its job logs:
    • gh api /repos/Kesin11/actions-timeline/actions/jobs/<job_id>/logs > job.log
  4. Compute expected durations for inner steps from log blocks:
    • ##[group]Run denoland/setup-deno@v1 ... ##[endgroup]
    • ##[group]Run actions/setup-node@v6 ... ##[endgroup]
  5. Compare to Mermaid sub-bars (allow small tolerance; e.g. duration ±3s).

試しにやらせてみたら非常にうまくいったので、その手順をskillにもしてもらってリポジトリにコミットしておきました。これによって以降の実装でもデグレしていないかの確認に活用でき、簡易的なE2Eテストを追加したような感じでした。

実際の生ログと生成されたmermaidを見比べて、compositeが正しく展開されたかを目視確認するのは地味に手間がかかる作業です。そこをAIに任せられたことで、自分は生成されたmermaidの見た目の違和感を指摘したり、改善のアイディアを伝えたりするぐらいで済みました。そのときに生まれたのが、展開後のstep名に (sub) をprefixとして付けて分かりやすくしたり、 expand-composite-actions-threshold オプションを追加してデフォルトでは短時間のcompositeを展開しすぎないように抑制したりするアイディアです。

あらゆるタイプのプログラムやツールの開発に使えるとは限りませんが、必要であればユニットテスト以外にもエージェントが検証可能な方法を用意し、実装 <-> 検証のループを構成する方式はおすすめできます。

サイボウズ 生産性向上チーム 💪

Discussion