TalentX Tech Blog

Tech Blog

golangci-lintとGitHub Actionsでlinterの新たなissueのみを通知する

MyTalentという採用MAサービスの開発を担当している、バックエンドエンジニアの樋口です!

MyTalentではGo言語でバックエンドの開発を行っています。サービス運用開始から2年が経過したタイミングで、新たなバックエンドエンジニアが増えても一定のコード品質を保つために、golangci-lintを導入しました。

この記事では、golangci-lintを導入した際に発生した問題と解決方法について記載します。これからgolangci-lintの導入を検討している方の参考になれば幸いです。

golangci-lintとは

golangci-lintはGo言語用のlinter実行ツールです。 github.com

Go言語には、エラーのチェック漏れを確認するerrcheckや、コードのシンプルさをチェックするgosimpleなど、様々なlinterが存在します。

本来は導入するlinterごとに実行が必要ですが、golangci-lintを利用することで一括でlinterの実行を行えます。
golangci-lintで実行することができるlinterはこちらから確認できます。

導入の目標

PRで発生したlinterのissueを自動的に検出し、GitHub Actionsを用いてPRへのコメントを自動生成することです。

発生した問題

GitHub Actionsでgolangci-lintを実行すると、PRで新たに発生したissueに対するコメントが欲しかったのですが、元々発生していたissueへのコメントが表示され、新たに発生したissueにはコメントされませんでした。
これは、既存のissueも含めて作成され、golangci-lintの各linterごとのissue作成上限に達したためでした。

解決方法

golangci-lint実行時にnew-from-revのオプションを設定することで、この問題を解決できました。
golangci-lintではnew-from-revを設定することで、指定したgitリビジョンでは発生していなかったissueのみを作成できます。

例えば、new-from-revにdevelopブランチを設定すると、developブランチで発生していなかったissueが検出されます。

 golangci-lint run --new-from-rev=develop

GitHub Actionsでgolangci-lintにこのオプションを設定して実行した際にエラーが発生したため、MyTalentでのGitHub Actions設定を簡略化しつつ、エラーの原因と対応方法を記載します。

GitHub Actionsの設定

name: reviewdog
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  golangci-lint:
    name: "reviewdog/golangci-lint"
    runs-on: ubuntu-latest
    steps:
      - name: Check out base branch latest commit
        uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.base.ref }}
      - name: Check out PR open branch latest commit
        uses: actions/checkout@v3
      - name: Run golangci-lint
        uses: reviewdog/action-golangci-lint@v2
        with:
          go_version_file: "./go.mod"
          golangci_lint_flags: "--config=.golangci.yml --new-from-rev=origin/${{ github.event.pull_request.base.ref }}"
          level: info
          filter_mode: nofilter
          fail_on_error: true
          reporter: github-pr-review

各ステップについて説明します。

ステップ1: ベースブランチの最新コミットにチェックアウト

このステップではベースブランチの最新コミットにチェックアウトしています。

      - name: Check out base branch latest commit
        uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.base.ref }}

このステップを省略すると、以下のエラーが発生します。

Can't process result by diff processor: can't prepare diff by revgrep: could not read git repo

これは、golangci-lintのnew-from-revで指定したgitリビジョンを取得できない場合に発生するエラーです。
ステップ1ではPRを作成したブランチの最新のgitリビジョンのみを取得しているため、golangci-lintでPRのベースブランチとの差分を検出しようとした際にgitリビジョンを参照できずに発生します。

${{ github.event.pull_request.base.ref }}はGitHub Actionsで利用できる変数になっていて、githubのPRのベースブランチのリファレンスを取得することができます。
GitHub Actionsには、GitHub側で設定されている変数が複数あり、こちらから確認できます。

ステップ2: PRを作成したブランチの最新コミットにチェックアウト

このステップでは、PRを作成したブランチの最新コミットにチェックアウトしています。

      - name: Check out PR open branch latest commit
        uses: actions/checkout@v3

ステップ3: golangci-lintの実行とPRへのコメントを行う

このステップではgolangci-lintを実行し、PRへのコメントを行います。
reviewdogを利用し、--new-from-revgolangci_lint_flagsに設定することで新たなissueのみを通知するようにしています。

      - name: Run golangci-lint
        uses: reviewdog/action-golangci-lint@v2
        with:
          go_version_file: "./go.mod"
          golangci_lint_flags: "--config=.golangci.yml --new-from-rev=origin/${{ github.event.pull_request.base.ref }}"
          level: info
          filter_mode: nofilter
          fail_on_error: true
          reporter: github-pr-review

最後に

TalentXでは一緒に働く仲間を募集しております。

カジュアル面談も行っていますので気になる方はぜひご応募いただければ幸いです!

i-myrefer.jp