🐙

Check! GitHub Actions 再利用可能なワークフローのポイントを抑える

2023/02/24に公開2

Prologue

こんにちは、@dz_ こと、岩永かづみです。

最近、GitHub Actions の "Reusable workflow" 再利用可能なワークフローについて質問されることが多いので、ポイントをまとめてみます。

https://docs.github.com/ja/actions/using-workflows/reusing-workflows

どういうときに再利用可能なワークフローを使えばいいのか?という疑問に、私なりのベストプラクティを後半に記載したので悩まれている方はご参考ください💡

GitHub Actions でワークフローから呼び出せるワークフローを作成できる

まずは、「ワークフローの再利用」についておさらいです。

どういうことかというと、他のワークフローから呼び出すことができるワークフローを作成することができます。

ドキュメントでは、呼ばれる側のワークフローは「再利用可能なワークフロー」(reusable workflow)、呼ぶ側のワークフローは「スターター ワークフロー」(starter workflow)と表現されています。

GitHub Actions 再利用可能なワークフローの概要図

ワークフローを再利用可能にするには、on:workflow_call を指定することで呼び出せるようになります。

再利用可能なワークフロー
on:
  workflow_call:

スターター ワークフローから再利用可能なワークフローを実行するには、job の直下で uses キーワードを用いて呼び出します。

スターター ワークフロー
jobs:
  # 別のリポジトリの再利用可能なワークフローファイルを呼び出す場合
  call_reusable_workflow_on_other_repository:
    uses: {owner}/{repo}/.github/workflows/{再利用可能なワークフローのファイル名}@main

  # 同じリポジトリの再利用可能なワークフローファイルを呼び出す場合
  call_reusable_workflow_on_same_repository:
    uses: ./.github/workflows/{再利用可能なワークフローのファイル名}

スターター ワークフローから再利用可能なワークフローを実行すると、再利用可能なワークフローのジョブは透過的にスターター ワークフロー側のジョブとして扱われます。例えば、再利用可能なワークフローに複数のジョブがあれば、実行時はスターター ワークフローのジョブに組み込まれた状態で実行されます。

GitHub Actions 再利用可能なワークフローはひとつのジョブのように

上図のサンプルコードはこちら。

https://github.com/dzeyelid/github-learning-playground/blob/main/.github/workflows/starter-workflow.yml

https://github.com/dzeyelid/github-learning-playground/blob/main/.github/workflows/reusable-workflow.yml

再利用可能なワークフローへの入力

再利用可能なワークフローに対して、入力を定義することができます。入力の値の型は、typestring, number, boolean を指定できます。

on:
  workflow_call:
    inputs:
      param1:
        description: Fill in param1
        required: true
        type: boolean
      param2:
        type: number
      param3:
        type: string
        default: 'hello'

詳しくは、ドキュメントをご確認ください。

再利用可能なワークフローへのシークレットの引き渡し

再利用可能なワークフローの中で扱うシークレットは workflow_call.secrets で定義し、スターター ワークフローから明示的に入力します。

reusable-workflow.yml
on:
  workflow_call:
    secrets:
      CLIENT_SECRET:
        required: true
starter-workflow.yml
jobs:
  reusable_workflow_job:
    uses: {owner}/{repo}/.github/workflows/reusable-workflow.yml@main
    secrets:
      CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}

詳しくは、ドキュメントをご確認ください。

再利用可能なワークフローの出力

再利用可能なワークフローの出力は、スターター ワークフローで利用することができます。

再利用可能なワークフロー
on:
  workflow_call:
    outputs:
      greeting_message:
        value: 'Hello'
スターター ワークフロー
jobs:
  reusable_workflow_job:
    uses: {owner}/{repo}/.github/workflows/reusable-workflow.yml@main

  post_process_job:
    needs: reusable_workflow_job
    runs-on: ubuntu-latest
    steps:
      - run: echo ${{ needs.reusable_workflow_job.outputs.greeting_message }}

詳しくは、ドキュメントをご確認ください。

再利用可能なワークフローを使うべきときは?

どういうときに、再利用可能なワークフローの仕組みを使うとよいか?自作アクションとの使い分けは?の問いに対して、筆者はこう捉えています。

再利用可能なワークフローが適したシチュエーション

  • 複数のアクション(+数行のシェルスクリプト)で構成できる場合
  • 条件分岐がない、少ない場合
  • 上記の条件にあてはまり、かつ組織やプロジェクトで処理を統一したい場合

いくつかワークフローを書いていると、ビルドやデプロイなどの処理はいくつかのアクションで簡単に実現できるが、似通っていて何度も書くのが面倒になってくることがあります。そういうときに、ワークフローにまとめておくと繰り返しの作業を軽減することができます。

なお、繰り返しの作業であっても、条件分岐が複雑な場合はむしろ煩雑になってしまうので要注意です。

また、組織やプロジェクトで統一したい処理がある場合も再利用可能なワークフローにまとめると、品質を保ったり、レビューを効率化するのに有効だと考えられます。ただし、ワークフローの処理が複雑になりそうな場合は、後述のテンプレートを利用してゆるく共有する方が適しているかもしれません。

自作アクションにした方がきれいなシチュエーション

逆に、自作アクションにした方がきれいにまとめられる場合もありますね。

  • 適したアクションが存在しない場合
  • シェルスクリプトで実現できるが、処理が多い場合
  • 条件分岐が複雑、多い場合

複雑な処理や条件分岐が多い場合は、 yml で処理するよりプログラムで処理した方が確実で、可読性も保てるので、自作アクションにまとめる方が適していると考えています。自作アクションは、JavaScript またはDockerコンテナを用いて任意の言語・環境で構成することができます。

自作アクションについてはこちらをご参照ください。

https://docs.github.com/ja/actions/creating-actions/about-custom-actions

GitHub Actions ワークフローをテンプレートとして共有するのも手

  • 複数のアクションで実現できるが、分岐が多い
  • 複数のアクションで実現できるが、バリエーションが多い

このような場合は、ワークフローをテンプレートとして組織内で共有するのも有効な手段です。繰り返しの作業を軽減できますし、ワークフローの構成の見本として提示することができます。

詳しくは、こちらをご参照ください。

https://docs.github.com/ja/actions/using-workflows/sharing-workflows-secrets-and-runners-with-your-organization

Epilogue

自分では自分の感覚で必要な時に使っていたけど、どんな時に使う?って質問をいただいたときに言語化できなかったので、整理を兼ねて記事に起こしてみました。

より便利に自動化ライフをお過ごしください♪

Discussion

若槻龍太若槻龍太

ドキュメントでは、呼ばれる側のワークフローは「再利用可能なワークフロー」(reusable workflow)、呼ぶ側のワークフローは「スターター ワークフロー」(starter workflow)と表現されています。

「スターター ワークフロー」は GitHub Actions においてはまた別の機能を指す用語なので、用法の間違いかと思います。
https://docs.github.com/en/actions/using-workflows/using-starter-workflows

ドキュメント上では、呼ばれる側は called workflow、呼ぶ側は caller workflow としているようです。

A workflow that uses another workflow is referred to as a "caller" workflow. The reusable workflow is a "called" workflow.

https://docs.github.com/en/actions/using-workflows/reusing-workflows#overview