actionlint を Vim + ALE で利用する Custom Linter を作ってみた


GitHub Actions の手動実行で入力された値を安全に使いたい」を書いているとき、actionlint という GitHub Actions(ワークフローファイル)用のリンターを知りました。

これまでは GitHub へ push したあとに「エラーになってしまった」と頭をかかえていたので、大変に魅力的なツールです。そこで Vim + ALE で利用するための Custom Linter を作ってみました。

何ができるようになるのか

Vim で GitHub Actions のワークフローファイルを編集しているとき、エラー箇所が表示されます。

図 1-1 サンプル
Vim で表示されているエラーを編集している動画

インストール

以下のような感じでインストールできます。

actionlint

actionlint の実行ファイルが必要なので何らかの方法でインストールしておきます。

Arch Linux だと AUR にパッケージが登録されていました。

私は VSCode の Remote Container 用のコンテナ内で使いたかったので Dockerfile で以下のようにしています。

Dockerfile
RUN set -ex; \
    \
    snip..
    # Setup actionlint for user.
    curl -s https://api.github.com/repos/rhysd/actionlint/releases/latest | jq .assets[].browser_download_url | grep linux_amd64 | xargs -I '{}' curl -sL '{}' | tar -zxf - -C "/home/${USERNAME}/.local/bin" actionlint; \

ale-linter-actionlint.vim

Vundle などで hankei6km/ale-linter-actionlint.vim をインストールします。

Plugin 'hankei6km/ale-linter-actionlint.vim'

どのように表示しているのか

ALE対応ツールactionlint が含まれていなかったので Custom Linter を作りました。

Custom Linter は以下を参考に作成できます。

また、標準で搭載されているリンターのソースも参考になります。

少し悩んだ点としては、GitHub Actions のワークフローファイルに処理を限定する箇所です。

これは、 circleci.vim を参考に「ファイルの PATH に .github/workflows が含まれているか」確認することで対応しています。ただし、PATH の区切り文字で手を抜いているのでおそらく Windows では動作しないです[1]

(クリックでスクリプト表示)
ale_linters/yaml/actionlint.vim
function! ale_linters#yaml#actionlint#Handle(buffer, lines) abort
    let l:output = []

    for l:err in ale#util#FuzzyJSONDecode(a:lines, [])
        call add(l:output, {
        \   'text': l:err['message'],
        \   'type': 'E',
        \   'code': l:err['kind'],
        \   'lnum': l:err['line'],
        \   'col' : l:err['column']
        \})
    endfor

    return l:output"
endfunction

call ale#linter#Define('yaml', {
\   'name': 'actionlint',
\   'executable': {b -> expand('#' . b . ':p:h') =~? '\.github/workflows$' ? 'actionlint' : ''},
\   'command': 'actionlint -format "{{json .}}" - < %s',
\   'callback': 'ale_linters#yaml#actionlint#Handle',
\   'output_stream': 'stdout',
\   'lint_file': 1,
\})

付録

Vim + ALE の他にどのような環境でサポートされているかざっと調べてみました。

おわりに

actionlintVim + ALE で利用できるようにしてみました。

久しぶりに Vim Script を使ったのでちょっと苦労しましたが、ワークフローのエラーをローカルで発見できるようになったので、それだけの価値はあったと言えそうです。

脚注
  1. Windows 上では開発用の環境をあまり整えていないのでくじけてしまいました。 ↩︎