LoginSignup
3
1

More than 1 year has passed since last update.

GithubActionsをローカルで検証可能にする

Last updated at Posted at 2022-12-19

概要

この記事は朝日新聞社 Advent Calendar 2022 の20日目の記事です。
朝日新聞デジタルの開発現場ではCI(継続的インテグレーション)ツールとしてGithub Actionsが利用されています。

エンタープライズ版で1ヶ月5,000分、無料版でも1ヶ月2,000分間は追加料金なしで利用できてとても便利ですが、テスト項目増加やデプロイフローが複雑化してくると上限時間を超過してしまうことがよくあります。(パブリックリポジトリは無制限です!!)

また、ちょっとしたGithubActionのデプロイフロー変更でもプルリクエスト(PR)をGithubにあげなくてはならないので非効率だと感じることがありました。

そこで、今回はGithubActionsを自身のローカル環境で試せるようにしたのでその方法をご共有しようと思います。

利用したライブラリ

成果物

Githubでサンプルコードを公開しております。
https://github.com/nakamura-k30/github-actions-demo
公式のサンプルリポジトリをForkして動作確認で試したコードを追加しています。
本記事のコマンド例もこちらのサンプルコードに対応してます。

実行環境

OS: macOS Big Sur 11.6
Docker Desktop for Mac: v4.14.1
Macで動作確認しておりますが、Windows/Linuxでも利用可能です。

導入手順

事前準備

dockerのインストールが必要です。
Docker Desktop for MacDocker Desktop for WindowsDocker Engine for Linux

actインストール

macOS/Linux

brew install act

これだけで準備OKです!

利用方法

GithubActionsのワークフローが設定してあるリポジトリのルートでact -lを実行して実行可能なワークフローを表示してみます。
以降の作業はすべてリポジトリのルートで実行しています。

$ act -l
Stage  Job ID  Job name  Workflow name  Workflow file  Events           
0      test    test      CI             main.yml       push,pull_request
0      lint    lint      CI             main.yml       push,pull_request
0      test    test      Reminder       reminder.yml   push       
1      deploy  deploy    CI             main.yml       push,pull_request

act -lで各ジョブが何のワークフローに属しているかの一覧が表示されました。
Stageはジョブの実行の順序(前提条件があるか)、Eventsは実行に必要なGithub eventになります。

続いてact -gを実行するとワークフローをグラフ化できます。

$ act -g
 ╭──────╮ ╭──────╮ ╭──────╮
 │ test │ │ lint │ │ test │
 ╰──────╯ ╰──────╯ ╰──────╯
             ⬇
         ╭────────╮
         │ deploy │
         ╰────────╯

サッと全体像が掴めるので便利ですね。
ただ、./.github/workflows/配下のワークフローが全て出ているので少しわかりづらいです。
そのような場合は-Wフラグで確認したワークフローファイルを指定できます。

 $ act -g -W "./.github/workflows/main.yml" 
 ╭──────╮ ╭──────╮
 │ test │ │ lint │
 ╰──────╯ ╰──────╯
        ⬇
    ╭────────╮
    │ deploy │
    ╰────────╯

それでは本題のジョブを実行してみます。
actとだけ実行すると全てのワークフローが動き出すのでact -j test -W "./.github/workflows/main.yml"としてmain.ymlのtestジョブのみを実行します。
初回実行時だけ実行のために必要なimageサイズを聞かれるのでMediumを選択します。

$ act -j test -W "./.github/workflows/main.yml"
? Please choose the default image you want to use with act:

  - Large size image: +20GB Docker image, includes almost all tools used on GitHub Actions (IMPORTANT: currently only ubuntu-18.04 platform is available)
  - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with all actions
  - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions

Default image and other options can be changed manually in ~/.actrc (please refer to https://github.com/nektos/act#configuration for additional information about file structure)  [Use arrows to move, type to filter, ? for more help]
  Large
> Medium
  Micro
...(中略)
[CI/test]   ✅  Success - Main test
[CI/test] ⭐ Run Post Setup Node
[CI/test]   🐳  docker exec cmd=[node /var/run/act/actions/actions-setup-node@v3/dist/cache-save/index.js] user= workdir=
[CI/test]   💬  ::debug::Caching for '' is not supported
[CI/test]   ✅  Success - Post Setup Node
[CI/test] 🏁  Job succeeded

Dockerイメージがダウンロードされてtestジョブの実行が成功しました。

これだけではGithubActionsのローカル検証ができるとはまだ言えないので、少し発展的な条件指定方法を紹介します。

  • イベント指定
  • アクター指定
  • シークレット情報の指定
  • github コンテキストの指定

イベント指定

GithubActionsワークフロー内で起動条件はonで記載されています。
コマンドからイベントを指定する場合は、act [<event>] [options]とします。
eventにはpull_requestpushpull_request_targetなど利用可能です。
何も指定しない場合はpushになります。

ワークフローの記載例を示します。

name: Reminder
on:
  pull_request:
    types: [opened, synchronize]

この場合はpull_requestでジョブを起動したいのでpull_requestと記載した場合のみ起動します。

実行可能
$ act pull_request -W "./.github/workflows/reminder.yml" 

実行されない(-vオプションで詳細表示)
$ act push -W "./.github/workflows/reminder.yml" -v 

起動条件でon.pull_request.typeson.push.branchesを指定することもあると思いますが、actでは未対応となっているようでした。

詳細は公式Wikiのactでサポートしているオプションリストを参照して下さい。
個人的にはjob.<job_id>.concurrency が利用できない点も残念でした。

Githubアクターの指定

actコマンドでGithubアクターを指定するには-aオプションを利用します。

実行可能
$ act -a "nakamura-k30" -j lint
実行されない
$ act -a "dependabot[bot]" -j lint

シークレット情報の指定

actコマンドでワークフロー内で利用されるシークレット情報を指定するには-sオプションを利用します。

    steps:
      - uses: actions/checkout@v3
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
          aws-region: ap-northeast-1

上のワークフローで利用されるシークレット情報を指定する場合は以下のコマンドになります。

$ act push -s AWS_IAM_ROLE_ARN=XXX

実行ログにもシークレット情報は***とマスクされた状態で出力されます。

github コンテキストの指定

最後に、github.*でワークフロー内で取得可能なgithub コンテキストを指定する方法を紹介します。
github コンテキストには、ワークフローの実行とその実行をトリガーしたイベントの情報が含まれます。

各イベント(push、pull_requestなど)ごとに付与できるペイロードは決まっています。
actコマンドでは各イベントのペイロードを用意しておけば実行時に指定することが可能になります。

pushとpull_requestの場合の例になります。

pushイベントのペイロード
ペイロード例

push-payload.json
{
  "ref": "refs/heads/master"
}

この値は、ワークフロー内でgithub.refとして参照可能になります。

pull_requestイベントのペイロード
ペイロード例

pull-request-payload.json
{
  "action": "opened",
  "pull_request": {
    "head": {
      "ref": "sample-head-ref"
    },
    "base": {
      "ref": "sample-base-ref"
    }
  },
  "number": 123
}

この値は、ワークフロー内でgithub.base_refgithub.head_refgithub.head_refgithub.numberとして参照可能になります。

以下のようなgithub.refがmasterブランチに向いているときにのみ動き出すワークフローでgithub コンテキストを指定します。

deploy:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' && github.actor != 'dependabot[bot]' && success()
    needs: [lint, test]

-eオプションで作成したイベントのペイロードへのパスを記載します。

$ act push -e push-payload.json -a "nakamura-k30" -s AWS_IAM_ROLE_ARN=XXX

終わりに

当たり前のことですがローカルにシークレット情報を持ってきて検証する場合は十分に注意が必要ですのでローカルでの管理はお気をつけください。
actコマンドは色々なオプションがあり便利でしたが一部対応していない機能もあるので研修やデプロイフローの理解のために役立てれると良いなと思いました。
今後も良いデプロイフローを構築できるように試行錯誤してみたいと思います!

参考

https://github.com/nektos/act
https://github.com/cplee/github-actions-demo
https://github.co.jp/features/actions
https://docs.github.com/ja/developers/webhooks-and-events/events/github-event-types
https://github.com/nektos/act/wiki/GitHub-Actions-compatibility#workflow

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1