github-comment で PR にコメントをして CI の結果を分かりやすくする
e.g. github-comment で Envoy Proxy の設定の validation に失敗したら通知
github-comment というツールを使って GitHub の Pull Request (以下 PR) にコメントをして CI の結果を分かりやすくする方法について紹介します。
執筆時点で最新バージョンは v4.1.0 です。
github-comment とは
github-comment は GitHub の commit, issue, PR にコメントをしたり、コメントを非表示にする CLI ツールです。
YAML の設定ファイルにコメントのテンプレートなどを記述し、それを元にコメントします。
シェルスクリプトとコメントのテンプレートを分離できるので、メンテナンス性が高いです。
3 つのサブコマンドがあります。
- post: コメントをする
- exec: 指定した外部コマンドを実行し、その結果に基づいてコメントをする
- hide: 条件にマッチしたコメントを非表示にする
態々 CI のログを見にいかなくても PR のページで結果を確認でき、
なおかつ素のログに比べて非常に分かりやすくできるのが特徴です。
hide コマンドで古いコメントを非表示にすることで、コメント欄が荒れるのを防ぐことも出来ます。
コメントのテンプレートは Go の html/template でパースされ、動的にコメントを生成することが出来ます。
template 中では sprig の関数が使えます。
exec では Go の antonmedv/expr という expression engine を使い、
コマンドの実行結果などに応じてコメントするか否か、するならどのテンプレートを使うかを変えることが出来ます。
例えば、特定の文字列 (Delete
, Warning
, Rate Exceeded
, etc) を含んでいたらコメントするとか、文面を変えるといったことも出来ます。
コマンドが失敗したら通知
CI が失敗したとき通常 CI のログを確認しますが、
どのコマンドが失敗したのか、どこからログを見ればよいのかわかりにくいことがあると思います。
また、そもそもログを見ない人もいます。
コマンドの前に github-comment exec --
とつけることによって、コマンドが失敗した場合に失敗したコマンドとその出力をコメントできます。
成功した場合はコメントされません。
$ github-comment exec -- curl --fail -LO https://github.com/suzuki-shunsuke/tfcmt/releases/download/v3.0.0-2/tfcmt_linux_amd64.tar.gz
失敗したコマンドとその出力がぱっとわかります。
これだけであれば設定ファイルも不要です。
github-comment exec の exit code は元のコマンドから引き継がれますし、標準入力も元のコマンドに渡されますし、標準(エラー)出力もそのまま出力されます。
コマンドが失敗したときに案内をする
上記のように単にコマンドとその出力をコメントするだけでなく、より丁寧に修正方法などを案内できます。
CI に Linter などを導入する場合、ツールを導入して CI が失敗するようになったら終わりではなく、
失敗したあとに適切にハンドリングできるようになっているのが重要です。
github-comment によって適切に案内することによって、トラブルを自己解決できるようにし、生産性を高めることが出来ます。
これは大きな組織・チームで様々な人が CI を実行する場合に特に重要です。
例
- コードがフォーマットされていなかったら、フォーマットするコマンドを案内
- ドキュメントをコードから自動生成している場合に、更新が漏れていたら(あるいはドキュメントを直接更新していたら)コマンドで更新するように案内
- Conftest のポリシーに引っかかったら、ポリシーのドキュメントを案内
- Linter の Rule のドキュメントや、場合によっては ignore する方法の案内(安易に ignore すべきではないとは思いますが)
Conftest の Policy 違反を分かりやすくする
特に Conftest と組み合わせて使うのは便利かなと思います。
Conftest のエラーメッセージが ユーザーにとって分かりにくかったり、メンテナンスしづらかったりするからです。
業務で Terraform や k8s manifest などのテストに Conftest を導入した際、
当初はエラーメッセージが分かりにくかったためユーザーにちゃんと伝わらず、
「なんか CI こけるんだけどどうしたらいいの?」という質問が来ることがままありました。
そこで Policy のファイルと同じ名前で同じディレクトリに Policy に関するドキュメントを作成し、そのドキュメントへのリンクを github-comment でコメントするようにしました。
e.g. Terraform で aws_cloudwatch_log の retention_in_days の設定を強制する Rule
policy/
cloudwatch_log_retention_in_days.md
cloudwatch_log_retention_in_days.rego
cloudwatch_log_retention_in_days_test.rego
# エラーメッセージのみ抜粋
msg = sprintf("%s: [retention_in_days should be set and greater than 0](%s)", [value.address, "https://github.com/suzuki-shunsuke/example-github-comment/tree/main/policy/cloudwatch_log_retention_in_days.md"])
github-comment.yaml
exec:
conftest:
- when: ExitCode != 0
template: |
## :x: Violate Conftest Policy
{{template "link" .}}
{{template "join_command" .}}
{{.CombinedOutput | AvoidHTMLEscape}}
Conftest のエラーメッセージは最小限にして、ドキュメントへと誘導します。
Conftest の Rule に関してドキュメントを書いておくと後で「この Rule なに?なんで必要なの?」ってならなくて良いので便利です。スクショにはないですが、 Rule を追加した背景(issue, Slack のメッセージ, etc) の link があると後で便利ですね(時間が経つと状況が変わったりするので)。
github-comment post
ここまで主にコマンドの実行結果に応じてコメントをする github-comment exec
について書きましたが、
コマンド関係なくコメントしたい場合、 github-comment post が使えます。
特殊な例ですが、 terraform apply が実行されて State が更新された際に、既存の PR の CI を自動で Rerun する通知を飛ばしている例
古いコメントを非表示にする
でも紹介していますが、コメントを非表示にする事もできます。
Batch Job で Issue にコメントをする
これまで CI で PR にコメントする場合について主に説明しましたが、
別の使い方として、定期実行するジョブの結果を issue にコメントするとかもあるかもしれません。
そのような使い方はしたことがないですし、ニーズがあるか分かりませんが。
ローカルではコメントしないようにする
CI で実行しているスクリプトをローカルでも実行したい場合、スクリプト内で github-comment が呼ばれると困ることがあります。
そういう場合、 GITHUB_COMMENT_SKIP
という環境変数を設定すると github-comment は呼ばれません。
post, hide はなにもしないし、 exec もコマンドを実行するだけです。
$ export GITHUB_COMMENT_SKIP=true
Install
Go 製なので簡単に install 出来ます。
- Homebrew:
brew install suzuki-shunsuke/github-comment/github-comment
- aqua
- GitHub Releases
個人的には aqua を使ってバージョン管理をするのがオススメです。
コメントをするには GitHub の Access Token を環境変数 GITHUB_TOKEN
に設定する必要があります。
さいごに
github-comment というツールを使って GitHub の Pull Request (以下 PR) にコメントをして CI の結果を分かりやすくする方法について紹介しました。
詳細はドキュメントや Release Note を参照してください。
Discussion