GitHub Actionsのテストをactを使って行う
GitHub Actionsのトリガーと分岐条件のテストにactを使ったので、そのときの知見です。
- act version 0.2.55
M1 Macなので以下のaliasを設定して作業しました。
alias act='act --container-architecture linux/amd64'
書いていること
- トリガーしたいブランチの指定方法
- github.event_nameでworkflow_dispatchが返ってくる方法
- false == ''がtrueの話(なんちゃって三項演算だと困るという話)
指定のブランチへのpushを検証する
act push
だけ行うとデフォルトブランチへのpushトリガーが発火するので、対象ブランチを変えたい場合は--defaultbranch
オプションでブランチを指定します- ワークフローのファイルを指定しなかった場合、
.github/workflows
ディレクトリ配下の全ファイルがチェック対象になるので、 特定のファイルを指定したい場合は-W
オプションでファイルを指定します
stagingブランチへのpush確認 $ act push --defaultbranch staging $ act push --defaultbranch staging -W .github/workflows/cd-staging.yml
手動実行ワークフローの検証をする
- ワークフローに渡すパラメータは。JSONファイルに定義して
-e
オプションで指定します - 実行させたいワークフローは、実行したいジョブ名でも限定できます(
--job
オプション)
手動実行の確認 $ act workflow_dispatch --job action-test -e act_cd.json -W .github/workflows/cd-staging.yml $ act workflow_dispatch --job build-test -e act_build.json -W .github/workflows/build.yml
ハマったところ
act workflow_dispatch 〜
というようにworkflow_dispatchを入れないと、github.event_nameがworkflow_dispatchになりませんでしたact 〜
だとinputのJSONファイルにactionをworkflow_dispatchで定義していても、github.event_nameはpushになっていました- そもそもJSONファイルにactionは記載しなくても動作しました
- また通常は
inputs.XXXX
でとれるinputsの値が、actを利用した場合はgithub.event.inputs.XXXX
と書かないと取れませんでした
ここまでのサンプルファイル
.github/workflows/cd-staging.yml
name: TEST Deploy on: push: branches: - staging workflow_dispatch: inputs: deploy-app: description: "deploy app" type: boolean default: true migration: description: "migration" type: boolean default: false jobs: build-images: uses: ./.github/workflows/build.yml with: build-app: true environment: "stg" if: ${{ github.event_name == 'push' }} action-test: runs-on: ubuntu-latest needs: build-images if: always() steps: - name: Check run: echo "${{ github.event.inputs }},${{ github.event_name }} deploy!" - name: Check deploy app Image if: ${{ github.event_name == 'push' || github.event.inputs.deploy-app }} run: echo "deploy-app true" - name: Check deploy migration Image if: ${{ github.event_name == 'push' || github.event.inputs.migration }} run: echo "deploy-migration true"
act_cd.json
{ "action": "workflow_dispatch", "inputs": { "deploy-app": true, "migration": false } }
.github/workflows/build.yml
name: TEST Build on: workflow_call: inputs: build-app: required: true type: boolean environment: required: true type: string workflow_dispatch: inputs: build-app: description: "appのimage作成" type: boolean default: true environment: description: "environment" type: choice required: true options: - prd - stg - dev jobs: build-test: runs-on: ubuntu-latest steps: - name: Check run: echo "${{ inputs }},${{ github.event_name }} build!" - name: Check build app if: ${{ github.event_name == 'push' || github.event.inputs.build-app }} run: echo "build-app true" - name: Check build environment if: ${{ github.event_name == 'push' || github.event.inputs.environment }} run: echo "${{ github.event.inputs.environment }}"
act_build.json
{ "action": "workflow_dispatch", "inputs": { "build-app": true, "environment": "stg" } }
false == ''がtrueの話
最後にちょっと困った話を書いておきます。
GitHub Actionsのドキュメントなどには、$$
と||
を使って、疑似的に三項演算子のような書き方をしているときがあります。
env: MY_ENV_VAR: ${{ github.ref == 'refs/heads/main' && 'value_for_main_branch' || 'value_for_other_branches' }}
説明のために解説すると、式A && 式B || 式C
という式があった場合、式Aがtrueであれば式Bの結果が、式Aがfalseであれば式Cの結果が返ってくるのですが、
これだと式Aで左辺の値が未定義ではなくfalseとして定義されているかをチェックすることができません。
というのもGitHub ActionsにはJavaScriptでいうところの厳密比較がないので、'' == false
やnull == false
はtrueになり、チェックしたい値 == false
とした場合、
チェックしたい値がfalseでも未定義でも結果がtrueになるからです。
なんでこんなことでハマったのかというと、最初はgithub.event_name
のことを忘却しており、
ワークフローのトリガーがworkflow_callかworkflow_dispatchかをinputsの値の有無で判定しようとしたのですが、
inputsの変数にfalseが入ってきたときににっちもさっちもいかなくなったからでした。
前半の解説にちょいちょいgithub.event_nameやinputsの話が出てきているのはこれが理由です
まとめ
act自体はGitHubにymlファイルをpushすることなくワークフローが試せるのでおすすめです。
今回はやらなかったのですが、actでGITHUB_TOKENを利用したワークフローを試す場合は、自身のGitHub個人トークンを発行し、.secretsファイルから読み込ませるとできるはずです。
2024/01/18追記
inputsとGITHUB_TOKENの話はこちらに補足があります。
あとがき
この記事を最近買ったNuPhy Air60 V2をMacBookの上に置いてBluetoothで繋いで書いたのですが、Discordのコミュニティで提供されていたQMK_firmware_nuphy_air60_v2_ansi_v1.1.1.bin
を適用した後も3回ほどBluetooth接続が切れてしまいました。
キーボード自体は思っていた以上に打ち心地が良かったので、改善されたfirmwareが出ることを期待しています。