概要
この記事は朝日新聞社 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 Mac、Docker Desktop for Windows、Docker 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_request
やpush
、pull_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.types
やon.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イベントのペイロード
ペイロード例
{
"ref": "refs/heads/master"
}
この値は、ワークフロー内でgithub.ref
として参照可能になります。
pull_requestイベントのペイロード
ペイロード例
{
"action": "opened",
"pull_request": {
"head": {
"ref": "sample-head-ref"
},
"base": {
"ref": "sample-base-ref"
}
},
"number": 123
}
この値は、ワークフロー内でgithub.base_ref
、github.head_ref
、github.head_ref
、github.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