【Github Actions】actを使ってローカルでワークフローを実行してみるよ!
どもども、若干お久しぶりです(聞いたことない日本語)
皆さん、Github Actions使っていますか?CI/CDパイプラインとして選択されている方も多いと思います。
CI/CDパイプラインを実行するには一度書いたコードをリモートリポジトリにPushして都度ワークフローの動きをチェック、失敗すればコードを修正してまたPushという動作を繰り返すと思います。
過去にAWSが提供するCI/CDパイプラインであるcodebuildをローカルで実行してみたように、github actionsもローカルで実行できたら色々捗るだろうなーと思っていたところactというツールを知ってしまったので使ってみた記事です。
Act
公式リポジトリはこちら!このツールを作成した理由として
Fast Feedback – Rather than having to commit/push every time you want to test out the changes you are making to your
.github/workflows/
files (or for any changes to embedded GitHub actions), you can useact
to run the actions locally. The environment variables and filesystem are all configured to match what GitHub provides.
とまさにな記載がありました!
どのように動作するか、インストール方法など詳細はユーザーガイドをご覧ください。
それでは早速動かしてみましょう。
準備
すでにgit化されているリポジトリとworkflowが作成されているリポジトリであればactをインストールするのみでそのまま利用できます。(AWSなど外部に接続するjobがあれば都度対応が必要です。)
公式が用意しているサンプルリポジトリも利用できますので環境を用意するのが面倒な人はこちらを使うのも手かとおもいます。
今回僕はgoで非常にシンプルなコードとテストを用意してみました。
package main
import (
"log"
"os"
)
func main() {
file, err := os.Create("test.txt") // test.txtというファイルを作成
if err != nil {
log.Fatal(err)
}
defer file.Close()
_, err = file.WriteString("test") // "test"と書き込む
if err != nil {
log.Fatal(err)
}
}
package main
import (
"os"
"testing"
)
func TestFileOutput(t *testing.T) {
main()
// ファイルの内容を確認
content, err := os.ReadFile("test.txt")
if err != nil {
t.Fatalf("ファイルの読み込みに失敗: %v", err)
}
defer os.Remove("test.txt") // テスト終了時にファイルを削除
expected := "test"
if string(content) != expected {
t.Errorf("期待される出力: %s, 実際の出力: %s", expected, string(content))
}
}
用意したワークフローは以下です。
name: Go Test
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: "1.23"
- name: Run tests
run: |
cd demo
go test -v
では、実際にactを利用してワークフローをローカルで実行してみます。
使ってみる
ユーザーガイドに従ってお使いの環境に合わせてactをインストールしておいてください。
actコマンドを実行することでパイプライン全体をローカルで実行することが可能です。例えば、今回僕が作成したワークフローの実行結果の一部はいかのようになります。
[Go Test/test] ⭐ Run Main Run tests
[Go Test/test] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/2] user= workdir=
| === RUN TestFileOutput
| --- PASS: TestFileOutput (0.00s)
| PASS
| ok act-demo 0.003s
[Go Test/test] ✅ Success - Main Run tests
[Go Test/test] ⭐ Run Complete job
[Go Test/test] Cleaning up container for job test
[Go Test/test] ✅ Success - Complete job
[Go Test/test] 🏁 Job succeeded
デコレートされていますが、実行内容としてはGithub Actionsで実行したものと相違ありません。では、コードを変更しテストに失敗する状態にして再度actを使用してみましょう。
package main
import (
"log"
"os"
)
func main() {
file, err := os.Create("test.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
_, err = file.WriteString("fail") // 書き込む文字列を"test"から"fail"に変更
if err != nil {
log.Fatal(err)
}
}
テストが失敗しています!このようにコードの修正によりCIが成功する稼働かをローカルで確認できるのは非常に嬉しいですね!
[Go Test/test] 🐳 docker exec cmd=[bash -e /var/run/act/workflow/2] user= workdir=
| === RUN TestFileOutput
| main_test.go:21: 期待される出力: test, 実際の出力: fail
| --- FAIL: TestFileOutput (0.00s)
| FAIL
| exit status 1
| FAIL act-demo 0.003s
[Go Test/test] ❌ Failure - Main Run tests
[Go Test/test] exitcode '1': failure
[Go Test/test] ⭐ Run Complete job
[Go Test/test] ✅ Success - Complete job
[Go Test/test] 🏁 Job failed
ワークフローを修正した場合などさまざまなケースでニーズがあり、とても便利です。
ちなみに、-l オプションで実行グラフが表示できます。今回は用意したワークフローが一つしかないのであまり意味がないですが、複数のワークフローを複雑に構成しているリポジトリではありがたいのではないでしょうか。
❯ act -l
Stage Job ID Job name Workflow name Workflow file Events
0 test test Go Test act-test.yml push,pull_request
まとめ
今回はactを利用してGithub Actions で実行するワークフローをローカル上で実行してみました!
とても簡単に導入できますし、もう一つの作成理由である
Local Task Runner – I love make. However, I also hate repeating myself. With
act
, you can use the GitHub Actions defined in your.github/workflows/
to replace yourMakefile
!
で記載があるようにタスクランナーとしても利用できますので導入を検討してみてはいかがでしょうか?
最後まで読んでいただきありがとうございました!