表題のものを書きました。
CIをもっと高速に回したい、という欲求は誰しも持っていると思います。CIを高速化することは、開発のテンポを上げることにも、機能リリースまでのリードタイムを下げることにもつながります。 一般的にもそうだと思いますが、測定して現状を把握し、ボトルネックになっているステップを特定することが高速化の一歩になります。
GitHub Actionsのweb UIは、各workflowのjobのステップごとにかかった時間を網羅的に見るのには向いていません。各jobのログを見て、手で集計する、というのはできなくはないと思いますが日が暮れてしまいます。
都合の良いことに、GitHub Actions workflowに関する情報を取ってこれるREST APIが提供されています。これを使わない手はないでしょう。kataribeのように、各ステップの所要時間の統計が取れればプロファイルの手がかりがつかめるはずです。……ということでガッと書きました。 TOMLで設定できるとか、アクセストークンは環境変数経由で渡すことができるとか、自分が使うにあたって欲しいであろう機能はひと通り実装できたと思います。
たとえば、以下は github.com/utgwkk/Twitter-Test のGitHub Actions (.github/workflows/ci.yml) をプロファイルした結果です。 cpanm -L local --installdeps .
の所要時間の最大値が跳ねているのは、 local
ディレクトリのキャッシュがないときにモジュールを全部インストールすることになるからだ、と推測できます。Maxは大きいけど50%ileで見るとそこまでないとか、最近はキャッシュが効いているのでインストールに時間はかからなくなった、ということも読み取れるでしょう。
Job: Perl 5.32 Number Min Median Mean P50 P90 P95 P99 Max Name 1 2.000000 3.000000 3.217391 3.000000 4.000000 4.000000 5.500000 6.000000 Set up job 2 1.000000 1.000000 1.362319 1.000000 2.000000 3.000000 3.000000 3.000000 Run actions/checkout@v2 3 0.000000 1.000000 1.159420 1.000000 2.000000 3.000000 5.000000 6.000000 Run actions/cache@v2 4 1.000000 2.000000 1.971014 2.000000 2.000000 2.000000 3.000000 3.000000 Set up Perl 5 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 Remove Perl Problem Matcher 6 0.000000 0.000000 6.840580 0.000000 2.500000 26.000000 176.500000 178.000000 Run cpanm -L local --installdeps . 7 0.000000 2.000000 1.608696 2.000000 3.000000 4.000000 5.000000 6.000000 Run cpanm -L local Test2::Plugin::GitHub::Actions::AnnotateFailedTest 8 2.000000 3.000000 2.741935 3.000000 3.000000 3.500000 4.000000 4.000000 Run prove -Ilocal/lib/perl5 -Ilib -lv t 13 0.000000 0.000000 0.394737 0.000000 1.000000 1.000000 1.000000 1.000000 Post Run actions/cache@v2 14 0.000000 0.000000 0.210526 0.000000 1.000000 1.000000 1.000000 1.000000 Post Run actions/checkout@v2 15 0.000000 0.000000 0.260870 0.000000 1.000000 1.000000 2.500000 3.000000 Post Run actions/cache@v2 16 0.000000 0.000000 0.129032 0.000000 0.500000 1.000000 1.000000 1.000000 Post Run actions/checkout@v2 17 0.000000 0.000000 0.032258 0.000000 0.000000 0.000000 0.500000 1.000000 Complete job
プロファイル結果をJSONで出力することもできます。JSONを加工してMackerelにメトリックとして投稿する、ということもできるかもしれません。
既知の不具合
設定ファイル (TOML) を渡しつつコマンドライン引数にも値を渡したとき、直感的にはコマンドライン引数の値が優先されてほしいけどされていない- Goの
flag
モジュールは、コマンドライン引数が渡されていないときデフォルト値を使う実装になっている- そのため、コマンドライン引数が渡されなかったのか、デフォルト値が指定されたのかの区別がつかない
-count
はアドホックになんとかしてる
- 真偽値のフラグなどはどうしようもない気がするのでなんかいいライブラリに乗り換えたい
flag
モジュールでも実現できることを教えてもらったけどすでにライブラリ変える方向で修正していた
- Override TOML config with cli arguments by utgwkk · Pull Request #4 · utgwkk/github-actions-profiler で修正しました
- Goの
- GitHubのREST APIが返すjobの統計情報に含まれる、各ステップの開始・終了時間はミリ秒以下が切り捨てられている
- 小数点以下を出してるけど平均値でしか意味を成さない……
- 将来的にタイムスタンプがミリ秒単位で返されるようになったら嬉しい
ジョブの出力順が毎回変わる- これは単純にmapに対してforループを回しているのでこうなっている (Hash Randomization的なやつだと思う)
- 名前でソートとかすればよい気がする
- Sort profile output in alphabetical order of job name by utgwkk · Pull Request #5 · utgwkk/github-actions-profiler · GitHub で修正しました
- テストがほぼない
- 整えたい!!!