はじめに
レビュワーの工数削減とヒューマンエラーを防ぎコードの品質をさらに向上させていく取り組みの一環として、自動コードレビュー(静的解析) を検討しました。
そこで、reviewdog
というツールを用いて実装しようとしたのですが、
reviewdogはgithub-actions
ベースで開発がされているため、gitlabでの使用に関しては、ほとんど事例・記事はありませんでした。
導入まで少しだけ苦労したので、この記事がgitlab上でreviewdogの使用を想定している人に向けて参考になれば幸いです。
reviewdogとは?
Go言語で記述されたOSS。
各種 linter 解析の検出結果を MR(またはPull Request) にコメントする形で指摘してくれるツール
以下のreviewdog開発者の記事を読むと概要が掴めると思います。
Reviewdog を飼ってコードレビューや開発を改善しませんか
導入までの全体感
- reivewdog開発用ブランチ(
feature/reviewdog
)を作成 -
feature/reviewdog
→develop
ブランチへのMRを作成する -
.gitlab-ci.yml
にreviewdog導入のスクリプトを書く - 変更をpushしてGitlab CI(パイプライン)を走らせ、Gitlab CIコンソールベースで確認しデバッグを行う
- 3,4を、エラーがなくなりreviewdogが正常に機能するまで繰り返す
-
develop
ブランチにマージする
▼ 準備(テスト用リポジトリを使用する場合)
reviewdog導入テスト用のリポジトリを使用する場合はこちらから開始。
※通常は、既存リポジトリに対してreviewdog用のブランチを切って作業する方法で良い
-
テスト用新規リポジトリ作成(例:
reviewdog-test
など) -
.gitlab-ci.yml
の修正 -
試しにpushするとパイプラインが実行されない。どうやらgitlab runnerが登録されていないよう
this job is stuck because you don't have any active runners that can run this job.
-
gitlab runnerの登録
【gitlab runnerとは?】
GitLabのCI/CDパイプラインはリポジトリのルートにある.gitlab-ci.yml
というyamlファイル
によって構成されます。
Runnerは.gitlab-ci.yml
ファイル に記載された処理を実行するアプリケーション# gitlabインスタンスで実行 # 新規リポジトリでのrunnerの登録 $ gitlab-runner register ~ ~ => Runner registered successfully. Feel free to start it, but if its running already the config should be automatically reloaded! # gitlab-runnerの起動 $ gitlab-runner run
任意のタグでgitlab runnerが登録されていることを確認
パイプラインを走らすと無事実行された!
▼ reviewdog導入
gitlabにreviewdogユーザーの作成
MRにコメントを追加するAPIトークンを取得するため、管理者メニューからユーザー追加でreviewdog用のユーザーを作成
reviewdogユーザーでgitlabにログインしAPIアクセストークンの取得を選択
適切な権限をつけてAPIアクセストークンを発行
※注意点
プロジェクト単位でアクセストークンを発行することもできますが、その場合アイコンを設定できないためレビューがややたんぱくになってしまう
gitlab-runnerにタグを追加
パイプラインを実行するときのstageを既存の処理と分けたいので、新しいタグ(reviewdog
)を追加する
開発用ブランチ作成
ブランチ戦略はGit Flow
を採用
develop
ブランチからfeature/reviewdog
ブランチを作成。
以降の作業はfeature/reviewdog
ブランチで行うこと。
.gitlab-ci.yml
に追記
reviewdogの導入は基本的には.gitlab-ci.yml
上で行う
.gitlab-ci.yml
にjobを作成し、job内でreviewdogのコマンドを叩くことで実行される
ここでは、例として、以下3つのlinterの設定を行う
-
textlint
- README.mdの校正
-
ESlint
- フロントエンド(Vue.js)用のlinter
-
rubocop
- バックエンド(ruby)用のlinter
共通部分に追記
-
variables
に先ほど取得したreviesdogユーザーのAPIトークンキーを追加する -
ESlint用のパス設定用の環境変数を設定
-
stagesに
reviewdog
を追加する(パイプライン実行時にstageをtest
とは分けたかったため).gitlab-ci.ymlvariables: # reviewdogユーザーから発行したAPIトークンを設定.これがないとreviewdogがコメントできない。 REVIEWDOG_GITLAB_API_TOKEN: 発行したアクセスキー # eslintのチェック対象とするdir/fileパスを指定。指定したパスに変更があったときのみreviewdog-eslintを実行する。 ESLINT_TARGET_PATH: app/javascript/packs/ stages: - test - reviewdog
textlint
- textlintインストール
$ npm init -y # package.jsonがすでに存在すればスキップ。だいたいすでに存在しているはず。
$ npm install --save-dev textlint # --save-devをつけることで開発環境だけに適用
$ npx textlint -v
=> v11.6.3
# textlint のルールは、本体とは別に Node パッケージとして提供されているので、ルールごとに次のようにインストール
# 「ら」抜き言葉を検出するルール
$ npm install --save-dev textlint-rule-no-dropping-the-ra
# 「〜である。〜ます。」の混在を検出するルール
$ npm install --save-dev textlint-rule-no-mix-dearu-desumasu
reviewdog-textlint:
stage: reviewdog
variables:
# 「reviewdog: fail to get diff: failed to get merge-base commit: exit status 1」エラーへの対処
GIT_STRATEGY: clone
GIT_DEPTH: 0
tags:
- reviewdog
allow_failure: true # CIに失敗してもMRをマージ可能にする設定
rules:
# ソースブランチがfeature/XXX かつ ターゲットブランチがdevelopブランチのときのみパイプラインに追加
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"'
# ソースブランチがhotfix/XXX かつ ターゲットブランチがmasterブランチのときのみパイプラインに追加
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^hotfix/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
script:
- echo "############ reviewdog-textlint start.....############"
- echo "source_branch:$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
- echo "target_branch:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
# nvmのinstall
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
# nvm: command not foundへの対応
- source ~/.nvm/nvm.sh
# nvm install --lts 版だとエラーになるので、v16を使用。
- nvm install 16.16.0
# installの確認
- node -v
- npm -v
# このリポジトリにあるpackage.jsonに記載された内容を元にnode moduleの読み込み
- npm install
# reviewdogのinstall. bin/ 配下に実行ファイルがインストールされる
- wget -O - -q https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s
# *.md ファイルを対象にtextlintを実行
- npx textlint -f checkstyle ./ | bin/reviewdog -f=checkstyle -name="textlint" -reporter=gitlab-mr-discussion
eslint
reviewdog-eslint:
stage: reviewdog
variables:
# 「reviewdog: fail to get diff: failed to get merge-base commit: exit status 1」エラーへの対処
GIT_STRATEGY: clone
GIT_DEPTH: 0
tags:
- reviewdog
allow_failure: true # CIに失敗してもMRをマージ可能にする設定
rules:
# ソースブランチがfeature/XXX かつ ターゲットブランチがdevelopブランチのときのみパイプラインに追加
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"'
changes:
- $ESLINT_TARGET_PATH
# ソースブランチがhotfix/XXX かつ ターゲットブランチがmasterブランチのときのみパイプラインに追加
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^hotfix/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
changes:
- $ESLINT_TARGET_PATH
script:
- echo "############ reviewdog-eslint start.....############"
- echo "source_branch:$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
- echo "target_branch:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
# nvmのinstall
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
# nvm: command not foundへの対応
- source ~/.nvm/nvm.sh
# nvm install --lts 版だとエラーになるので、v16を使用。
- nvm install 16.16.0
# installの確認
- node -v
- npm -v
# このリポジトリにあるpackage.jsonに記載された内容を元にnode moduleの読み込み
- npm install
# reviewdogのinstall. bin/ 配下に実行ファイルがインストールされます
- wget -O - -q https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s
# -f checkstyle 対象とするdir/fileパス指定
# 例:app/javascript/packs/**/**/*.{ts,js,vue} → ts,js,vueファイル限定
# 例:app/javascript/packs/**/**/*.{ts,js,vue}, app/javascript/packs/**/*.{ts,js} → 複数指定可能。但し、指定した拡張子のファイルがパスに存在していないといけない。
# 例:app/javascript/packs/ → packs配下の全てのファイル
- npx eslint -f checkstyle $ESLINT_TARGET_PATH | bin/reviewdog -f=checkstyle -name="eslint" -reporter=gitlab-mr-discussion
rubocop
rspec:
image: ruby:2.7.2
stage: test
tags:
- testing
- reviewdog
before_script:
- hogehoge
script:
- hogehoge
after_script:
# reviewdog ✖︎ rubocopとの連携を実行
- echo "############ reviewdog-rubocop start.....############"
- wget -O - -q https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s
- bundle exec rubocop | bin/reviewdog -f=rubocop -reporter=gitlab-mr-discussion
artifacts:
paths:
- coverage/
expire_in: 10 days
▼ 動作確認
MergeRequestを作成し、literが警告を出した箇所を確認すると、reviewdogがコメントをしてくれます。
ここまで確認できたら成功です。
アイコンが愛くるしいですね🐶
▼ChatGPTの活用
余談ですが、ChatGPTを使用するとある程度のヒントをくれます。
細かい修正はご自身の環境でデバッグしながら行う必要があります。
以下に、質問の例を示しておきます。プロンプトエンジニアリングの観点から、「段階的かつ論理的に」という言葉を入れると良いです。
あなたは優秀なソフトウェアエンジニアです。
gitlab上にreviewdogを用いて静的解析を行いたいです。
.gitlab-ci.ymlにreviewdog導入のスクリプトを記述してたいです。
例を示して、段階的かつ論理的に教えてください。
▼参考記事
reviewdog / linter
-
reviewdoc
README -
textlint
gitlab ci
-
gitlab ci
https://qiita.com/yurano/items/a7804d987ccff37b1a9d
https://qiita.com/ynott/items/1ff698868ef85e50f5a1
https://qiita.com/kytiken/items/a95ef8c1fccfc4a9b089 -
.gitlab-ci.yml
https://www.sobyte.net/post/2022-09/reviewdog-gitlab/
https://dev.classmethod.jp/articles/sample-to-understand-rules/ -
gitlab runer
https://blogs.networld.co.jp/entry/2022/03/10/090000