scheduleで定期実行するworkflowが動かないとき、手動実行が成功しているだけでは、schedule側も正常だとは判断できません。手動実行はworkflowのjobを動かす経路を確認できますが、cron条件に合うscheduleイベントがGitHub側で作成されたかまでは証明しないためです。最初に「予定時刻のイベントが作られていない」のか、「イベントは作られたがjobが開始されない・失敗した」のかを分けます。この分岐を飛ばしてrunnerやスクリプトを変更すると、原因のない修正を重ねることになります。
目次
まず確認する二つの状態
Actionsのworkflow run履歴を開き、対象workflowの実行一覧で発生時刻とイベント種別を見ます。手動実行の表示だけでなく、予定時刻付近にscheduleイベントのrunがあるかを確認してください。
-
schedule runがない:jobより前の条件を調べます。workflow定義が既定ブランチにあるか、scheduleが有効か、cronの時刻が合っているか、リポジトリの活動状況などが候補です。
-
schedule runがある:そのrunを開き、jobがqueued・skipped・cancelled・failedのどこで止まったかを追います。この場合はbranch/condition、権限、環境、runner、job内の処理へ進みます。
-
runの有無を判断できない:時間範囲を広げてworkflow名とevent種別を確認します。履歴が見当たらないことを、実行された証拠として扱わないでください。
この切り分けでは、workflowの手動実行を追加で何度も行うより、まず既存runのevent種別を記録するほうが有効です。runが存在しない状態と、runの中でjobが失敗した状態では、見るべきログも対処も異なります。
Scheduleがイベントを作る前に確認すること
1. workflowファイルが既定ブランチにあるか
GitHub Actionsのscheduleは既定ブランチ上のworkflowを対象にします。作業ブランチだけにworkflowファイルを置いている場合、そのブランチで手動実行を試せても、scheduleが同じ条件で作られるとは限りません。リポジトリの既定ブランチ名をSettingsで確認し、.github/workflows/内の対象YAMLがそのブランチに存在するかを見ます。
workflowの表示名だけでファイルを決めず、run詳細からworkflowファイル名と参照ブランチを記録してください。似た名前のworkflowが複数ある場合、別ファイルを調べていることがあります。
2. cronの構文と時刻
scheduleのcronは5フィールドのPOSIX cron形式です。たとえば30 2 * * 1-5は、指定タイムゾーンの平日2時30分を表します。現在のGitHub ActionsではtimezoneにIANAタイムゾーンを指定できます。未指定ならUTCです。日本時間の午前9時を意図しているのにUTCの午前9時として設定していないか、曜日・日付フィールドが意図と合っているか、YAMLのインデントや引用符を含めて確認します。
「毎月末」のような要件は、月の日数が一定でないため、単純な日付指定で期待した日に動くかを別途確認します。複数のcron行がある場合、各行の時刻を個別にJSTへ換算してください。曜日と日付の両方を指定した表現は、一般的なcronの感覚と違って見える場合があります。式を変更する前に、実行したい日時を具体的に3回ほど書き出し、各時刻が式に一致するか確かめると誤読を減らせます。
scheduleイベントはbest-effortです。GitHub Actionsの負荷が高い時間帯、とくに毎時ちょうど付近では遅延し、負荷が十分高いとqueued runがdropされることがあります。予定時刻にrunがないとき、数分の遅れを待つことはできますが、遅延を理由にrunner設定を変更してはいけません。次回も同じなら、予定時刻・実際にrunが見えた時刻・event typeを記録し、cronを毎時ちょうど以外へずらす案を検討します。
3. workflowやリポジトリが無効化されていないか
Actionsのworkflowが無効化されていると、triggerに応答しません。対象workflowのActions画面で無効化状態を確認します。また、公開リポジトリでは、リポジトリに60日間活動がない場合、scheduled workflowが自動的に無効化されることがあります。リポジトリの公開状態と活動状況、workflowの画面上の状態を確認してください。この条件に当てはまるか不明なら、リポジトリ設定を変更する前に管理者へ確認します。
runがある場合の診断
Jobがskippedの場合
runのイベントがscheduleであることを確認したら、各jobのif条件、branch filter、environment条件、必要なsecretやrepository variableの存在を見ます。scheduleは既定ブランチの最新commitで実行されるため、手動runで選んだブランチとコードが異なる場合があります。手動側だけに存在するファイルや設定を前提にしていないか、実際のrunのrefとcommit SHAで比較します。
Jobがqueuedまたはrunner待ちの場合
runが作成されているなら、schedule trigger自体は少なくともrun作成まで進んでいます。runnerラベル、利用可能なrunner、同時実行制限、concurrency設定、environment承認待ちを確認します。queuedのrunを見てすぐcronを変更すると、トリガーとは別の待ち行列問題を隠すことがあります。run詳細の状態、開始時刻、待機理由を先に記録してください。
Jobがfailedの場合
失敗したjobの最初の失敗stepから読みます。最後に見えるエラーだけでなく、前段で出力された権限拒否、入力不足、secret未設定、API応答、timeoutを確認します。手動runとschedule runで、branch/ref、入力値、actor、利用できる権限やsecretが同一とは限りません。ログへtoken、個人情報、機密値を貼り付けず、値そのものではなく「設定済みか」「どの条件で失敗したか」を記録します。
workflow_dispatch成功をどう解釈するか
workflow_dispatchを使った手動実行には、workflowを手動起動できる設定と、実行者のwrite権限が必要です。手動runが成功したことから分かるのは、その実行で選択されたref・入力・権限において、jobが動いたという範囲です。scheduleイベントが生成された、cronが正しく解釈された、あるいはschedule側の配信が毎回成功することまでは示しません。
比較するときは、run URL、event type、ref、commit SHA、入力値、job結果を並べます。schedule runが作られていないならrunnerやアプリコードのログを主因として追わず、workflow定義・既定ブランチ・有効状態・時刻条件から調べます。schedule runが存在するなら、そのrunのjobログへ進みます。これが最初の分岐です。
原因調査の記録テンプレート
再現や再調査に備えて、次の項目を1件の記録にまとめます。
-
Repositoryとworkflow名/ファイルパス
-
既定ブランチ名、対象workflowがそのブランチにあるか
-
Scheduleのcron式とtimezone
-
期待したJST時刻、確認した期間
-
Actions runの有無、event type、run URL
-
runのref、commit SHA、job状態
-
最初に失敗したstepとエラー分類(secret値は記録しない)
-
workflowの有効状態、公開/非公開、最近のrepository活動の有無
-
次に確認する項目と、変更した場合の日時
この記録があれば、次の確認者は「スケジュールが発火しない」という曖昧な報告ではなく、どの段階を通過し、どこで止まったかを追えます。個人アカウントやorganizationの内部設定を推測せず、画面で確認できた事実と未確認の条件を分けてください。
原因ごとの次の一手
schedule runがない場合は、まず既定ブランチ上のworkflow定義、on.scheduleのcronとtimezone、workflowの有効状態、リポジトリ活動条件を確認します。次に予定時刻の負荷・遅延を考慮して、毎時ちょうどを避けた次の観測時刻を記録します。複数の予定時刻を一度に変えず、変更前の式、変更理由、次に確認するrunを残してください。イベントがない段階でrunnerのラベルやjobのスクリプトを変更する根拠はありません。
schedule runがある場合は、jobの状態に沿って処理します。skippedなら条件式とref、queuedならrunner・concurrency・承認待ち、failedなら最初の失敗stepを確認します。手動runとの差は同じcommit・refか、同じ入力か、同じ権限・environmentかで比較します。必要な権限を広げる前に、失敗した操作と現在の権限差を特定します。
runが見えず、設定も期待どおりに見える場合、利用者側の表示だけではイベントが作られなかった理由を確定できません。次の予定時刻でもrun URLと時刻を記録し、必要ならGitHub Supportへ照会します。Supportに渡す情報はrepositoryの公開状態、workflowファイルパス、cron/timezone、予定時刻と観測時刻、runが見つからなかった検索条件です。token、secret、非公開の業務データは添付しません。Community投稿は症状の参考にはなりますが、個別repositoryの原因を確定する公式根拠として扱わないでください。
変更前後の安全確認
原因を切り分ける前に、scheduleの時刻・権限・runner・workflow条件をまとめて変えないでください。複数の変更を同時に行うと、どの変更で結果が変わったのか分からなくなります。調査中は現在のYAML、workflowの有効状態、run履歴を保存し、変更が必要なら一つの仮説に対して一つの差分を適用します。再現しなかった場合も、成功と断定せず、観測した期間・cron・event typeを残します。
手動runを定期実行の代替として運用する必要がある場合は、担当者、実行時刻、対象ref、入力、実行結果を別途記録します。手動runを追加するだけではscheduleの問題は解消しません。重要な処理で実行欠落が許されないなら、scheduled eventだけに依存する設計で要件を満たせるか、通知や再実行の仕組みを別途検討します。その設計判断は、既存workflowの権限や費用、失敗時の影響を確認してから行ってください。
公式情報と適用範囲
GitHub DocsのWorkflow syntaxはscheduleのcron形式、既定タイムゾーン、既定ブランチでの実行、timezone指定を説明しています。Events that trigger workflowsはscheduleの遅延・高負荷時のdrop、公開リポジトリで60日活動がない場合の自動無効化を説明しています。Troubleshooting workflowsは高負荷時の遅延と、手動実行が動いてもscheduled workflowが止まる場合の確認を案内しています。これらはGitHub Actionsの一般仕様です。個別repoの公開状態、workflow無効化、実際のevent生成、権限・runnerの状態は、対象repoの画面とrun履歴で別に確認してください。
次にすること
-
対象workflowの既定ブランチ上のファイルを開く。
-
scheduleのcron・timezoneをJSTに換算し、予定時刻を記録する。
-
Actions履歴でその時刻のrunとevent typeを探す。
-
runがないならtrigger前の条件へ、runがあるならjob状態へ進む。
-
確認できた証拠と未確認項目を残し、仮説を一つずつ検証する。
手動実行が成功したという事実だけで、scheduleの原因をrunnerやスクリプトへ結び付けないでください。まず予定されたイベントが存在するかを確認することが、最短の診断になります。
公式Sources
-
GitHub Docs, Workflow syntax: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax(新しいタブで開く)
-
GitHub Docs, Events that trigger workflows: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows(新しいタブで開く)
-
GitHub Docs, Troubleshooting workflows: https://docs.github.com/en/actions/how-tos/troubleshoot-workflows(新しいタブで開く)
-
GitHub Docs, Manually running a workflow: https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow(新しいタブで開く)
Checked: 2026-10-15
Editorial Note: 公式Docsを根拠にした診断ガイド。対象repositoryでの実行検証は行っていない。Community discussionは公式根拠に使っていない。
