GitHub Actions の timeout-minutes の linter 及び一括設定ツール
GitHub Actions の timeout-minutes に関する lint rule 及び一括で timeout-minutes を設定するツールを作ったので紹介します。
timeout-minutes とは
timeout-minutes は GitHub Actions の job 及び step (workflow は対応していないはず) の設定項目の一つで、 job 及び step のタイムアウトです。
timeout-minutes で設定した時間以内に job 及び step が完了しない場合に強制的に終了し失敗扱いになります。
デフォルトは 360 分です。
ただし、 reusable workflow を使っている job は timeout-minutes をサポートしていません。
なぜ timeout-minutes を設定すべきなのか
デフォルトの 6 時間はかなり長く、ほとんどの job はそこまで長い時間はかかりません。
何らかの理由で処理がハングすると強制終了するまで延々と job は実行され続け、無駄にリソースを消費します。
タイムアウトを適切に設定することで早期に問題に気づき、ワークフローをリトライするなどして問題を解決できます。
適切な timeout の値はなにか
適切な timeout は job や step 毎に異なりますが、殆どの場合 30 分もあれば十分でしょう。
もちろん 30 分で終わらないようなものは 60 分とか適切に伸ばす必要がありますし、直ぐ終わるような処理であれば 10 ~ 20 分とかより短く設定してもよいでしょう。
また step 毎に設定することも出来ますが、個人的には job 単位で十分だと思います。
あまり細かく設定しても消耗してしまうのである程度余裕をもって設定するのが良いでしょう。
timeout-minutes が設定されているかチェックする lint rule
自分は ghalint という GitHub Actions の linter を開発していますが、 v0.2.12 から job の timeout-minutes が必須になりました。
現状除外設定はありません。 timeout-minutes を設定しないほうが良いようなケースが特に思い浮かばないからです。
また ghalint は 自分が開発する lintnet という汎用の linter にも module として移植されており、そちらの module にも同様の lint rule が追加されています。
これらを CI で実行することで timeout-minutes の設定を強制できます。
timeout-minutes を一括で設定
timeout-minutes が設定されていない多くの workflow がある場合、それらを全部手で修正するのは大変です。
そこで timeout-minutes が設定されていない job に自動で設定するツールを開発しました。
設定ファイルや環境変数などを必要としない非常にシンプルなツールです。
使い方は簡単で、 workflow があるリポジトリのルートディレクトリで ghatm set
というコマンドを実行するだけです。
ghatm set
そうすると timeout-minutes が設定されていない job に自動で timeout-minutes: 30
という設定が追加されます。
30 という値はコマンドラインオプションで変更できます。
ghatm set -t 60
既に timeout-minutes が設定されている job には何の影響もありません。
あくまで一括で同じ値を設定するだけなので、特定の job だけ別の値を設定するといったことには対応していません。
それをしたい場合はその job だけ手で修正すればよいでしょう。
このツールは YAML のコメントやインデント、空行、アンカーなどを維持しつつ、 timeout-minutes
を設定する行を追加します。
YAML にパッチを当てるツールやライブラリの中にはこれらを維持しないものもありますが、 ghatm ではそのへんを維持できるように工夫しています。
pull_request
イベントなどをフックして ghatm を CI で実行し、自動で feature branch に変更を push することで timeout-minutes の設定を自動化することも出来ます。
ただし、自動で設定された timeout-minutes の値が適切とも限らないので場合によっては修正が必要でしょう。
multi-gitter と ghatm で全リポジトリをまとめて修正
ghatm を使うと簡単に timeout-minutes を設定できますが、多くのリポジトリに対し手作業で ghatm を実行し pull request を作成するのは大変です。
そこで multi-gitter というツールを使うと特定の GitHub Organization ないし User の全リポジトリ(対象を絞ることも可能)に対しまとめて pull request を作成したり、作成した pull request をまとめてマージしたり出来ます。
自分が実際に multi-gitter を使って大量のリポジトリに timeout-minutes を設定したログはこちらです。
multi-gitter も ghatm も aqua でインストールできます。
今回は multi-gitter の run, merge コマンドを使いました。
- run: PR の作成
- merge: PR の merge
幾つかポイントを書いておきます。
- 作業ログを GitHub Issue か何かに残しておく。作成する PR の description に issue への URL を含める
- ローカルで実行したスクリプトなどは GitHub で管理し、後から参照できるようにしておく
- multi-gitter の git-type は cmd にする
- デフォルトでは go-git が使われ、コミットに署名がされない場合がある
- https://github.com/lindell/multi-gitter/issues/261
-
--skip-forks
で fork は対象外にする - merge コマンドは CI が失敗している pull request はマージしないのでエラーを解消する必要がある
multi-gitter は今回はじめて使いましたが、便利ですね。
例えば pinact を実行して GitHub Actions のバージョンを固定するのもまとめて出来そうです。
Discussion