CTO室SREの @sinsoku です。
社内のGitHub ActionsのYAMLが複雑になってきたので、私が参考にしてる情報や注意点、イディオムなどをまとめておきます。
頻繁に参照するページ
新しい機能の説明が日本語ページに反映されていないため、基本的に英語ページを読むことを推奨。
- ワークフロー構文
- YAMLの基本構文の確認
- コンテキストおよび式の構文
github
オブジェクトの情報、関数の確認
- ワークフローをトリガーするイベント
- 各イベントの
GITHUB_SHA
とGITHUB_REF
が記載されている
- 各イベントの
- About GitHub-hosted runners
- インストールされているSoftwareのバージョンなどが記載されている
- GitHub REST API
- APIを使うときに参照する
よく使うaction
actions/checkout
イベントによってはデフォルトブランチをチェックアウトするため、 ワークフローをトリガーするイベント のページで GITHUB_SHA
を確認する必要がある。
例えば pull_request
イベントの GITHUB_SHA
はデフォルトブランチとのマージコミットになるため、ブランチのHEADを使う場合は以下のような指定が必要です。
- uses: actions/checkout@v2 with: ref: ${{ github.event.pull_request.head.sha }}
actions/github-script
簡単なAPIの実行であれば、これで事足りる。
例えば、Issueコメントにリアクションをつけるコードは下記の通り。
name: reaction on: issue_comment: types: [created] jobs: - name: Create a reaction uses: actions/github-script@v3 with: script: | await github.reactions.createForIssueComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: context.payload.comment.id, content: "+1", });
ワークフローを書く時に注意すること
文字列は一重引用符
RubyやJavaScriptを書いていると間違いやすいので注意。
"foo"
はエラーになるので 'foo'
にします。
タイムアウトの指定
Actionsは実行時間で課金されるため、意図しない長時間の実行を防ぐために基本的に設定しておく方が良い。
timeout-minutes: 5
並列実行数の制御
ワークフローを無駄に実行しないように、基本的に設定しておく方が良いです。
ただ、 github.ref
だけ指定すると他ワークフローを意図せず止めてしまうことがあるため、 github.workflow
を接頭辞につけておいた方が安全です。
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true
GITHUB_TOKEN
を使うと新しいActionは起動しない
意図せず再帰的にActionが起動するのを防ぐためですが、知らないとハマります。1
- Approveされたプルリクを自動マージ
- マージされた後に自動デプロイ
例えば上記のように2つのActionを作っても、2つ目のActionは起動しないです。
これを解決するには GITHUB_TOKEN
の代わりに personal access token を使う必要があります。
envは steps
の中でしか使えない
以下のコードは Unrecognized named-value: 'env'
でエラーになります。
env: FOO: foo jobs: run: runs-on: ubuntu-latest timeout-minutes: 5 env: BAR: ${{ env.FOO }}-bar steps: - run: echo ${{ env.BAR }}
同様に matrix
の中でも env
は使えないです。
success()
はifでしか使えない
以下のコードは Unrecognized function: 'success'
でエラーになります。
- name: Notify finish deploy to Rollbar uses: rollbar/github-deploy-action@2.1.1 with: environment: 'production' version: ${{ github.sha }} local_username: ${{ github.actor }} status: (success() && 'succeeded') || 'failed'
if条件は式構文 ${{ }}
を省略できるケースがある
ドキュメントに記載されてはいるが、Web上の事例ではあまり書いてないので紹介する。
式に演算子が含まれていない場合は ${{ }}
を省略できます。
if: always()
ただ、 ${{ }}
をつけても特に問題はないため、常に ${{ }}
で囲んでおいた方が良いかも。
outputs のデフォルト値
ドキュメントに記載されていないですが 空文字列 になります。
例えば、デプロイ処理の準備中にワークフローをキャンセルされることもあるため、以下のように if:
でoutputsをチェックしておく必要があります。
deploy: outputs: deployment-id: ${{ steps.deploy.outputs.deployment-id }} steps: - name: Prepare for deployment run: echo "do something" - name: Deploy id: deploy run: echo "::set-output name=deployment-id::1" rollback: needs: [deploy] if: cancelled() && needs.deploy.outputs.deployment-id
イディオム
三項演算子
三項演算子と同等のことは以下の書き方で実現できます。
env: RAILS_ENV: ${{ (github.ref == 'refs/heads/main' && 'production') || 'staging' }}
ArrayとObjectの生成
リテラルの記法が存在しないため、 fromJSON
を使う必要があります。
env: is_target: ${{ contains(fromJSON('["success","failure","error"]'), github.event.deployment_status.state) }} rollbar_status: ${{ fromJSON('{"success":"succeeded","failure":"failed","error":"failed"}')[github.event.deployment_status.state] }}
その他
Dependabotを設定する2
DependabotはGitHub Actionsに対応しているので、設定しておくと便利です。
version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily"
採用のリンク
メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!
■募集ポジションはこちら
https://medpeer.co.jp/recruit/entry/
■開発環境はこちら
https://medpeer.co.jp/recruit/workplace/development.html
-
GITHUB_TOKEN
の詳細な権限は Authentication in a workflowを参照してください。↩