💪

github-comment で PR にコメントをして CI の結果を分かりやすくする

2021/12/28に公開

e.g. github-comment で Envoy Proxy の設定の validation に失敗したら通知

image

github-comment というツールを使って GitHub の Pull Request (以下 PR) にコメントをして CI の結果を分かりやすくする方法について紹介します。

https://github.com/suzuki-shunsuke/github-comment

執筆時点で最新バージョンは 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

image

失敗したコマンドとその出力がぱっとわかります。
これだけであれば設定ファイルも不要です。

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}}

image

Conftest のエラーメッセージは最小限にして、ドキュメントへと誘導します。

image

Conftest の Rule に関してドキュメントを書いておくと後で「この Rule なに?なんで必要なの?」ってならなくて良いので便利です。スクショにはないですが、 Rule を追加した背景(issue, Slack のメッセージ, etc) の link があると後で便利ですね(時間が経つと状況が変わったりするので)。

github-comment post

ここまで主にコマンドの実行結果に応じてコメントをする github-comment exec について書きましたが、
コマンド関係なくコメントしたい場合、 github-comment post が使えます。

特殊な例ですが、 terraform apply が実行されて State が更新された際に、既存の PR の CI を自動で Rerun する通知を飛ばしている例

image

古いコメントを非表示にする

https://zenn.dev/shunsuke_suzuki/articles/improve-terraform-cicd-with-tfcmt

でも紹介していますが、コメントを非表示にする事もできます。

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 出来ます。

個人的には aqua を使ってバージョン管理をするのがオススメです。

https://zenn.dev/topics/aquaclivm

コメントをするには GitHub の Access Token を環境変数 GITHUB_TOKEN に設定する必要があります。

さいごに

github-comment というツールを使って GitHub の Pull Request (以下 PR) にコメントをして CI の結果を分かりやすくする方法について紹介しました。
詳細はドキュメントや Release Note を参照してください。

https://github.com/suzuki-shunsuke/github-comment

Discussion