情報の自動取得

GitHub Actionsのscheduleを本線にしない—外部cronで定時を保証する

Actionsのcronは遅延・スキップがあり得る。本線は外部cronからworkflow_dispatch。PAT最小権限と /dispatchesの判定基準。

「3時間おき」とYAMLに書いたのに、実ログでは数十分遅れたり、枠ごと未発火だったりします。GitHub公式もscheduleの遅延・スキップがあり得る前提で、保証ではありません。取り込みやPages更新をschedule一本にすると、「止まっているのか遅いのか」が分からず、気づく手段も弱いです。読み終わると、定時の本線を外部cron → workflow_dispatch に置き、失敗時の再実行と権限・APIパスまで合格/不合格で切れます。

この記事でわかること

状況

典型は次です。

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 に揃っている。

是正の手順(型)

  1. workflowに workflow_dispatch と必要な inputs を足す(scheduleは保険で残してよい) 2.外部cronからGitHub APIの /dispatches へPOSTする(Cloudflare Workers Cron、cron-job.org、VPSなど。無料本線の一例はWorkers)
  2. 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 / 403PATの期限・スコープ・対象リポ
404URLが /dispatch(単数)になっていないか。privateならContents Read不足も404に見える
外部は成功なのにActionsにrunが無いリポのActionsが無効、workflow名/ID違い、ref 違い
同じ時刻に二重実行GitHub scheduleと外部cronの両方。どちらかを止める/ずらす

まとめ

参考リンク