情報の自動取得
GitHub Actionsのscheduleを本線にしない—外部cronで定時を保証する
Actionsのcronは遅延・スキップがあり得る。本線は外部cronからworkflow_dispatch。PAT最小権限と /dispatchesの判定基準。
「3時間おき」とYAMLに書いたのに、実ログでは数十分遅れたり、枠ごと未発火だったりします。GitHub公式もscheduleの遅延・スキップがあり得る前提で、保証ではありません。取り込みやPages更新をschedule一本にすると、「止まっているのか遅いのか」が分からず、気づく手段も弱いです。読み終わると、定時の本線を外部cron → workflow_dispatch に置き、失敗時の再実行と権限・APIパスまで合格/不合格で切れます。
この記事でわかること
- Actionsの
scheduleを本線にしない理由 - 外部cronから
workflow_dispatchを叩く合格条件 - PATの最小権限と
/dispatches(複数形)の切り分け - 作業前にAIへ渡す入力(貼り付け文)
状況
典型は次です。
1.ワークフローに cron: '0 */3 * * *' だけを書く
2.ある時刻枠が飛んだ/大幅に遅れた(例: 想定の定時付近にrunが無い)
3.「Actionsが壊れた」「権限が落ちた」と疑うが、YAMLは正しい
4.手動のRun workflowや gh workflow run ならすぐ動く
5.本線を外部の確実なcron(Workers Cron、cron-job.org、VPS crontabなど)に移し、同じworkflowを workflow_dispatch で起動する
scheduleは保険として残してよいです。本線と同時刻だと二重実行し得るので、安定したらschedule側を弱めるか止める判断が要ります。
失敗1:scheduleの文言を時刻保証だと思う
状況: YAMLのcron表現どおりに毎枠発火すると期待する。
悪い例: 「3時間おき」と書いてあるから、ログ上もほぼその時刻に残るはずだ、と切り分けを止める。
良い例: 公式どおり遅延・スキップがあり得る前提で、実時刻はActionsのrun一覧で確認する。飛ばても同じ入力で再実行できる経路がある。
合格条件: 「N時間おき」がログ上ほぼその時刻に残る、または飛ばても同じworkflowを外部/手動から再実行できる。
失敗2:定時が飛んでも再実行手段が無い
状況: scheduleだけ。権限者しかUIを知らず、API/CLIの起動が無い。
悪い例: 枠が飛んだら翌日まで待つ。失敗に気づく手段も無い。
良い例: workflow_dispatch 入力を用意し、外部cron(または gh workflow run)から同じ run_mode 等を渡せる。手動Run workflowでも同等。
合格条件: 失敗時に手動/外部から、同じworkflowを同じ入力で再実行できる。
失敗3:トークンをリポに直書きする/権限を盛りすぎる
状況: 外部からGitHub APIを叩くためにPATが要る。
悪い例: トークンをリポやガイド本文に平文で置く。何でも通るPATを1本にまとめる。
良い例: WorkerやcronサービスのSecretにだけ置く。privateならClassicは repo + workflow、Fine-grainedならActions R/Wに加えContents Read(無いと起動APIが404に見えることがある)。期限とローテーション方針がある。
合格条件: トークンは最小権限・Secret保管・ローテーション方針がある。リポ/チャットに平文が無い。
失敗4:RESTのパスを /dispatch のまま権限不足と誤診する
状況: gh workflow run は成功するのに、自前のPOSTやWorkerだけ404。
悪い例: トークンを何度も作り直して終わる。CLIが通るからWorkerも通ると決めつける。
良い例: 正は .../actions/workflows/{id}/dispatches(複数形)。単数 /dispatch は404。GH_DEBUG=api などでCLIが叩いたパスと突き合わせる。権限不足も404に見えることがあるので、パス確認のあとに権限を疑う。
合格条件: 404のとき「権限」と「URL/リソース名」を両方疑う。ドキュメントと代替cronの例も /dispatches に揃っている。
是正の手順(型)
- workflowに
workflow_dispatchと必要なinputsを足す(scheduleは保険で残してよい) 2.外部cronからGitHub APIの/dispatchesへPOSTする(Cloudflare Workers Cron、cron-job.org、VPSなど。無料本線の一例はWorkers) - Body例:
{"ref":"main","inputs":{"run_mode":"feeds"}}(入力名は自分のworkflowに合わせる) 4.スモーク: 外部から1回叩き、Actionsにworkflow_dispatchのrunが並ぶことを見る 5.二重実行が気になるなら、安定後にGitHub側scheduleを弱めるか止める
汎用のPOST形(OWNER/REPO/ワークフローファイル名は自分の環境に置き換え):
curl -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/OWNER/REPO/actions/workflows/ingest.yml/dispatches \
-d '{"ref":"main","inputs":{"run_mode":"feeds"}}'
または:
gh workflow run ingest.yml -f run_mode=feeds
作業前にAIへ渡す入力
AI向け:永続ルール(rules / AGENTS.md)
GitHub Actions の schedule(cron)は遅延・スキップがあり得る。定時の本線にしない。
本線は外部の確実な cron(Workers Cron/cron-job.org/VPS 等)から workflow_dispatch を叩く。
schedule は保険として残してよいが、本線と同時刻の二重実行に注意する。
外部起動用の PAT は Secret のみ。リポ/チャットに平文禁止。最小権限(private は Contents Read も疑う)。
workflow_dispatch の REST は /dispatches(複数形)。単数 /dispatch の 404 を権限不足だけと決めつけるな。
「定時が飛んだ」切り分けでは、YAML の文言ではなく Actions の実 run 時刻と、手動/外部からの再実行可否を先に確認する。
AI向け:この作業の開始時にチャットへ貼る文
定時取り込み/定時デプロイの本線を設計または是正する。
Actions の schedule だけに頼る案は不合格。外部 cron → workflow_dispatch の経路、再実行手段、PAT の保管と最小権限、API パスが /dispatches かを先に表で出せ。
実装・トークン再発行の前に、上記の合格/不合格を一文ずつ書け。秘密はチャットに貼るな。
人間向け
なし。上をAIに渡すだけでよい。
うまくいかないとき
| 症状 | 先に疑うこと |
|---|---|
| 401 / 403 | PATの期限・スコープ・対象リポ |
| 404 | URLが /dispatch(単数)になっていないか。privateならContents Read不足も404に見える |
| 外部は成功なのにActionsにrunが無い | リポのActionsが無効、workflow名/ID違い、ref 違い |
| 同じ時刻に二重実行 | GitHub scheduleと外部cronの両方。どちらかを止める/ずらす |
まとめ
- Actionsの
scheduleは「だいたいその時刻」であり、時刻保証ではない - 定時の本線は外部cron →
workflow_dispatch - 飛ばても同じ入力で再実行できること、が運用の合格線
- トークンはSecret・最小権限。RESTは
/dispatches - 作業前にAIへ渡す入力を残さないと、次の定時設計でschedule一本に戻る