世界を動かす技術を、日本語で。

GitHub Actionsをローカルで実行する

概要

  • GitHub Actions をローカルで実行できるツール act の紹介
  • 迅速なフィードバックと Makefile 代替としての利用が可能
  • VS Code拡張機能 でエディタ内から直接操作可能
  • Dockerを活用して GitHub本番環境 に近い実行環境を再現
  • 導入・貢献方法やサポートチャネルも案内

GitHub Actionsをローカルで動かす:actの活用提案

  • act は、GitHub Actionsを ローカル環境 で実行するためのツール 提案

  • 主な目的は 2つ ・迅速なフィードバックを得ること ・Makefileの代替として ローカルタスクランナー 化すること 提案

ローカル実行のメリット

  • .github/workflows/の変更を 即時テスト できるため、毎回commit/pushする必要がない 確認

  • 環境変数ファイルシステム がGitHub本番環境と一致するよう自動設定 確認

  • Makefileの繰り返し記述を省略し、 ワークフロー定義 をそのままタスクランナーとして利用可能 提案

VS Code拡張機能による運用

  • GitHub Local Actions というVS Code拡張機能を使うことで、actをエディタ内から直接操作可能 確認

  • ワークフローの ローカル実行・テスト をエディタから離れずに完結できる 効率化

actの動作仕組み

  • actは.github/workflows/内のGitHub Actions定義を読み取り、 実行すべきアクション を決定する 流れ把握

  • Docker APIを利用し、 必要なイメージ をpullまたはbuildすること 実行手順

  • ワークフロー内で定義された 依存関係 に基づき、実行経路(execution path)を決定すること 実行手順

  • Docker APIを用い、各アクションに対して コンテナ を起動し、準備したイメージで実行すること 実行手順

  • 環境変数ファイルシステム はGitHub本番と同様に自動構成 再現性確保

サンプルとドキュメント

  • Sample Repository で実際の動作例を確認可能 体験

  • 詳細な利用方法は act User Guide でドキュメント化 参照

サポートと貢献

  • Gitter で質問・サポートを受け付け 相談

  • 貢献希望者は contributing guidelines を参照し、開発参加すること 参加

ソースからの手動ビルド手順

  • Goツールチェーン(1.20+) をインストールすること 準備

  • リポジトリを git clone で取得すること 準備

  • make testユニットテスト を実行すること 確認

  • make installビルド・インストール を行うこと 導入


関連リンク

Hackerたちの意見

今週、Rubyテストの変なCIエラーをデバッグするために、もう一度これに挑戦してみたんだけど、MシリーズのMacを使ってるからプラットフォームの不一致があってさ。それに、アクションランナーとしてデポ画像を使ってるから、ドライランの段階を超えて動かすことができなかった。CIランナーとローカルのDockerイメージの間には、ほんとにたくさんの違いがあるんだよね。catthehackerのイメージも試してみたけど、15GB以上あって、それでも動かなかった。結局、諦めちゃった。

それよりもひどいのは、圧縮されて20GB、展開すると60GBになること。とはいえ、VMのディスクスペースが足りなくなると、意味のあるエラーは出ない(まあ、12ヶ月前はそうだった)し、起動に失敗するだけなんだよね。(多分colima特有かもしれないけど、Dockerはアンインストールしたからわからない)ローカルではうまくいくこともあれば、実際のアクションでは失敗することもあるし、その逆もある。とはいえ、全体的には進展を促進するのが楽になったかな。

こんなのが役立つかもしれないよ。実行中のインスタンスにSSHで入って、正確なコンテキストでデバッグできるからね:https://docs.warpbuild.com/tools/action-debugger

デバッグしようとしたアクションで運が良かったけど、ランタイムの差が大きすぎて100%信頼するのは無理だな。残念だけど、このツールは結構いいと思うんだよね。

ローカルでGHアクションをデバッグしようとした時の経験に似てるな。今までに2回試してみたけど、何GBもあるイメージをダウンロードして、色々インストールして、結局はよくわからない設定や環境の問題で行き詰まっちゃった。ローカルでLinuxも動かしてたから、これが一番うまくいくと思ったんだけど。もう一度試す気にはなれないし、もしすごく遅いCIとか、何か理由で頻繁に更新が必要なGHアクションがない限り、リモートでCIが動くのを待つ方がいい気がする。

GH Actionsは、変なことしなければずっと完璧に動いてる。先週、カスタムサーバーからGH Pages + GH Actionsに戻したら、ビルドフェーズの後に出力ディレクトリが必要な機能が壊れちゃった。どう直せばいいかわからない。多分簡単なんだろうけど、もう疲れちゃった。

ChristopherHXは、ランナーの中からルートファイルシステムをtarballにパッキングして直接作成されたDockerイメージを公開してる。ただ、イメージはめちゃくちゃ大きい。https://github.com/ChristopherHX/runner-image-blobs/pkgs/con...

Apple SiliconでのRubyの経験は全然スムーズじゃなかった。問題を完全に解決する唯一の方法は、最新のRubyリリースを実行して、その影響に対処することだったよ。GHアクションが最新のRubyバージョンを実行してるとは思えないな。

これは本当にアクションのロジックをデバッグするためだけだよね?私のチームでは、NixがCIジョブがやる面白いことのほとんどをカプセル化するのにうまく機能してるみたい。ローカルバージョンを実行するために仮想化は使ってないし、アーキテクチャの不一致の問題にも直面してないよ。

私の経験(そしてこの投稿に寄せられたコメントにも反映されてるけど)、複雑なCIワークフローをローカルで動かそうとするのは、かなり絶望的な試みだと思う。完全にコンテナ化されたワークフローがあれば近づけるかもしれないけど、それでもCI特有の環境変数をすべて揃えるのは簡単じゃないし、ワークフローがタスク間で何かを調整してる場合(例えば、一つのタスクがアーティファクトをアップロードして、別のタスクがそのアーティファクトを使う)には、CIで何が起こっているのかを正確に再現するのは難しいよ。私の会社(RWX)はGitHub Actionsの競合を作っていて、意図的にローカル実行をサポートしてないんだ。代わりに、git pushせずにローカルマシンからリモートビルドを簡単に開始できるようにして、実行中のタスクの前後でSSHセッションを取得して、ワークフローが実行されている正確なビルド環境を確認できるようにしてる。

ローカル開発には.envファイルとmiseを使えるよ。https://mise.jdx.dev/environments/#env-file 俺はdaggerを使ってこれらの.env/mise環境変数を読み込んで、テストコンテナにダミー値を注入してる。プロダクションはシークレットマネージャーで管理してるよ。

警告:actはDockerを使うなら素晴らしいけど、Podmanはサポートしてないよ。Podmanのサポートや互換性、回避策に関する問題や議論は、簡潔なメッセージで閉じられてる。オープンソースプロジェクトとしては珍しいね。

Podmanサポートのための長い間開いている問題があるね。もしかしたら、重複に疲れちゃったのかな? [1] https://github.com/nektos/act/issues/303

最後に見たとき、ActはAWSサービスを模倣しようとする「サーバーレスオフライン」オプションに似てた。もし使い方がシンプルなら動くかもしれないけど、何か「エキゾチック」なことをする場合(私が失敗した実行でデバッグしようとしてることが多い)には、ActはGHAの体験を完全には再現できない。あと、理解できるけどmacOSのサポートはないし、私はiOSビルドのためにGHAでmacOSを使ってるから(これもデバッグしなきゃいけない場所なんだ)。

このツールは、GitHub Actionsが実際に動かしているのと同じコンテナイメージやランタイム環境を使ってないってことは重要だよ。あくまで近似なんだ。シンプルな使い方なら問題ないけど、複雑なGitHub Actionsを使ってると、動作が異なることがあるからね。それは、奇妙なCIの失敗をデバッグしてるときにフラストレーションにつながることがある。

AWS LambdaはDockerイメージを公開してるけど(例: public.ecr.aws/lambda/python:3.12-arm64)、GitHub Actionsにも似たようなものはあるのかな?

そうだね、これはダサい。Gitlabなら、実行するイメージを正確に選べるし、自分のイメージを提供することもできる。だから、ローカルで全く同じ環境で同じコードを簡単に実行できるんだ。GitlabのYAMLをDockerの呪文に変換するツールがあれば便利かもしれないけど、そんなに頻繁に必要なわけじゃないから、問題にはなってないよ。

GitHubは本当にGitHub Actionsでのローカル開発をサポートする必要があるよ。ちょっと、何て後退なんだ。

GitHubは本当にGitHubアクションでのローカル開発をサポートする必要があるよね。賛成だわ。actみたいなツールには感謝してるけど、ローカルでghアクションを実行する公式にサポートされた方法が必要だと思う。

最近のCIの正しい使い方って、ほとんど何もしないことだと思う。CIはスクリプトをトリガーするだけで、そのスクリプトをローカルで実行すればいいんだよね。

彼らは特にそうしないと思うよ、競合製品を作るために使われないように。アクションはGitHubにお金をもたらす要素の一つだからね。

actの代わりにおすすめの代替品はある?長い間使ってきたけど、去年はactでたくさんの問題にぶつかって、他にもっといい代替品があるのか気になってる。

GitHub Actionsの話が出るたびに、最適な代替品を探し始めるチャンスだね、行こう!Daggerはもう使えるの?Earthlyにはまだ希望がある?一般的なワークフローシステムはすぐに勝てるのかな、それともまだコードを書くのが怖い?GitHub Actionsとは違って、ローカルで動かす基本的な機能を全てカバーしている新しいシステムはある?

nixの上に、earthlyと同じくらい使いやすくてパワフルなものを作れると思うけど、nixの良いところ、再現性やキャッシュ、どのnixパッケージのコマンドでも使えるとか、そういうのを全部取り入れられるんじゃないかな。

earthlyは設定ベースだから、俺の中ではGHAと同じレベルだね。https://docs.earthly.dev/docs/earthly-config daggerだけがコードベースのソリューションだよ。動くけど、面積が大きいからちょっとした欠点もあるし、常に成長してるからね。

最近のJenkinsはどうなってる?

GitLabには勝てないよね。

EarthlyはCI/CD製品から方向転換してる:Satelliteを閉鎖して、Earthlyのオープンソースプロジェクトのアクティブメンテナンスを停止するんだって。https://earthly.dev/blog/shutting-down-earthfiles-cloud/

Gitlab?アクションよりも前からあるし、ずっと良いと思うんだけど、なんで他の選択肢を考える人がいるのか正直わからない(理由があれば聞きたいけど)。

もう一つ提案させて:オンプレミスのTeamCityはどう?まだ無料で使えるし、最後に使ったのは数年前だけど、すごく完成度が高くて安定してて使いやすい印象だった。比較すると、Jenkinsは重くて複雑に感じるね。

Giteaは簡単にセルフホスティングできて、Gitea Actionsもサポートしてるよ。GitHub Actionsと大体互換性があるんだ。今、試してみようとしてるところ。 https://docs.gitea.com/next/usage/actions/overview

Earthlyはもう終わったと思うけど、Daggerはまだ元気そうだね… Earthlyは素晴らしかった。CIとローカルで全く同じセットアップだった。コミュニティの努力で復活させようとしてるけど、果たして生き残るかどうかはわからないな。

バカな質問かもしれないけど、なんでGitHubはGitHub Actionsをローカルで実行できるソリューションを作らないの?せめてアクションを検証するソリューション(成功する確率を少し上げる、いわばドライランみたいな)を作ってほしいな。俺の戦記だけど、楽観的に5回のキー入力「r」「s」「p」「e」「c」で自分を救おうとしたら、40回以上のコミットと朝日を見ただけで、GHAでの成功したテスト実行はなし。ヘッドレスブラウザは脆弱だけど、GHAを使うのに比べてコストパフォーマンスがひどかった、少なくともインディー開発者にとってはね。

GitHub(マイクロソフトのサービス)が、なんでユーザーにGitHubに依存しすぎないようにさせたいの?それって消滅を難しくするだけじゃん。

そうだよ。アクションは空でもいいし、アクションがWebhookイベントを生成するから。Webhookで好きなことをすればいいよ。

これって https://docs.gitlab.com/runner/ のこと?

CIとデプロイをGitHub Actionsに縛るより、できるだけ多くをシェルスクリプトにして、それをGHアクション内のコンテナで呼び出す方がいいよ。ダウンロードした依存関係のキャッシュなど、最適化したいこともあるし、ビルドがCIに依存しないように待ってると、ベンダー特有のショートカットに誘惑されにくくなる。通常はもっとコードが必要になるけど、ローカルでテストしやすくなるよ。それに、後でプロバイダーを変更するのは難しいけど、「チームを立ち上げて6ヶ月かかる」レベルではないからね。

Nixは実際にこれにぴったりだよ。

こういうスレッドではいつもこれがトップコメントだね。今のCI/CDの状態が悲惨にプロプライエタリだっていう証拠だと思う。無料でオープンソースのコンパイラがなかった暗黒時代みたいだ。いつになったら反撃して「もう十分だ!」って言えるんだろう?CI/CDは、私たちのコントロールとローカルで作業する能力を取り戻すために、Kubernetesに似たものが絶対に必要だよ。個人的には、Gitコミット、プッシュ、デバッガーも変数インスペクターもなしで5分待って、コンソールログにダンプするようなパイプライン開発の内ループにはうんざりしてる。俺たちはタイヤショップの中でタイヤを再発明する必要なんてないんだ。

それは大体合ってる。 - コードの変更とコンテナをつなぐ何かが必要かも。特にマルチ/モノレポの設定だと、すべての変更で全てをビルドするのは難しいから。 - コンテナの結果をブランチ保護ルールに戻す方法も必要だと思う。毎回全てをビルドするなら簡単だけど、そうじゃないと難しいよね。 - アクションが実行されるコンピュート能力をコントロールしたいと思うはず。スピードとコスト管理のためにね。キャッシュが重要だから、コンピュートソリューションによっては良し悪しがあるし。GitHub Actionsがこれらの問題をうまく解決してるとは思わないけど、コンテナも単独では解決できてないよね。