GitHub Actions を act でローカルテストする

create
2020年11月02日
update
2020年11月19日

はじめに

GitHub Actions は便利。
だけど書いたワークフローが実際どう動くか試すため、実際に GitHub リポジトリへプッシュやマージしてコミット履歴を汚くするのはつらい。

できればローカル上で GitHub Actions をテストしたい!

ということで act を導入してローカル上でテストできるようにする。

Table 1. 環境
App Version

Windows10 Pro

1903

Docker Desktop

2.4.0.0

act

0.2.16

act とは🚀

GitHub Actions をローカルで実行するコマンドツール。
利用するには Docker が必要。

プロジェクト配下の .github/workflows/ を読み込み、Docker API を使って必要なイメージをプル・ビルドする。
そして各アクションはコンテナ内で実行される。

特徴
  • 環境変数やファイルシステムは GitHub が提供しているものに対応

  • GitHub Actions ワークフローをタスクランナー代わりとして使用可能

    • Makefile の代替

  • GitHub が提供しているコマンドツールについてデフォルトでは一部のみ対応

    • すべてのコマンドツールに対応させると Docker イメージのサイズが巨大マックス

    • 全部込みこみのイメージとして nektos/act-environments-ubuntu:18.04 が用意されているが 18GB 超え……

  • Rnners は ubuntu のみ対応

    GitHub Runner actが使用するDockerイメージ

    ubuntu-latest

    node:12.6-buster-slim

    ubuntu-18.04

    node:12.6-buster-slim

    ubuntu-16.04

    node:12.6-stretch-slim

インストール

今回はDebian ベースの Docker コンテナ内で使うのでシェルスクリプトからインストールした。
他ディストリビューションのインストール方法は 公式のREADME を参照。

rootユーザーでインストール
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | bash

使い方🍣

act [event name to run] [flags] で実行する。

コマンドの一例

他コマンドオプションについては act -h または README を参照。

Example 1. ワークフローの確認
# アクション一覧
act -l

# 特定イベントのアクション一覧
act pull_request -l

# DryRun
act -n
Example 2. テストを実行
# テスト実行
act

# コンテナを再利用してテスト
act -r

# イベントを指定してテスト
act workflow_dispatch

# ジョブ名を指定してテスト
act -j JOB_NAME

# Secret変数を指定してテスト
act -s MY_SECRET=something

act の設定ファイル

  • コマンドオプション

    オプションは ./.actrc または ~/.actrc 設定ファイルに記述しておくことができる。

    Example 3. .actrc ファイルの例
    # runnerイメージを変更
    -P ubuntu-18.04=node:12-buster
  • 環境変数

    環境変数はデフォルトで .env ファイルを参照する。
    別ファイルで参照させたいときは --env-file <ENV_FILE> オプションを追加。

Dockerコンテナ内で実行したい

Docker コンテナ内でやる場合は DooD(Docker outside of Docker) のように、ホスト側の docker.sock をバインドしておく。
(コンテナ内でのdockerパッケージは不要)

docker.sockをバインドしておく
docker run --rm -it \
    --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
    debian:buster-slim \
    bash
コンテナユーザーが root 以外

docker.sock のパーミッションのため、コンテナ起動時に root グループへ所属させておく(--group-add 0)。
セキュリティは低下するが、開発用でしか使わないなら許容できる。

docker run --group-add 0 ...
Windowsホストの場合

バインドした /var/run/docker.sock は所有者 root:root でパーミッションが 755 になっている。
よってコンテナ内のユーザーが root 以外の場合はパーミッションを修正する必要がある。

Windowsホストからパーミッションを修正
docker exec CONTAINER_NAME chmod 660 /var/run/docker.sock

トラブルシューティング🔨

○✕コマンドがない

act がデフォルトで使う Runner のイメージ(node:12.6-buster-slim)ではインストールされているコマンドが少ないため。
git コマンドもない。

代替として、一通りのコマンドが揃っている node:12-buster イメージを使うといい。

act -P ubuntu-18.04=node:12-buster

if文が期待する動作をしない

条件式を ${{ }} で囲むといい。
実際の GitHub Actions では省略しても大丈夫だが、act で省略すると判定してくれない場合があるっぽい。

Example 4. act で動作するif文の例
- name: install
  if: ${{ steps.yarn-cache.outputs.cache-hit != 'true' }}
  run: yarn install

おわりに🐾

act により GitHub Actions のテストと修正が簡単にできるようになったので満足。
ただし、実際にGitHubリポジトリで動作させるとバグが見つかる場合があるので注意する。