2022年8月31日水曜日

nektos/act で GitHub Actions のワークフローをローカル実行

GitHub Actions で困る、というか面倒なのがワークフローのデバッグをするために都度 push してトライアンドエラーなところじゃないでしょうか?
単純に直列に step 並べるだけならそんなに困らないですが、steps.*.if 使ったり output 使って後続 step で利用しているような場合など、ちょっとしたミスで動かなかったりするのでできれば push するまえに確認できると嬉しいですよね。

あとはイベントによっては PR のときに確認できないことがあるので、マージしてからミスに気づくこともあります。
Release してみたらワークフロー失敗したってのは私も何回もやってます。そういう系は workflow_dispatch に対応しておくのがオススメ。

また、CI と同じことをローカルで実行したいということはよくあると思います。
CI サービスによってはローカル実行サポートしてることもありますが、GitHub Actions 公式には今の所ないので act を使います。

https://github.com/nektos/act

act pull_request とすると、 pull_request で trigger されるジョブが実行されます。
細かい使い方はドキュメント見ていただくとして、ここでは使ってみてわかった注意点などを書いておこうと思います。

最初に結論

最初にもっとも重要な注意点を書いておこうと思います。

act オススメしません!

補足すると「GitHub Actions と同じことをローカルでやりたい」のであれば act 使わずに Dagger とか Makefile とか shellscript とかなんでもいいので GitHub Actions のワークフローと処理を分離しておくことをおすすめします。
Jenkins のときと同じですね。

というわけでそのような目的がある場合は、この記事を読んでいないで処理の分離を始めましょう。

そうではなく、GitHub Actions のワークフローの方をローカルで検証したいときは act を使ってみるのはアリかもしれません。
記事の最後で私なりの利用ケースを考えてみたので興味のある方は最後までお付き合いいただけると幸いです。

ポイント
act の runner は hosted runner と同一ではない

act の runner は hosted runner よりも最小の環境で作られています。
なので hosted runner にはあるけど act の runner にはないものがあったりします。

より hosted runner に近いイメージも用意されていますが、とても大きいイメージなので注意してね、とのことです。
https://github.com/nektos/act#runners

↑にも書かれていますが、 -P ubuntu-18.04=nektos/act-environments-ubuntu:18.04 のように runs-on 指定の名前を置換してあげることができます。
このオプションを利用すると self-hosted runner 使っている場合の対応が簡単です。

act のときは〜をする・〜をしない

https://github.com/nektos/act#skipping-steps

やはりどうしても環境が異なっていたり、act でできないこともあり、act でそのまんまワークフローを実行するのは無理だったりします。
なので、そういう場合は if: ${{ !env.ACT }} のように ACT 環境変数で分岐させると良いです。

コンテキストの内容がすべて定義されない

act pull_request としても github context にはほとんどの情報が設定されません。
特に event は空っぽなので、 github.event.pull_request.head.sha とかを workflow 中に参照していると失敗します。
イベント情報などある状態で act 実行したい場合は、以下に書かれてるようにイベントの json ファイルをオプションで指定してください。

https://github.com/nektos/act#events

GITHUB_TOKEN は自動発行されない

https://github.com/nektos/act#github_token

はい。当たり前ですが自動では発行されないです。必要な場合は -s オプション使ってシークレットをセットしてください。

サービスコンテナは未対応

services の内容は無視されます。

設定ファイル

act で実行するにはそれなりにオプションで動くようにカスタマイズが必要だと思います。
お試し程度なら良いかもしれませんが、開発ワークフローで act を常用するようであれば、それらの設定をファイル(.actrc)に書き出しておくと良いと思います。
こうしておけば誰でも実行できるようになるはず。

https://github.com/nektos/act#configuration

ドキュメントに書かれてないこと
本家とは微妙に挙動が異なることがある

これはほんの一例ですが、公式ツールではないのでどうしても本家と違う挙動をすることがあります。
※下記の例は旧バージョンの話なのですでに修正されてます。

setup-ruby が ImageOS が想定外のために失敗する

act の提供してる image の ImageOS 環境変数が small ってなってて ruby/setup-ruby が失敗しました。どうやら setup-ruby は ImageOS 環境変数で実行環境を判断してるっぽいです。
step.*.env で ImageOS 環境変数を与えて上げること回避することはできますが、act 向けの変数になってしまうので微妙ではあります。

こんなときに便利かも
シークレットを設定する権限をもっていないとき

そういうケースってあんまりない気もしますが、なくもないのかなと思います。
シークレットが必要なワークフローの PR をしたけど、そのリポジトリのシークレットを設定する権限がない。 fork したとか、リーダーにしか権限ないとか?

シークレット追加してもらって検証というのもしづらいかなと思いますので、act -s で想定シークレットを渡してデバッグしておくといいかもしれません。

レアなイベントをトリガーにしている場合

pull_request イベントなら PR 出せば済む話ですが、workflow_dispatch とか release とか branch_protection_rule とかのイベントトリガーのワークフローをデバッグするのってめんどくさいです。
というのもイベントによってはデフォルトブランチにワークフローがあることが条件のものがあるからです。
ワークフローをトリガーするイベント - GitHub Docs

こういうやつ。

ですが、act 使えばこれらのイベントでトリガーされたときのデバッグが簡単になると思います。(env.ACT をみて dryrun な状態にしておくこと!)
最後に

act どうなんでしょうね?
本当に必要なケースってあんまりないような気もしてしまいます。

GitHub Actions のワークフローで書くことって大概が pull_request イベントだと思うし、それなら実際に動かしたらいいってなるし。

時間かかるからローカルがいい、処理をデバッグしたいって話だとワークフローとは別の話な気がするので act でなくても解決できるはず。

デフォルトブランチに入れなきゃ動作確認できないイベントはたしかに act があると便利そうではありますが・・果たして本当に楽になるのだろうか?


「デフォルトブランチに入れなきゃ確認できない」って部分は GitHub 公式でなんらか解決策を出してくれると嬉しいですね。

以上。

0 件のコメント:

コメントを投稿