GitHub ActionsのProblem MatchersでShellCheckの指摘を表示する
ShellCheckは、シェルスクリプト用のLintツールで、文法上の問題や想定外な実行結果が起こらないようにチェックするツールである。
シェルスクリプトは雰囲気で書いているので、Linterがあるのは嬉しい。
この記事では、ShellCheckの実行方法や、GitHub ActionsのProblem MatchersでShellCheckの指摘を表示する方法を説明する。
ShellCheck をインストールする
Macであればhomebrewを使ってインストールできる。
$ brew install shellcheck
ShellCheck を実行する
ShellCheckは次のコマンドで実行できる。
$ shellcheck *.sh
例えば次のような、定義されていない変数を使っているようなスクリプトに対してチェックをしたとする。
#!/bin/bash
echo "$foo"
ShellCheckを実行すると、構文エラーとなる項目が表示される。
$ shellcheck -f gcc *.sh
test.sh:3:7: warning: foo is referenced but not assigned. [SC2154]
GitHub Actions で ShellCheck を実行する
GitHub Actionsでは、ランナーがLinuxの場合のみ、ShellCheckがプリインストールされている。
そのため、他のLintツールのように事前にインストールする必要がない。
Ref. https://github.com/koalaman/shellcheck#in-your-build-or-test-suites
ShellCheckをGitHub Actionsで動かすためのアクションはいくつか公開されているが、開発元が公開したActionsはなかった。
今回は、Problem Matchersを使って、指摘内容をGitHub Actionsのアノテーションに表示させる。
ちなみに、ludeeus/action-shellcheckというアクションでは、Problem Matchersを使ってアノテーション表示できるようだった。
エラー結果をキャプチャするルールファイルを追加する
Problem Matchersとは、GitHub Actionの出力結果を正規表現のパターンとして解析し、アノテーションを表示する機能である。
出力結果のパターンをどのようにキャプチャするかのルールは、jsonファイルで定義する。
あとでGitHub Actionsのワークフロー側で指定するため、ファイル名や位置は何でも良い。
ただ、GitHub.comの機能なので、.github
以下に置くと行儀が良さそう。
owner
にProblem Matchersの固有のIDを割り振り、pattern
以下に正規表現のパターンを定義する。
今回のShellCheckerはgcc形式で出力するので、regexp
はgcc形式に合わせた正規表現とした。
また、キャプチャしたグループの順番を、file
(ファイル名)やline
(行番号)といったプロパティに指定する。
{
"problemMatcher": [
{
"owner": "shellcheck-matcher",
"pattern": [
{
"regexp": "^(.+):(\\d+):(\\d+):\\s(note|warning|error):\\s(.*)\\s\\[(SC\\d+)\\]$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5,
"code": 6
}
]
}
]
}
GitHub Actions のワークフローを追加する
ShellCheckerを実行するGitHub Actionsのワークフローを追加する。
Problem Matchersを使って実行結果をキャプチャするには、ツールの実行前にecho "::add-matcher::ルールファイルのパス"
を実行すれば良い。
name: shellcheck
on:
pull_request:
paths:
- "*.sh"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Enable Problem Matchers
run: echo "::add-matcher::.github/shellcheck-matcher.json"
- name: Exec shellcheck
run: |
shellcheck -f gcc *.sh
echo "::remove-matcher owner=shellcheck-matcher::"
先ほどの、定義していない変数を使ったシェルスクリプトに対し、このワークフローを実行すると、アノテーションにエラー内容が表示された。