GitHub Actions を使っているとこんなことありますよね。
- このフォルダー配下の変更があったときだけ特定の Actions を動かしたい
- このファイルの変更されたときは、あの Actions は動かしたくない
これを実現するのが、paths
または paths-ignore
のフィルターです。
慣れてないと公式ドキュメントでは探しにくいせいか、この機能が認知されてないと感じることがよくあるのでまとめていきます😊
ブログのタイトルいまいちやなぁと思いながら書き始めました... paths って知らないとこんなんでググるかなぁとか思ったり、いやなんか違うやろと思ったり...
最初に知っておきたいこと
細かいこと抜きにとりあえず知っておきたいことは...
特定のファイル・フォルダーで GitHub Actions のトリガーを制御するには、paths
または paths-ignore
を使って定義することができます。
paths
: ファイルやフォルダーを指定することで GitHub Actions のトリガーを制御することができます。無視する定義も可能です。無視する定義のみの定義はできません。paths-ignore
: 無視する定義のみをする場合はこっちを使います。
あとは、「 paths
と paths-ignore
の2つを1つのワークフローで一緒に使うことはできない」ということくらいです。
ユースケースのイメージとしては、
- ファイル・フォルダーで、フィルターしたいものと無視したいものが混在する場合は
paths
を使う
例: モノレポでフロントエンドとバックエンドのコードがあるので、フロントエンドの変更があった場合はフロントエンド用の Actions のみを起動したい。ルートの README.md の変更時は Actions を起動させない - 無視したいファイル・フォルダーのみの場合は、
paths
を使ってもいいしpaths-ignore
を使ってもいい:
例...書くほどでもないですよね。
Paths フィルターの使い方
基本
GitHub Actions の Trigger (on
) の定義で、events (push
や pull_request
など) の一段下で paths
を定義します。branchs とかと同じインデントです。
frontend
フォルダ配下の変更は全て含める、ルートにある README.md を無視するにはこんな書き方です。
on: push: branches: - main paths: - 'frontend/**' - '!README.md'
paths
の中で無視したい場合は先頭に !
を付けます (上のサンプルの !README.md
)。
ワイルドカードなどの正規表現
上のサンプルでも使ってますが、frontend
フォルダ配下の変更は全て含める場合はワイルドカード **
を使って定義できます。
ワイルドカードで私的に最初に覚えておきたいのはこの2つ。
**
は、すべての文字列のワイルドカードとなります (0文字でも対象) 。'frontend/**'
と定義することでfrontend
フォルダーの配下全てが対象になります。*
だと/
はマッチしないので、つまりはそのフォルダの直下のみのワイルドカードになります (0文字でも対象) 。
他に使える正規表現は、以下の公式ドキュメントが参考になります。
Tips
順番は大事
書く順番も大事で、基本的には後に書いた方が強くなります。
具体的な例として、以下のようなフォルダー構成だったとします。
root ├ 📁 dir1 │ ├ README.md │ ├ index.js │ ├ test.css │ └ ... └ 📁 dir 2 └ ...
dir1
フォルダ配下の変更はトリガーに含めたいけど、dir1/README.md
の変更だけは無視したい場合、以下のように書くのが正解です。後に書いた方が強いので「dir1 フォルダー配下を含める ( dir1/**
)」→「dir1 直下の README.md は無視する ('!dir1/README.md')」という流れです。
# 正しい例 on: push: branches: - main paths: - 'dir1/**' - '!dir1/README.md'
これを以下のように反対に書くと、2つ目に書いた「dir1 フォルダー配下を含める ( dir1/**
)」定義が強いので、最初に書いた「dir1 直下の README.md は無視する ('!dir1/README.md')」定義が打ち消されます。
# ダメな例 on: push: branches: - main paths: - '!dir1/README.md' # これだとあかん! - 'dir1/**'
ということで順番には注意しましょう。
無視する定義だけしたけど Actions が全く動かない?!
前述してますが公式ドキュメントにも書いてある通り、paths
の中で無視する定義のみをすることはできません。この場合、何を変更しても何をしても Actions は動きません (←2022年4月時点での動作確認)。
無視したいファイルだけを定義したい場合は paths-ignore
を使いましょう。
たまにフィルターされない?!
Actions の yml が正しければおかしくなることはないです。が、突然ある日フィルターされず動かない・想定外に動く可能性は無きしもあらずです。その原因として2つ、1000 コミットより多い場合と diff のファイルが 300 までという制限です。
まぁ、私は遭遇する気がしないので気にしないでおきますが、正確な内容は公式ドキュメントは以下で書かれています。
paths-ignore フィルターの使い方
基本的な書き方は paths
と一緒なのでもう書くことはないですが、こんな感じで使えます。
on: push: branches: - main paths-ignore: - 'docs/**'