複数リポジトリでのGithub Actions運用 2021年の状況総まとめ
「複数のリポジトリでGithub Actions運用しているけど横展開が大変」
「似たような処理が多いからうまくまとめたい」
「でもどうすればいいんだろう」
Github Actionsを扱っているとそう思う機会って結構ありませんか?解決する方法もいくつかあるんですが、それぞれが一長一短ですし注意が必要な点もいくつかあります。
なので2021年末時点で何が使えるのか、どれを使うべきか、今後どうなっていくのかを全部まとめました。
この記事を読めばまるっと状況を把握できる...はずです!(多分)
(shellをゴリゴリ書くなどやり方次第で色々突破できるかもですが、この記事ではあくまでgithub actionsの機能として用意されているものをスコープに話を進めていきます。)
なおこの記事はMakuake Advent Calendar 2021とGitHub Actions Advent Calendar 2021の22日目の記事です。
今現在何が使えるのか
「複数のリポジトリでGithub Actionsに同じような処理をさせる」方法は大きく以下の2つです。
- 別のリポジトリにあるactionを
checkout
で取得して使用する - 別のリポジトリにあるReusable workflowを使用する
それぞれメリット・デメリットがあります。
別のリポジトリにあるactionをcheckoutで取得して使用する
一つ目の方法は別リポジトリのactionsを使うものです。
使い方
流れとしては
- 使用側の
workflow
から使いたいリポジトリをcheckout
する -
checkout
したactionをuse
し実行する
というシンプルなものになるのですが、checkout
時には色々と注意が必要です。
例を見ながら注意点をコメントで説明していきます。以下のymlはまさに上記の通り2つの(checkout
し、use
する)ステップを記述しています。
name: example
on:
push:
jobs:
use-other-action:
name: Use other action from this repository
runs-on: ubuntu-latest
steps:
# まずcheckoutして他のリポジトリの内容を持ってくる
- name: Checkout other repository
uses: actions/checkout@v2
with:
# 使いたいactionがあるorganization/repositoryをcheckoutする対象に指定
repository: organization-name/repository-name
# branch名だけでなくtagやcommit hashなど取得元を一意に特定できるものなら何でもok
ref: main
# 取得したアクションをこのリポジトリのどこのディレクトリに持ってくるか決める
path: .github/actions/other-repository
# private repoのactionを使う時のみ必要。
# ここで使うtokenはsecrets.GITHUB_TOKENでは不可
token: ${{ secrets.YOUR_ACCESS_TOKEN_FOR_PRIVATE_REPOS }}
- name: Use the action in the other repository
# checkout時にpathで指定した場所 + 使用するactionの場所をつなげて記述する
# ディレクトリを指定しているので./から始める必要がある点に注意
uses: ./.github/actions/other-repository/.github/actions/other-action
with:
# 引数は好きに渡せる
message: "Any args can be passed to the action"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # ここで使うgithub tokenはsecrets.GITHUB_TOKENでok
基本的に上記のコメントの通りですが、特にハマりがちなのはcheckout
時のtoken
の設定です。publicリポジトリしか触らない方であればtoken
の設定は不要なのでここは読み飛ばしていただいて構いません。
普段であればsecrets.GITHUB_TOKEN
と記述すればPersonal Access Token
(PAT
)を発行せずとも権限を持たせてworkflowを走らせることが可能です。
ですが、privateリポジトリをcheckout
する際はsecrets.GITHUB_TOKEN
では権限が足りないため、privateリポジトリの権限を持つPAT
を事前に発行しておいて使う必要があります。
先述の通りPAT
を使う必要があるのはここだけで、checkout
前後にaction
を実行するためであればsecrets.GITHUB_TOKEN
で十分なはずです。
[参考: secrets.GITHUB_TOKEN
について]
メリット・デメリット
この方法の大きなメリットとして、privateリポジトリのaction
であっても使用できる、という点が挙げられます。後述する方法ではprivateリポジトリにある処理を使用することはできないのですが、こちらにはそうした制約がありません。
一方デメリットとしては、サードパーティー製のaction
を使い回せないという点が挙げられます。というのも、action
には「別のaction
を呼び出すことができない」という制約があるからです。 この方法では別リポジトリにあるaction
の定義を拝借して実行するので、そこからさらにaction
を呼び出すことはできません。
このため、github公式のaction
(checkoutやsetup-node、chacheなど)や、aws-actionsなどを使用するには、結局自身のworkflow
に記述するしかありません。
Reusable workflow
を使用する
別のリポジトリにある二つ目の方法は最近一般に公開されたReusable workflow
という機能を使うものです。先程はaction
を使い回していましたが、これは名前の通りworkflow
を再利用するものです。 詳しくは後述しますが、あくまでworkflow
なのでaction
を使うことができ、複雑な処理であっても簡単に共通化することができます。
またこれも後述しますが、他のリポジトリのReusable workflow
を利用する場合、Publicリポジトリに置いてあるReusable workflow
しか使用できない という点も注意が必要です。
使い方
流れとしては
- 対象のworkflowを直接useする
というシンプルなものになっています。ですがこちらもいくつか注意は必要なので、実際の例と一緒に見ていきましょう。
使用する側
まず使用する側の記述です。
name: Reusable user
on:
workflow_dispatch:
jobs:
use-reusable-workflow:
# runs-onの指定は不要
# reusable workflowがあるorganiztion名/リポジトリ名/workflowまでのpath@ref で記述
# refは一意に特定できるものならok(tag, branch, commit hashなど)
uses: organiztion-name/repository-name/.github/workflows/reusable.yml@main
# 引数はwithに渡す
with:
name: ${{ github.repository }}
workflow
を丸ごと再利用するものなので、jobs.runs-on
の定義が不要になっている点に注意が必要です。
また、action
を使用するのと異なり、yml
までのpathをuses
に指定する必要があります。action
の場合はaction.yml
が格納されているフォルダ名まで指定すれば良いのですが、この点は異なるので注意してください。
使用される側
次に使用される側です。
name: Reusable provider
on:
# workflow_callを設定することでreusableとして扱えるようにする
workflow_call:
# inputs/outputsはworkflow_call以下に定義
inputs:
name:
required: true
type: string
jobs:
example_job:
name: Run shared action and show passed value
runs-on: ubuntu-latest
steps:
- run: echo Hello
# reusable workflowを提供する側に定義されているactionを使う場合checkoutする必要あり
- uses: actions/checkout@v2
with:
# organization名/リポジトリ名
repository: organization-reusable-provider/repo-provider
ref: main
# 使用側のどこにcheckoutするか決める
path: .github/actions/other-repository
# 使用側のworkflowとして実行されるので、使用側としてどれを使うのかという目線で書く
- uses: ./.github/actions/other-repository/.github/actions/shared
# inputsを使う場合は${{ inputs.hoge }}で使用する
- run: echo this workflow is run by ${{ inputs.name }}
Reusable workflow
として扱うためにはon.workflow_call
を定義する必要があります。
一点注意が必要なのが、Reusable workflow
から同じリポジトリ(Reusable workflow
を定義・提供しているリポジトリ)にあるaction
を使用する場合です。Reusable workflow
はあくまで使用側のworkflow
として実行されるため、実行時に元々のリポジトリを参照することができません。
そのため、そうしたaction
を使用したい場合はあらかじめ他のリポジトリから利用することを意識してcheckoutしておく必要があります。 この点はハマりそうだと感じたので詳しくは別途記事にまとめようと思います。
なお文法全般について気になる方は、以前自分がざっとまとめた記事や公式ドキュメントを見てみてください。
メリット・デメリット
この方法ではworkflow
を再利用するため先述のとおりどんなaction
も使用できるというのが大きなメリットです。
一方でこちらも先述のとおり、publicリポジトリに定義されているworkflow
しか再利用できないという制限があるのが難点です。正確に言うと、現時点では
- publicリポジトリの
workflow
を再利用する - 同一リポジトリ内の
workflow
を再利用する(こちらはprivateリポジトリでもok)
の2パターンに限られています。
詳細は公式ドキュメントを確認してください。
どれを使うべきか
ここまでいくつか方法を見てきましたが、フローチャート的にまとめると以下の通りです。
- 単一リポジトリ内で共通化したい場合
-
Reusable workflow
を利用しましょう!
-
- 複数リポジトリ間で共通化したい場合
- 処理内容を公開できる場合
- publicリポジトリを作成し、
Reusable workflow
を定義して使い回しましょう!
- publicリポジトリを作成し、
- 処理内容を公開できない場合
- 自作でき、メンテもできる処理の場合
- privateリポジトリ内に
action
を作成し、checkout
して使い回しましょう!
- privateリポジトリ内に
- 自作が大変 or メンテできない処理の場合
- 共通化はせずに、各
workflow
で定義しましょう
- 共通化はせずに、各
- 自作でき、メンテもできる処理の場合
- 処理内容を公開できる場合
privateリポジトリを多く使うユーザーの場合、基本的にactionを自分で作成・メンテするのは手間ですし、思ったより共通化できず何とももどかしい状況なのがわかると思います。
この状況はこれから変わっていくのでしょうか?
今後どうなっていくのか
github actionsの今後はロードマップとして公開されています。(下記のリンクはactions
でクエリしてあります)
追記(2022/08/04): リンク切れを修正しました
最も興味深いissueは、下記のActions: Organization and enterprise workflows です。複数リポジトリで実行可能なorganizationレベルでのworkflowを定義できるようにするもので、これまで見てきた諸問題を解決できるように見えます。
ただし、現時点で実装時期はfuture
とされており、いつ頃実装されるかわからないので気長に待つ必要があるでしょう。
ロードマップから逸れますが、Reusable workflow
がprivate organization内で使い回せない件についてcommunityでも少し話題になっているようです。 もしこのトピックに対してLikeが集まれば何かしらアクションがあるかもしれません。 (私もLikeしておきました)
追記(2022/08/04): リンク切れを修正しました
まとめ
- publicリポジトリに公開できる処理ならReusable workflowに寄せられそうです
- 公開できない処理のうち、自分で記述でき、かつメンテできそうな範囲であれば
action
単位で切り出してcheckoutして使いましょう - 上記に当てはまらないものは共通化するのは一旦待ちましょう...
最後に
明日もまだまだアドベントカレンダーは続くので楽しみにしてくださると嬉しいです!
また、MakuakeではエンジニアやPM、デザイナーを始めとしてほとんどの職種で採用中です!興味ある方は以下から見てみてください!
Discussion