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-rev
をgolangci_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では一緒に働く仲間を募集しております。
カジュアル面談も行っていますので気になる方はぜひご応募いただければ幸いです!