4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub Actionsの on: トリガー完全ガイド — 発火条件ごとに変わる context を理解する

Last updated at Posted at 2025-12-08

GitHub Actions は最初は「YAML を書けば動く」感覚で始められますが、本格的に活用しようとすると次のような壁にぶつかりがちです。

  • push と pull_request の両方で CI が走って二重実行される
  • PR では取得できた context が dispatch では null になる
  • schedule 実行時だけ条件式が成立しない
  • デプロイをどのトリガーで行うべきか定まらない

こうした問題に対して場当たり的にif:を増やしたり、workflow を分割して対処しようとすると、規模が大きくなり破綻する原因となります。
私がこの課題に取り組んで理解したのは、次の点が重要だということです。

トリガー(on)が変わると、workflow 内で扱える context(変数)が変わる

この関係を理解できると、条件式が整理され、workflow がシンプルになり動作も一気に安定します。 
この記事では、実務で頻繁に使う5つのトリガーに絞り「発火条件」「context」「実務での使いどころ」「よくある事故」を整理します。

この記事で扱う5つのトリガー

GitHub Actions には多くのトリガーがありますが、実務で頻繁に登場するものは限られています。
この記事では、網羅的なリファレンスではなく「現場で遭遇するものに絞って深掘りする」ことを目的として、次の5つを扱います。

push
pull_request
issue_comment
workflow_dispatch
schedule

ここから先のセクションでは、

  • そのトリガーが発火する条件
  • どのcontextがどのように変化するのか

という構成で、5種類それぞれを解説していきます。

① push

発火条件

pushは、ブランチまたはタグにコミットが到達したタイミングで発火します。
典型的な設定は次のようなものです。

on:
  push:
    branches:
      - main
      - develop
    paths:
      - src/**

発火タイミングを整理すると以下の通りです。

状況 発火有無
ローカルから main に push 発火
develop への push 発火
main へのマージ(PR merge) 発火
タグ作成 発火
draft PR の状態で push 発火(pull_request ではなく push 扱いのため)
リベースして force push 発火
pathsの対象外ファイルのみ変更して push 発火しない(paths フィルタに一致しないため)
fast-forward merge で main に新しい commit が載らなかった 発火しない(main にコミット到達が発生していないため)

push は CI の中心になる一方で、「PR merge でも push が走る」という点が pull_request と混同されやすいため、期待した動作をしないことがあります。

context の中身

pushcontextの特徴を端的に言うと「コミットおよびブランチの情報が中心で、PR 情報は含まれない」 です。

代表的なcontext値は次の通りです。

フィールド 値の例
github.event_name "push"
github.ref "refs/heads/main"
github.ref_type "branch" または "tag"
github.sha commit hash
github.event.head_commit.message コミットメッセージ
github.actor 実行ユーザー

PRとは違いgithub.event.pull_request.*は存在しません。
そのため、push で動かす Jobs に PR 固有の情報を期待するとnullになり落ちます。

② pull_request

発火条件

pull_requestは、PR のライフサイクルに応じて様々なタイミングで発火します。
代表的なtypesは以下の通りです。

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]

主要イベント(types)の動作を整理すると次のようになります。

イベント 発火タイミング
opened PR 作成時
synchronize PR に対する追加 push(コミット追加)
reopened PR 再オープン時
ready_for_review Draft → Ready に変更時
converted_to_draft Ready → Draft に変更時
closed PR がクローズしたとき(マージ含む)
merged closedの一種だが github.event.pull_request.merged が true

補足として、レビューコメント・ラベル追加・アサインなどではpull_requestは発火しません。
レビュー操作を契機にする場合はpull_request_targetまたはissue_commentを組み合わせます。

(補足)push との違い

pull_request では github.ref は head ブランチではなく refs/pull/<番号>/merge になることがある。

例:

  • PR の実体のブランチ: feature/foo
  • github.ref: refs/pull/123/merge

これは GitHub が自動生成する「マージコミット用の仮ブランチ」です。
これを知らずにgithub.refでブランチ名を判定しようとすると事故が起きます。

context の中身

pull_request は PR のメタデータ・差分情報を含んだ最も情報量の多いイベントです。

利用頻度の高い context を抜粋します。

フィールド 値の内容
github.event_name "pull_request"
github.event.pull_request.number PR 番号
github.event.pull_request.title PR タイトル
github.event.pull_request.user.login 作成者
github.event.pull_request.head.ref PR 元ブランチ名(例: "feature/foo"
github.event.pull_request.base.ref マージ先ブランチ名(例: "main"
github.event.pull_request.merged マージ済みかどうか(true/false)
github.event.pull_request.draft Draft かどうか
github.event.pull_request.labels ラベル一覧

③ issue_comment

発火条件

issue_commentは Issue・PR に対するコメントが投稿されたときに発火します。
名前的に「Issue 限定」と誤解されがちですが PR も対象です。

on:
  issue_comment:
    types: [created]

typesを指定しない場合、コメントの作成・編集・削除すべてで発火します。

context の中身

issue_comment の context は、pull_request や push とは全く異なる構造です。

特に重要な仕様として、github.event.issue.numberは「コメントした対象」の番号が入ります。

つまり、

  • Issue にコメント → Issue番号
  • PR にコメント → PR番号

となります。

フィールド 値の内容
github.event_name "issue_comment"
github.event.comment.body コメント本文
github.event.issue.number コメント対象の Issue/PR 番号
github.event.issue.pull_request 対象が PR の場合にのみ存在
github.event.comment.user.login コメント投稿者
github.actor 実行ユーザー(コメント投稿者になる場合が多い)

重要なのはgithub.event.issue.pull_requestの有無で
そのコメントが PR なのか Issue なのか判別できるという点です。

if: github.event.issue.pull_request != null

④ workflow_dispatch

発火条件

workflow_dispatchは手動実行用のトリガーです。
GitHub UI や API を通して、ユーザーが任意のタイミングでworkflowを実行できます。

最もシンプルな宣言は次の通りです。

on:
  workflow_dispatch:

実務では inputs を定義してパラメータ実行する形がよく使われます。

on:
  workflow_dispatch:
    inputs:
      environment:
        type: choice
        description: "Deploy target environment"
        options:
          - dev
          - stg
          - prod
        required: true

workflow_dispatchはシンプルな手動実行トリガーですが、本当の強みはinputsと組み合わせた選択式・パラメータ実行にあります。

context の中身

代表的な context は以下の通りです。

フィールド 値の内容
github.event_name "workflow_dispatch"
github.event.inputs 手動入力された値
github.ref 実行対象に選んだブランチ
github.sha 実行対象ブランチの最新コミット
github.actor 実行ユーザー

つまり、dispatch では push や pull_request と違い「どのコードに対して実行したいか」をユーザーが選択します。

⑤ schedule

発火条件

scheduleは cron 形式で 定期実行を行うトリガーです。

最も基本的な例は次の通りです。

on:
  schedule:
    - cron: "0 9 * * *"   # 毎朝9時 (UTC)

scheduleの実行は GitHub の負荷状況により 最大10分程度遅延する可能性があることが明記されています。
厳密な時刻保証は必要ない前提で設計すべきです。

context の中身

schedule の context は独特です。特に押さえるべき点は次の2つです。

  • github.refは常にデフォルトブランチ(例: refs/heads/main)になる
  • PR などの context は存在しない

代表的な context 値は次の通りです。

フィールド 値の内容
github.event_name "schedule"
github.ref refs/heads/main(固定)
github.sha デフォルトブランチの最新コミット
github.actor "github-actions"(ほぼ固定)

つまり schedule 実行は「main の最新コードに対して定期的に処理を行う」という仕様が標準です。
ここを理解していないとif:判定が期待通りに動かず、事故が発生します。

実務での設計パターン(レシピ集)

ここまで「トリガーごとの発火条件と context の中身」を見てきましたが、
実際の CI 設計では、この理解をベースに目的に応じて最適なトリガーを選ぶことが重要になります。

現場でよく使われる設計パターンを、最小構成のレシピ形式でまとめます。

パターン1:push は「変更検知用」、pull_request は「レビュー品質保証用」

push と pull_request を両方書くとどちらでも CI が走るため、役割分担が必須です。

push            → コード変更を検知してビルドや静的解析を走らせる
pull_request    → レビューでの品質確認に必要なテストのみ走らせる

メリット:

  • 二重実行や無駄な負荷が消える
  • PR のレビュー速度が上がる
  • PR のためのテストと本番想定のテストを分けられる

パターン2:デプロイは push ではなく workflow_dispatch に集約

開発初期は push での自動デプロイが便利ですが、チーム規模が大きくなるにつれ事故が起きやすくなります。

再現性・安全性を考えると、次のような整理が効果的です。

push/pull_request → CI(品質担保)
workflow_dispatch → CD(リリース)

メリット:

  • 誰が、いつ、どこにデプロイしたかが明確になる
  • デプロイの承認フローや環境指定がしやすい
  • ロールバックも対称設計で実装できる

パターン3:issue_comment でデプロイ承認・再実行フローを作る

コメントベースの運用を導入すると「レビュー → コメント → 実行」という流れが自然に定着します。

例:

/deploy stg
/deploy prod
terraform apply
terraform deploy

メリット:

  • 人の意思が入るべき処理を push や PR に寄せずに済む
  • PR の場で完結する
  • 権限や対象環境の扱いが柔軟

特に「PR レビュー者の一言でデプロイ可能」にしたい場合に適しています。

パターン4:schedule は「早期検知タスク」専用

schedule を push/PR と同じ扱いにするとCIが重くなり破綻します。
スケジュール実行用に軽めのタスクだけを切り出すのが現場で安定するパターンです。

例:

  • 毎朝ユニットテスト(外部依存の変化検知)
  • モノレポの依存パッケージ更新
  • CI 自己診断(期限切れ、キャッシュ肥大、stale ブランチ検出など)

ポイント:

  • main の最新コミットで実行されるため、PR テストとは役割が違う
  • 成果物がスパムにならないよう通知抑制設計が有効

まとめ

最適な CI/CD の鍵は 「どのトリガーで何をすべきか」 を明確に役割分担することです。

検知 検証 意思決定 定期
push pull_request workflow_dispatch / issue_comment schedule

「on を理解すると if が楽になる」

GitHub Actions の条件分岐はif:を使うのが基本ですが、
if:の書き方に悩む原因の多くは on の理解不足によって context が想定と違っていることです。

逆に言えば、

「どのトリガーのとき、どんな context が渡ってくるのか」

を理解できると、if:は驚くほどシンプルになります。

まず押さえるべき原則

if は「発火条件の補正」
on は「発火そのものを定義」

onが適切なら、if:はほとんど必要ありません。
誤解の典型例は以下のような書き方です。

on: push
jobs:
  build:
    if: github.event_name == 'push'

これは冗長です。onの段階で push に限定できているため if:は不要です。

使うべき if になるのは「on だけでは判断できない分岐」

具体例をトリガー別に整理します。

トリガー if が必要になる代表例
push ブランチによって振り分けたい場合
pull_request Draft かどうか、ラベル有無、PR タイトルなどで判定
issue_comment コメント本文や投稿者で分岐
workflow_dispatch inputs による振り分け
schedule 定期実行時だけ軽量ジョブにしたい、などの分岐

シンプルで強力な条件式の例

PR がマージされた場合だけ実行する

if: github.event_name == 'pull_request' && github.event.pull_request.merged == true

コメントで/deployと書かれた場合だけ実行する

if: github.event_name == 'issue_comment' && contains(github.event.comment.body, '/deploy')

手動実行でprodを指定した場合だけ実行する

if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'prod'

main ブランチへ push された場合だけ実行する

if: github.ref == 'refs/heads/main'

よくある事故と回避策まとめ

GitHub Actions で発生するトラブルの多くは、YAML 構文ミスでもジョブ設定ミスでもなく、「トリガーと context の誤解」から生まれます。

ここでは実務で特によく遭遇する事故を、原因と対策と合わせて整理します。

事故内容 原因 回避策
CIが二重実行される push と pull_request 両方でCIを走らせている トリガーの役割分担、if: github.event_nameで補正
PR merge で意図せずデプロイが走る merge → push の流れを考慮していない デプロイは dispatch/コメントに集約
PR番号を取得しているつもりで Issue番号になっている issue_comment の context を誤解 github.event.issue.pull_request != null判定でPRのみ処理
schedule 実行時に条件式が成立せず何も動かない github.refが常に main になる仕様を未理解 if: github.event_name == 'schedule'を併用
forkからのPRだけ落ちる secrets が渡らない仕様 権限が必要な処理は pull_request_target or コメント承認
デプロイの再実行で過去のコミットを参照してしまう dispatch の ref 指定が曖昧 入力でブランチ選択 or ref: refs/heads/main明記
コメントのたびに実行されて暴走 /deployなどの判定なし contains(comment.body, '/deploy')などの条件必須

まとめ

GitHub Actions は、YAML の書き方やテクニックより先に「on × context」を理解することで扱いやすくなります。

  • push/pull_request/dispatch/comment/schedule の役割を決める
  • context の違いを前提に設計する
  • on で切り、if で補正する

この3点が揃うと、条件式の爆発、workflow の増殖、予期せぬ実行などのトラブルが減り、運用が落ち着きます。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?