PRの差分に応じてコメントするGitHub Actionsを作って公開した
はじめに
自分のチームでは開発のフレームワークにスクラムを採用しており、Google が提唱したFour Keysを元に開発生産性の向上に取り組んでいます。その中でデプロイ頻度や変更のリードタイムを改善する目的として、PR の差分をチーム内で決めた行数以下にするというルールを導入しています。
これによって PR の粒度が細かくなるので、レビューのコストが大幅に減ります。また、実装の方向性が間違っている場合も早期に気づけるので、手戻りの発生を未然に防ぐことができます。
しかし、この変更差分を特定に行数以下に収めること自体は個人の努力義務になっています。
そこで、このルールの促進と変更行数に関する口頭の指摘を防ぐことを目的として、PR の変更行数に応じてコメントをする GitHub Actions を作成しました!
今回は作成した GitHub Actions について紹介したいと思います!
今回紹介する GitHub Actions は Marketplace にも公開してあり、簡単に導入できるので興味のある方はぜひ使ってみてください!
作成した GitHub Actions
今回作成した GitHub Actions の全体像は下記になります。
処理の流れ
inputs
のバリデーション
1. inputs
として
-
threshold
:変更行数の上限 -
message
:上限を超えた際のメッセージ
を受け取ります。
それぞれがちゃんとセットしてあるかをチェックします。
2. 変更行数の計算
ベースブランチの最新のコミットと、headのコミットの差分を計算します。git diff --numstat
で追加・削除された行数を出力して、awk
コマンドでそれぞれを足し合わせて変更行数を算出します。
3. 変更行数の評価
inputs
で受け取った変更行数の上限と、2 で計算した実際の変更行数を比較します。
4. PR にコメント
3 で変更行数が上限を超えている場合、PR にコメントをします。
詰まった箇所
inputs
のバリデーションは手動で行う必要がある
inputs
のthreshold
とmessage
にはrequired: true
を指定しています。ただ、required: true
を指定しても値が設定されているかは検証されません。こちらに関しては Issue でも議論されています。
そのため今回は Issue に載っていた方法を用いて、明示的にinputs
の検証をすることにしました。
- name: Validate inputs
run: |
[[ "${{ inputs.threshold }}" ]] || { echo "threshold input is empty" ; exit 1; }
[[ "${{ inputs.message }}" ]] || { echo "message input is empty" ; exit 1; }
shell: bash
if
での比較が文字列として評価されてしまう
最初は PR にコメントをするステップの条件は下記のように記載していました。
if: env.GIT_DIFF > inputs.threshold
ただこれだと文字列の比較として扱われてしまい、期待する挙動にならないことがありました。
そのため、変更行数の評価は shell のexpr
コマンドを使用して比較を行い、結果をアウトプットとして出力するようにしました。そのアウトプットをif
で評価することで PR にコメントをするステップの実行を制御しています。
- name: Evaluate Git diff
id: evaluate_git_diff
run: |
diff=${{ env.GIT_DIFF }}
threshold=${{ inputs.threshold }}
result=$([ "$(expr $diff \> $threshold)" = 1 ] && echo "true" || echo "false")
echo "should_post_comment=$result" >> $GITHUB_OUTPUT
shell: bash
- name: Post comments
if: steps.evaluate_git_diff.outputs.should_post_comment == 'true'
# 省略
まとめ
やりたいことはシンプルだったのですが、いざ作ってみると意外と詰まる箇所があったのでいい勉強の機会になりました。
自動生成の差分は除外するなどいくつかやりたいことはあるので、今後も改善を進めていこうかなと思っています。
Discussion