APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

(あらためて)Bicep LinterをGitHub Actionsで実行する

f:id:turtle2005:20210609141446p:plain

Azure Bicep with GitHub Actions

Azure Bicepにはv0.4.1からLinter機能が搭載されています。 AZ CLIにも組み込まれておりいつでも利用可能です。また、Visual Studio Code Extensionにも含まれているためBicepコードを記述しながらLint結果を確認することができます。

ここまで来ると、Pull Request発行時にもLinterを実行したくなるというものです。 ということで今回実現したいのは次の2点です。

  1. Azure Bicep LinterをGitHub Actionsで実現する
  2. 同時にProblem Matcherでエラー・ワーニング箇所がすぐにわかるようにする

Azure Bicep LinterをGitHub Actionsで実現する

BicepにはLinter専用コマンドやコマンドオプションは用意されていません。Azureにデプロイする際、またはBicepのBuildを実行する(ARM Templateを作成する)際に実行されます。ということで、GitHub ActionsでのLint実行はbicep buildを利用することにしました。 ここで問題が1つ。BicepのLint結果は通常Warningレベルで出力されます。コマンド実行結果もコード0(正常)となります。これだとGitHub Actionsは正常終了と認識してしまい、通知を行ってくれません。当初この問題を linter-rulesをbicepconfig.jsonで変更することで解消しようとしました。しかし、以下のワーニングはどうやらbicepconfig.jsonで出力レベルを変更することができませんでした。

BCP036: The property "omsagent" expected a value of type "ManagedClusterAddonProfile" but the provided value is of type "null | object".

ここからが戦いの始まりでした。

上記のBCP036ワーニングのような場合もlinter-rulesのワーニング同様のメッセージフォーマットで出力されるようです。であれば、grepでWarningを検索し、あればエラーexit 1、なければexit 0で終了してやればいいのではないか。

仕組みは簡単です。GitHub Actionsのワークフロー上でスクリプトを直接書いてやればよい。よいはずでしたが、そう簡単にはいかない。実はGitHub Actionsのワークフロー上でコマンドを実行した場合、exit 0以外のコマンド実行を検知するとその時点で止まってしまいます。さて、ここで問題になるのがgrepです。ご存じの通り、grepは検索対象が見つかった場合は0を、見つからなかった場合はそれ以外を終了時に返します。そうです、grepの実行でWarningがなかった場合は0以外が返りますので、この時点でワークフローが終了してしまいます。

ということでスクリプトファイルを作成し、lintやgrepはそのスクリプト内で実行し、ワークフローからはこのスクリプトファイルを実行するのみとします。これで問題は解消。

そこで作成したスクリプトファイルは次のようなものです。

#!/bin/bash
exitCode=0
for file in `ls **/*.bicep`; do
  az bicep build --file $file --stdout 2>&1 > /dev/null | grep -iE '^warning|^error'
  if [ $? -eq 0 ]; then
    exitCode=1
  fi
done
exit $exitCode

これでLinterは実行できるようになりました。

Problem Matcherでエラー・ワーニング箇所がすぐにわかるようにする

次は、ワーニングやエラー発生時にPull Requestの画面でエラーの内容がわかりやすくすることにします。

GitHub Actionsには検出したエラーやワーニングを表示する機能があります。以下がそのサンプルです。ここまでlint実行時も表示してくれれば便利ですね。

f:id:turtle2005:20210919105157j:plain
error

でも、さきほど作成したスクリプトを実行した際はここまで表示してくれません。 エラーメッセージの形式がGitHub Actionsが用意しているものとは異なるためです。

この形式を指定するのがProblem Matchersです。(詳細は本家のドキュメントをご覧ください)

指定した内容は Warning用

{
    "problemMatcher": [
        {
            "owner": "bicep-linter-warning",
            "severity": "warning",
            "pattern": [
                {
                    "regexp": "(^[Ww].+) (/.+\\.bicep)\\((\\d+),(\\d+)\\)\\s:\\s(.*)$",
                    "file": 2,
                    "line": 3,
                    "column": 4,
                    "message": 5
                }
            ]
        }
    ]
}

Error用

{
    "problemMatcher": [
        {
            "owner": "bicep-linter-error",
            "severity": "error",
            "pattern": [
                {
                    "regexp": "(^[Ee].+) (/.+\\.bicep)\\((\\d+),(\\d+)\\)\\s:\\s(.*)$",
                    "file": 2,
                    "line": 3,
                    "column": 4,
                    "message": 5
                }
            ]
        }
    ]
}

の2つです。 regexp の部分をメッセージフォーマットに合致するよう正規表現で記載します。そのあとのfileline,columnmessageでGitHub Actionsがメッセージの内容を理解できるようにします。

これをGitHub Actionsのワークフローで

    - name: Add problem matcher
      run: |
        echo "::add-matcher::.github/matcher/bicep-linter-warning.json"
        echo "::add-matcher::.github/matcher/bicep-linter-error.json"

と指定すればOK.

以下が実際のワークフローのyamlです。

name: Check on pull-request
on:
  pull_request:
  push:
    branches:
    - main

jobs:
  lint:
    name: Lint check
    runs-on: ubuntu-latest
    steps:
    - name: Chckout pull request
      uses: actions/checkout@v2
    - name: Setup Bicep
      uses: anthony-c-martin/setup-bicep@v0.1
      with:
        version: v0.4.613
    - name: Add problem matcher
      run: |
        echo "::add-matcher::.github/matcher/bicep-linter-warning.json"
        echo "::add-matcher::.github/matcher/bicep-linter-error.json"
    - name: Run Bicep build
      shell: bash
      run: |
        bash .github/commands/lint.bash

これで以下のようにワーニングやエラーの内容を画面上に表示できます。

f:id:turtle2005:20210919105241j:plain
warning

f:id:turtle2005:20210919105157j:plain
error

これでBicep LinterをGitHub Actionsでも実行可能になりました。最低限のチェックはPull Requestで行ってくれるので安心ですね。