GitHub Actions で Go言語 のテストカバレッジをプルリクエストにコメントする

### はじめに
Goプロジェクトにおいて、テストカバレッジを定期的に監視し続けることは、コード品質を維持する上で非常に重要です。`GitHub Actions`を利用すれば、プルリクエストに対するテストカバレッジを自動でコメントとして付与することが可能になり、これによりレビュアーがカバレッジ情報を即座に確認できるようになります。この記事では、その具体的な手法を紹介します。具体的には、`GitHub Actions`を活用してGoのテストカバレッジをプルリクエストに自動コメントする方法、そして、プルリクエストの最後に新しいコメントを追加し、既存のコメントを更新する方法について詳しく解説します。

### 実装
1. リポジトリのルートディレクトリに`.github/workflows`という名前のフォルダを作成し、その中に`coverage.yml`という名前のファイルを作成します。このファイルに`GitHub Actions`ワークフローを記述します。
2. `coverage.yml`に以下の`YAML`コードを追加します。

```yaml
name: coverage
on: pull_request
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - uses: actions/setup-go@v3
        with:
          go-version: 1.18.0
      - name: run coverage
        run: |
          make coverage
      - name: Find existing comment
        id: find_comment
        uses: peter-evans/find-comment@v2
        with:
          issue-number: ${{ github.event.number }}
          body-includes: "## Test Coverage Report"
      - name: Delete existing comment
        if: steps.find_comment.outputs.comment-id
        run: |
          curl \
            -X DELETE \
            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            -H "Accept: application/vnd.github+json" \
            "https://api.github.com/repos/${{ github.repository }}/issues/comments/${{ steps.find_comment.outputs.comment-id }}"
      - name: Comment coverage on PR
        uses: peter-evans/create-or-update-comment@v3
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.number }}
          body-path: 'coverage.txt'
```

1. **actions/checkout@v3:** このステップでは、リポジトリをチェックアウトします。つまり、`GitHub`リポジトリのコードを`GitHub Actions`の実行環境にダウンロードします。ここでの`ref: ${{ github.event.pull_request.head.sha }}`は、プルリクエストの`HEAD`コミットを指すようにリファレンスを設定しています。

2. **actions/setup-go@v3:** Go環境をセットアップします。ここではGoのバージョンを`1.18.0`に設定しています。

3. **run coverage:** このステップでは、`make coverage`コマンドを実行してテストカバレッジを生成します。

4. **Find existing comment:** ここでは、`peter-evans/find-comment@v2`アクションを使用して、既存のテストカバレッジコメントを探します。コメントの本文に`"## Test Coverage Report"`が含まれているものを探します。既存のコメントが見つかった場合、そのコメント`ID`は次のステップで使用されます。

5. **Delete existing comment:** 前のステップで見つかったコメント`ID`がある場合にのみこのステップが実行され、そのコメントは削除されます。これは`curl`コマンドを使って`GitHub API`を呼び出し、コメントを削除するために行われます。

6. **Comment coverage on PR:** ここでは`peter-evans/create-or-update-comment@v3`アクションを使用して新しいテストカバレッジコメントをプルリクエストに追加します。コメントの本文は、前のステップで生成された`coverage.txt`ファイルの内容になります。


### Makefileのコマンド

```yaml
coverage:
	go test -short -v -covermode=count -coverprofile=coverage.out  | tee test_output.txt
	go tool cover -func=coverage.out | awk '/total/ {print "| **" $$1 "** | **" $$3 "** |"}' | tee coverage.txt
	cat test_output.txt | grep 'ok.*coverage' | awk '{print "| " $$2 " | " $$5 " |"}' | tee -a coverage.txt
	echo "## Test Coverage Report" > coverage_with_header.txt
	echo "| Package           | Coverage |" >> coverage_with_header.txt
	echo "|-------------------|----------|" >> coverage_with_header.txt
	cat coverage.txt >> coverage_with_header.txt
	mv coverage_with_header.txt coverage.txt
	rm test_output.txt
```

出力されるtxtファイルの中身の例
```txt
## Test Coverage Report
| Package           | Coverage |
|-------------------|----------|
| **total:** | **67.5%** |
| apihandler | 75.3% |
| utils | 60.2% |
| database | 70.1% |
```

追加されるコメントのサンプルは下記のようなものです。
![スクリーンショット 2023-05-19 20.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/5c34dd3e-100c-9141-502f-b7c20fda7d6e.png)


### まとめ
この記事を通じて、`GitHub Actions`を活用してGoのテストカバレッジをプルリクエストに自動的にコメントする手法、そして既存コメントの更新方法を学びました。このアプローチにより、コードレビューの過程でテストカバレッジの確認が非常に容易になります。さらに、プルリクエストが更新されるたびにコメントが最新の状態に保たれるため、テストカバレッジの変化を効率的に追跡することができます。これにより、プロジェクトの品質を一層向上させることが可能となります。


https://about.codecov.io/language/go/

https://github.com/marketplace/actions/go-coverage

https://github.com/gwatts/go-coverage-action

https://github.com/codecov/example-go