以前の記事で、Violationsツールを使い、Javaプロジェクトの静的解析結果をGitLabのマージリクエストに連携した。
最近、Next.jsによる開発を行っており、エディタとして使用しているVSCode上ではリアルタイムでESLintによる解析をしているため、エラーがpushされることはほとんどない(あっても next build
でエラーになる)が、警告は見過ごされることがある。
ViolationsがESLintに対応しているのは以前の記事の段階で確認しており、今回のプロジェクトでも、静的解析結果をGitLabのMRに連携してみたのでメモ。
環境
Violation Comments To GitLab Command Line v1.30.2。
Gitサーバーとしては、GitLab.comを使用。
Node.jsのパッケージマネージャーにはYarn v1.22.15を使用。
ツール概要
以前の記事を参照。
今回はGitLabのマージリクエスト(MR)連携を行うが、GitHubやBitbucketのプルリクエスト(PR)連携も可能。
これらのコマンドラインツールは、いずれも npx
で実行可能。ただし、内部で利用されるViolations LibがJavaライブラリのため、Java実行環境が必要。ないと Error: spawn java ENOENT
といったエラーが発生する。
使用例
今回は、GitLab CI/CDによるパイプライン実行にて、ESLintの解析およびMR連携を行う。GitLabのCIランナーや、ESLintの設定等は省略。
GitLab設定
以前の記事と同様に、コメント用のユーザーを作成し、ユーザー設定 > アクセストークンから、apiスコープのパーソナルアクセストークンを作成。
GitLab CI/CD Variablesとして、作成したユーザーのアクセストークンを保存する。名前も前回と同様、 VIOLATION_API_TOKEN
とした。
ESLint実行コマンドの作成
src/
配下のJavaScriptまたはTypeScriptを対象として、解析結果をCheckstyle形式で lint/eslint.xml
に出力する。ディレクトリが存在しなくても、ファイルごと作成してくれた。
yarn eslint --ext .js,.jsx,.ts,.tsx -o lint/eslint.xml -f checkstyle src/
GitLab MR連携コマンドの作成
Javaインストール済みの環境で、 npx violation-comments-to-gitlab-command-line
にて実行可能。指定可能な引数はGitHubのREADME参照。
以前の記事で、Gradleにて設定したものと基本は同じ。
severity
や comment-only-changed-content
、 single-file-comments
系の設定など、省略可能なものは省略。デフォルトで、差分のあるファイルにのみ、ディスカッション形式でコメントされるようになっていた。
コメントのテンプレートは文字列で指定する必要あり。複雑なテンプレートであれば、ファイルに記述して $(cat commentTemplate.txt)
あたりで読み込んだほうがスッキリしそう。
npx violation-comments-to-gitlab-command-line \ -gitlab-url "<GitLab URL>" \ -project-id "<GitLab Project ID>" \ -mr-iid "<Merge Request IID>" \ -api-token "<API Token>" \ -comment-template "**重大度**: {{violation.severity}}, **解析ツール**: {{violation.reporter}}{{#violation.rule}}, **ルール**: {{violation.rule}}{{/violation.rule}}\n\n**対象**: {{changedFile.filename}} \\# {{violation.startLine}}行目{{#violation.endLine}}~{{violation.endLine}}行目{{/violation.endLine}}\n\n**内容**: {{violation.message}}" \ --violations "CHECKSTYLE" "lint" ".*/eslint.xml$" "ESLint"
ファイルパスの指定が上手くいかないことが多かったが、第2引数で指定したディレクトリ配下のファイルを再帰し、そのファイルパスが第3引数の正規表現パターン(java.util.regex.Pattern
を使用)にマッチすれば処理対象として抽出している模様。第3引数の先頭には .*/
を指定しないと、まずマッチしない。
.gitlab-ci.yml設定
CI実行時のDockerイメージとして node:<version>-alpine
を利用している。
Node.jsやYarnはインストール済みだが、Javaは未インストールされていないので、 before_script
でインストールした。
コマンドで指定したGitLabのURL、プロジェクトID、MR IIDは、すべて対応する変数が存在するため、置き換えている。
また、 yarn eslint
を実行した際に、解析結果にエラーが含まれると、exit codeが1となり、ジョブが中断してしまうため、 yarn eslint ... || true
で、エラーが含まれる場合もexit codeを0にしている。
default: image: node:16.15-alpine stages: - violation violation: stage: violation allow_failure: true before_script: - apk update - apk --no-cache add openjdk17 - yarn install script: - yarn eslint --ext .js,.jsx,.ts,.tsx -o lint/eslint.xml -f checkstyle src/ || true - |- npx violation-comments-to-gitlab-command-line \ -gitlab-url "${CI_SERVER_URL}" \ -project-id "${CI_PROJECT_ID}" \ -mr-iid "${CI_MERGE_REQUEST_IID}" \ -api-token "${VIOLATION_API_TOKEN}" \ -comment-template "**重大度**: {{violation.severity}}, **解析ツール**: {{violation.reporter}}{{#violation.rule}}, **ルール**: {{violation.rule}}{{/violation.rule}}\n\n**対象**: {{changedFile.filename}} \\# {{violation.startLine}}行目{{#violation.endLine}}~{{violation.endLine}}行目{{/violation.endLine}}\n\n**内容**: {{violation.message}}" \ --violations "CHECKSTYLE" "lint" ".*/eslint.xml$" "ESLint" rules: # マージリクエストの場合のみ実行 - if: $CI_PIPELINE_SOURCE == 'merge_request_event' tags: - violation
実行結果
以下のようなコメントが、解析結果に対応する変更行にコメントされるようになった。
振り返り
「なぜかわからないが出ている警告」みたいなものが、今回の作業でレビューしやすくなった。
早く修正したほうが、コストが少なく済むので、こうした警告を見落としにくくなったのはありがたい。
余談
久しぶりにGitLabのCI/CD設定を触ったら、デフォルトで Protect variable
が有効になっていたのに気づかず。