みかづきメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ

ローカルで GitHub Actions 開発をやりたい!

GitHub Actions をちまちま作っているのですが、いちいち push などをせずにローカル環境で
開発する方法みたいなのが見つからなかったので書いておきます。
(そもそも GitHub Actions を作っている人があまりいなさそうだけど...)


今回作ったもの

github.com

前提条件として macOS で開発することにしていますが、多分 LinuxWindows でもできます。
まずはローカル環境で実行する為のツールを導入します。

  1. brew tap nektos/tap && brew install nektos/tap/act
  2. ghq get mcolyer/actions-toolkit-action

nektos/actGitHub Actions をローカルで実行するためのコマンドです。
mcolyer/actions-toolkit-action は Webhook イベントデータの fixture です。
後者は自分で用意してもかまいませんが、面倒なので fixture を使います。

GitHub Actions は適当に Dockerfileentrypoint.sh っぽいファイルがあれば動きます。
詳しくは公式ドキュメントを見てね。
このとき、デバッグ用の .github/main.workflow を用意しておきます。

こんな感じ

workflow "New workflow" {
  on = "push"
  resolves = ["print message 'Hello, World'"]
}

action "Run only master branch" {
  uses = "actions/bin/filter@master"
  args = "branch master"
}

action "Check commit sender is repository owner" {
  uses = "./"
  needs = ["Run only master branch"]
  args = "sender.login eq mika-f"
}

action "print message 'Hello, World'" {
  uses = "actions/bin/sh@master"
  needs = ["Check commit sender is repository owner"]
  args = ["echo 'Hello, World'"]
}

uses = "./" が含まれている Action が作成している GitHub Action です。
あとは act コマンドを実行することで、上記 Workflow 通りに GitHub Actions を実行できます。

ただし、on = "push" 以外をトリガーに実行したい場合は、act event_type のようにします。 また、 GitHub のイベントペイロードを参照したい場合は以下のように実行します。

$ act status -e $GHQ_ROOT/github.com/mcolyer/actions-toolkit-action/fixtures/status.json
[Run only master branch] git clone 'https://github.com/actions/bin' # ref=master
[Run only master branch] docker build -t bin:master /var/folders/1f/0cmdc6fs4jnf1ql07yc_p7000000gn/T/act/actions/bin/filter@master/filter
[Run only master branch] docker run image=bin:master entrypoint=[] cmd=["branch" "master"]
refs/heads/master matches refs/heads/master
[Success CI checks] docker build -t action-filter-by-payload:0789a7f /Users/mikazuki/Desktop/repos/github.com/mika-f/action-filter-by-payload
[Success CI checks] docker run image=action-filter-by-payload:0789a7f entrypoint=[] cmd=["state" "eq" "success"]
[print message 'Hello, World'] git clone 'https://github.com/actions/bin' # ref=master
[print message 'Hello, World'] docker build -t bin:master /var/folders/1f/0cmdc6fs4jnf1ql07yc_p7000000gn/T/act/actions/bin/sh@master/sh
[print message 'Hello, World'] docker run image=bin:master entrypoint=[] cmd=["echo 'Hello, World'"]
Running 'echo 'Hello, World''...
Hello, World
Successfully ran 'echo 'Hello, World''

act -e /path/to/fixture.json のように -e を渡すことで仮のデータを渡すことが可能です。
ちなみに、現時点では何も渡さない場合、イベントデータは {} で設定されます。

あとは無事期待通りの動作をしたら GitHub に push して release すれば公開されます。