メドピア開発者ブログ

集合知により医療を再発明しようと邁進しているヘルステックリーディングカンパニーのエンジニアブログです。読者に有用な情報発信ができるよう心がけたいので応援のほどよろしくお願いします。

入門 GitHub Actions

CTO室SREの @sinsoku です。

社内のGitHub ActionsのYAMLが複雑になってきたので、私が参考にしてる情報や注意点、イディオムなどをまとめておきます。

頻繁に参照するページ

新しい機能の説明が日本語ページに反映されていないため、基本的に英語ページを読むことを推奨。

よく使う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

  1. Approveされたプルリクを自動マージ
  2. マージされた後に自動デプロイ

例えば上記のように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



  1. GITHUB_TOKEN の詳細な権限は Authentication in a workflowを参照してください。

  2. Keeping your actions up to date with Dependabot