GitHub ActionsでCIを設定する際、多くのチュートリアルで以下のような設定を見かけますが、実は両方指定する必要nないケースが多いです。
on:
push:
branches: ["**"]
pull_request:
branches: ["**"]
この記事では、なぜ両方指定する必要がないのか、どちらを選ぶべきかについて解説します。
問題点:重複実行が発生する
何が起こるか
push と pull_request の両方を指定すると、以下のような流れでCIが2回実行されることがあります:
-
featureブランチにコミットをプッシュ → CI実行(1回目) - そのブランチでプルリクエストを作成 → CI実行(2回目)
具体例
name: Rails CI
on:
push:
branches: ["**"] # すべてのブランチのプッシュで実行
pull_request:
branches: ["**"] # すべてのブランチへのPRで実行
この設定で以下の操作を行うと:
git checkout -b feature/new-function
git commit -m "新機能追加"
git push origin feature/new-function # ← 1回目のCI実行
# GitHubでPRを作成 # ← 2回目のCI実行(重複!)
解決策:pushのみで十分
推奨設定
name: Rails CI
on:
push:
branches: ["**"]
なぜpushのみで十分なのか
push トリガーだけで以下のすべてのケースをカバーできます:
- 開発ブランチでの作業 → プッシュ時にCI実行
- PR作成時 → すでにブランチでテスト済み
- PR更新時 → 追加コミットのプッシュでCI実行
- マージ時 → マージコミットのプッシュでCI実行
- mainブランチへの直接プッシュ → プッシュでCI実行
メリット
- ✅ 重複実行の回避 → CIリソースの節約
- ✅ シンプルな設定 → 管理が容易
- ✅ 一貫した動作 → どのブランチでも同じようにテスト実行
例外:用途別に使い分けるケース
場合によっては、異なる目的でトリガーを使い分けることもあります:
パターン1: mainブランチのみprotectedにする
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
-
push: mainブランチの品質保証 -
pull_request: PRのマージ前チェック
パターン2: 異なるジョブを実行する
name: CI
on:
push:
branches: ["**"]
pull_request:
branches: ["main"]
jobs:
test:
if: github.event_name == 'push'
# 全テストを実行
quick-check:
if: github.event_name == 'pull_request'
# 軽量なチェックのみ実行
実際のプロジェクトではどうなっている?
多くのOSSプロジェクトでは、以下のような設定が採用されています:
Ruby on Rails本体
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
多くの小〜中規模プロジェクト
on:
push:
branches: ["**"]
結論
一般的なプロジェクトでは push のみで十分です。
# 推奨設定
name: Rails CI
on:
push:
branches: ["**"]
jobs:
test:
runs-on: ubuntu-latest
# ... your CI steps
使い分けの指針
-
小〜中規模プロジェクト →
pushのみ - 大規模プロジェクト → 用途に応じて使い分け
-
mainブランチ保護が重要 →
pull_requestも併用
重複実行を避けて、効率的なCIパイプラインを構築しましょう!