🐙

[GitHub Actions]とりあえず常に成功するjobが欲しいときのプラクティス

2023/07/27に公開

背景

ブランチプロテクションルールで、特定の名前のジョブのCIが成功していることを必須にすることがある。
https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-status-checks-before-merging

その場合、GitHubはそういったジョブはpath filteringとか設定はしないことをおすすめするよって言っていた(最近このページ削除されたので過去のスナップショットを貼っておく)
https://docs.github.com/en/enterprise-server@3.7/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks

これ、モノレポだと結構相性が悪くて、たとえば、 Required Job って名前のjobを Status checks that are required. に登録しているとすると、

awesome-repo/
  ┣ backend/  // ここをいじったときに走らせたいCIと、
  ┣ frontend/ // ここをいじったときに走らせたいCIは違うし、
  ┗ README.md // でもここをいじったらRequired Jobが走らないとマージできないので走らせたい

ということが起こる。
幸いにも、同名のjobは複数登録できる。
なので、backendをいじったときとfrontendをいじったときのCIにも同名のjobを設定すればそれぞれマージにステータスチェックを必須にすることができる。
また、複数のrequired before mergeな同名jobが動いている場合、そのすべてのjobが成功しないとマージ可能にはならないのでこれもいい感じである。

ここで1つ残っている問題がある。上記の例でいくと、awesome-repo/README.mdだけいじった時にとりあえずRequired Jobが実行されて欲しいのだ。

これ、とりあえずechoだけするとかで常に成功するjobを作っているのをたまに見かけるが、それだと1secは毎回かかるはずで、そうすると毎回1minのGitHub Actionsのクレジットを消費しているはずで割と無駄だったりする。
もっといい方法でとりあえず成功するjobを作ることができるという話です。

what

ものとしてはこんな感じ。
ポイントとしては、すべてのstepがskipされたjobはSuccessfulとして扱われるという点。
これを使えば0secでjobが終了するためクレジットを消費を抑えつつ、とりあえず常に成功するjobをGitHub Actionsに登録できる。

on:
  pull_request:
    types: [ opened ]

jobs:
  required-job:
    name: Required Job
    runs-on: ubuntu-latest
    timeout-minutes: 1
    if: false
    steps:
      - name: skip Required Job
        run: echo "とりあえずRequired JobというジョブをSuccessfulにするためのダミーのジョブです。"

Discussion