swift-formatを実行するGitHub Actionを作った
GitHub ActionsでSwiftもlintしよう
みなさん、Swiftを書くときにどんなlinterを使っているでしょうか。
Swift対応のlinterというとApple謹製のapple/swift-formatとかrealm/SwiftLintが有名ですかね。私は前者のswift-formatの方を使っています。
GitHubリポジトリのmain/masterブランチへPUSHしたときや、Pull Requestが作られたときに自動でswift-formatを実行してくれるGitHub Actionを作ったので良かったら使ってみてください。
GitHub Actionでswift-format使うとどんな感じ?
例えばPull Requestにmtgto/swift-format-actionを利用した場合、swift-formatのlint結果がPull RequestのFiles changedに結果が反映されます。
github.com/mtgto/swift-format-actionのPR1 が結果のサンプルになってます。
使い方
使い方はGitHubのリポジトリに .github/actions/swift-format.yml
のようなファイルを作ればOKです。
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
# ソースコードを取得
- name: Checkout Code
uses: actions/checkout@v2
with:
# Pull Requestの差分ファイル取得のためにgit履歴も取得してください
fetch-depth: 2
- name: Lint
uses: mtgto/swift-format-action@main
with:
# configurationファイルがあればgitリポジトリ内でのパスを記述する
configuration_file: .swift-format
# falseにするとpushの場合はそのコミット、pull requestの場合はそのpull requestの変更ファイルだけをlint対象とする
# trueにするとすべてのファイルをlint対象とする
all_files: false
# いくつまでwarningを許容するか。-1なら制限なし。0ならwarningが一個でもあればlintエラーにする
max_warnings: -1
まだ自分しか使ってないと思うので要望とか質問とかあればコメント欄やTwitterで聞いて下さい。
GitHub ActionsでDockerを使うか使わないか
swift-formatはSwiftで書かれているCLIのプログラムです。これをGitHub Actionsで動かすにはmacOS環境でNode.jsから動かすかDockerコンテナをLinux環境で動かすかどっちかを選ぶ必要があります。
今回はDockerアクション形式を選択しました。Super-Linterというたくさんのプログラミング言語に対応したGitHub Actionがあるんですが、このActionはAlpine LinuxにたくさんのLinterツールをインストールしたDockerイメージを作ってそれを使ったDockerイメージ形式のGitHub Actionになっており、それに対応することを考えてDocker形式を選びました。
なんでswift-formatをSuper-Linterに対応させなかったかというと、Alpine Linux上でswift-formatを動かすのが2021年1月現在非常に難しいというのが理由です。
Appleがswift-formatが使っているlib_InternalSwiftSyntaxParserの静的リンク用ライブラリのLinuxバイナリを提供してくれたらもしかしたらSuper-Linterへの対応ができるかもしれないと思ってチケットだけは切ってあります。 https://bugs.swift.org/browse/SR-14001
他にDocker形式のアクションを選んだ理由としてはAppleがswift-formatをバイナリで配ってないのでどっかの知らない誰かが作ったバイナリを動かすよりはDocker HubのAutomated Buildのほうが信用できるかなと思ったからなのですが、Dockerアクションは作るのにかなり癖があるのでmacOSで動かしたほうが良かったんだろうなと作ったあとでは思っています。そのうちmacOSネイティブに切り替えるかもです。
(swift-formatはApache License 2.0なのでライセンスファイルを同梱すれば再配布できる)
感想:シェルスクリプトってめんどくさい
Dockerベースイメージとして利用した swift:5.3-slim
にはPythonもRubyもnodeも入ってないので(Perlは入ってたけど私が書けない)、久しぶりにシェルスクリプトを持ち出してGitHub Actionのメインを書いたんですが、めちゃくちゃめんどくさかったです。
ファイルの差分を git diff --name-only
で取り出して、それを swift-format lint
のあとにくっつけて、みたいな作業をするわけですがシェルの配列の扱いとかもう全く覚えてないしなんかうまくいかなくなって結局xargsを使ったりしました。
シェルスクリプトを書くときもユニットテストもあったほうがいいんだろうなあと思いつつ結局めんどくさくて用意できなかったので、Dockerコンテナ形式を使うときにはSwift/Goのように別環境で単体バイナリにコンパイルしてそれを使うほうがよかったのかなあというのがGitHub Actionを初めて書いてみた感想です。
Discussion