actions/labeler とは
PRに自動でラベルを付与する便利なアクションです。ブランチパターンに基づいてラベルを付ける機能もあるため、リリースPRの管理に活用できます。
やりたかったこと
develop -> qa または qa -> main へのPRに、自動で release ラベルを付与したいと考えていました。つまり、以下の条件をOR結合したいということです。
(base=qa AND head=develop) OR (base=main AND head=qa)
最初の設定
release:
- all:
- base-branch: ['^(qa|main)$']
- head-branch: ['^(develop|qa)$']
正規表現の alternation(|)を使い、単一の all ブロックで両方のパターンをカバーしていました。
AIコードレビューによる指摘
この設定に対し、AIコードレビューツールから以下の指摘を受けた。
「この設定では develop -> main という意図しない組み合わせもマッチしてしまう。条件を分離し、明示的な組み合わせにするべき」
確かに論理的には正しい指摘です。base-branch と head-branch はそれぞれ独立して評価されるため、以下の全組み合わせがマッチしてしまいます。
| head \ base | qa | main |
|---|---|---|
| develop | ✅ develop→qa | ⚠️ develop→main |
| qa | - | ✅ qa→main |
ダメだった
AIの指摘に従い、論理的に厳密になるよう2つの all ブロックに分離しました。
release:
- all:
- base-branch: ['^qa$']
- head-branch: ['^develop$']
- all:
- base-branch: ['^main$']
- head-branch: ['^qa$']
一見、「条件1 OR 条件2」を記述しているように見えます。しかし、この設定に変更した途端、releaseラベルが付与されなくなりました。
原因
actions/labeler v6 のソースコードを確認すると、原因が判明しました。
トップレベルの設定項目(- all: や - any: の各ブロック)はすべてAND結合される仕様になっており、先ほどの2つの - all: ブロックは「両方のブロックを同時に満たす必要がある」と解釈されていました。
develop -> qa のPRの場合:
- ブロック1(base=qa, head=develop):✅ マッチ
- ブロック2(base=main, head=qa):❌ マッチしない
- 結果:false(両方同時にマッチしないため、ラベル付与なし)
正規表現パターンで妥協
actions/labeler の現在の仕様では、(A AND B) OR (C AND D) のような複合条件を、独立したブロックとして正確に表現する手段がありません。そのため、以下のように正規表現を用いて1つの all ブロックにまとめるのが最も現実的な対応となります。
release:
- all:
- base-branch: ['^(qa|main)$']
- head-branch: ['^(develop|qa)$']
この設定では develop -> main もマッチしてしまいますが、あくまでreleaseラベルを自動付与するためのアクションだったのでこれで妥協しました。