はじめに
GitHub Actionsでは、PushやPull RequestなどをトリガーとしてWorkflowを実行するだけではなく、指定した時間に定期実行することもできます。
定期実行は下記のような用途で利用できます。
- 毎日決まった時間にバッチ処理を実行する
- 定期的にAPIからデータを取得する
- 定期的にテストを実行する
- 定期的にIssueを作成する
- 定期的に依存関係などをチェックする
GitHub Actionsで定期実行すること自体は非常に簡単ですが、実際に利用する場合には「指定した時間ぴったりに実行されるとは限らない」など、いくつか知っておきたい仕様があります。
そこで今回は、GitHub Actionsで定期実行する方法と、実際に利用する際の注意点について整理していきます。
GitHub Actionsを定期実行する
GitHub Actionsでは、scheduleイベントを利用することでWorkflowを定期実行できます。
毎日9時に処理を実行する場合は、下記のように設定します。
name: Scheduled Workflow
on:
schedule:
- cron: '0 0 * * *'
jobs:
scheduled-job:
runs-on: ubuntu-latest
steps:
- name: Run
run: echo "Scheduled workflow"
scheduleでは、cron構文を利用して実行するタイミングを指定します。
cronとは?
cronでは、5つの値を使って実行するタイミングを指定します。
cronの構造を整理すると、下記のようになります。
┌───────────── 分(0 - 59)
│ ┌───────────── 時(0 - 23)
│ │ ┌───────────── 日(1 - 31)
│ │ │ ┌───────────── 月(1 - 12)
│ │ │ │ ┌───────────── 曜日(0 - 6)
│ │ │ │ │
* * * * *
毎日0時に実行する場合は、下記のように指定します。
0 0 * * *
それぞれの値を分解すると、下記のようになります。
分 0
時 0
日 *
月 *
曜日 *
よく利用するcronの指定を整理すると、下記のようになります。
| cron | 実行タイミング |
|---|---|
0 0 * * * |
毎日0時 |
0 0 * * 1 |
毎週月曜日の0時 |
0 0 1 * * |
毎月1日の0時 |
0 */6 * * * |
6時間ごと |
*/15 * * * * |
15分ごと |
GitHub Actionsでは、最短5分間隔で定期実行できます。
時刻には注意が必要
GitHub Actionsのscheduleは、タイムゾーンを指定しない場合はUTCを基準として実行されます。
日本標準時(JST)はUTCより9時間進んでいるため、日本時間の9時はUTCでは0時となります。
日本時間 9:00
│
▼
UTC 0:00
タイムゾーンを指定せず、日本時間の毎朝9時に実行する場合は下記のようになります。
on:
schedule:
- cron: '0 0 * * *'
現在のGitHub Actionsでは、タイムゾーンを明示的に指定することもできます。
日本時間の毎朝9時をタイムゾーンと合わせて指定する場合は、下記のようになります。
on:
schedule:
- cron: '0 9 * * *'
timezone: 'Asia/Tokyo'
日本時間を基準として運用するWorkflowであれば、タイムゾーンを明示した方が設定内容も理解しやすくなります。
指定した時間ぴったりに実行されるとは限らない
GitHub Actionsを定期実行する際に、特に知っておきたいのが実行時間のズレです。
日本時間の毎朝9時に実行する場合は、下記のように設定できます。
on:
schedule:
- cron: '0 9 * * *'
timezone: 'Asia/Tokyo'
この設定だけを見ると、毎朝9時ちょうどにWorkflowが開始されるように感じます。
しかしGitHub Actionsでは実行が集中して負荷が高くなっている場合、scheduleイベントの実行が遅延する可能性があります。
実際の実行イメージは下記のようになります。
cron
9:00
│
▼
実行予定
│
▼
GitHub Actionsが混雑
│
▼
9:03
9:08
9:15
...
│
▼
Workflow開始
cronで指定している時間は、「必ずその時刻に処理を開始する」という保証ではない点に注意が必要です。
毎時0分は避けた方が良い
GitHubの公式ドキュメントでは、高負荷になりやすい時間帯として毎時の開始時点が挙げられています。
下記のような時間帯です。
10:00
11:00
12:00
13:00
cronを設定する場合、下記のように0分を指定するケースも多いと思います。
cron: '0 * * * *'
多くのWorkflowが同じようにキリの良い時刻へ設定されることで、その時間帯に処理が集中する可能性があります。
実行時間を厳密に0分にする必要がなければ、下記のように少し時間をずらして設定できます。
cron: '7 * * * *'
17分に実行するのであれば、下記のようになります。
cron: '17 * * * *'
毎時0分から少しずらすことで、混雑による遅延を避けやすくなります。
遅延だけではなく実行されない可能性もある
GitHub Actionsの定期実行では、単純に実行時間が遅れるだけではない点にも注意が必要です。
GitHubの公式ドキュメントでは、GitHub Actionsの負荷が十分に高い場合、キューに登録されたジョブの一部がドロップされる可能性があると説明されています。
非常に単純化すると、下記のようになります。
schedule
│
▼
実行予定時刻
│
▼
GitHub Actionsが高負荷
│
├─ 遅れて実行
│
└─ 実行されない可能性
そのため、下記のような厳密なスケジューラーとして利用することには向いていません。
毎日9:00:00に
必ず処理を開始する
GitHub Actionsのscheduleは、指定した時間を基準として定期的にWorkflowを実行する仕組みとして考える必要があります。
定期実行する処理の設計も重要
実行時間が多少前後する可能性を考えると、Workflow内で実行する処理についても考える必要があります。
毎日9時に前日分のデータを取得するような処理であれば、多少実行が遅れても問題にならない場合が多いと思います。
毎日9時に実行
│
▼
前日分のデータを取得
9時になった瞬間に必ず処理を開始する必要がある場合は、GitHub Actionsのscheduleが適しているとは限りません。
9:00になった瞬間
│
▼
必ず処理を開始する
GitHub Actionsの定期実行は、下記のような用途として考える方が適しています。
指定した時間を基準として
定期的にWorkflowを実行する
万が一実行されなかった場合でも問題にならないよう、処理を再実行できる設計にしておくことも重要です。
デフォルトブランチで実行される
scheduleイベントでは、スケジュールされたWorkflowがデフォルトブランチの最新コミットに対して実行されます。
デフォルトブランチがmainの場合のイメージは、下記のようになります。
main
│
├─ 最新コミット
│ │
│ ▼
│ schedule実行
│
└─ 過去のコミット
Workflowファイル自体もデフォルトブランチに存在している必要があります。
別ブランチへWorkflowファイルを追加しただけでは定期実行されないため、Workflowを作成する際には注意が必要です。
長期間更新されていないリポジトリにも注意
パブリックリポジトリでは60日間リポジトリにアクティビティがない場合、スケジュールされたWorkflowが自動的に無効化されます。
更新頻度の低いリポジトリで定期実行だけを行っている場合は、下記のような状態になる可能性があります。
定期実行を設定
│
▼
リポジトリの更新なし
│
▼
60日経過
│
▼
scheduleが無効化
一度設定すれば永続的に動き続けるとは限らないため、定期バッチなどで利用する場合には注意が必要です。
手動実行もできるようにしておく
定期実行するWorkflowでは、workflow_dispatchも合わせて設定しておくと便利です。
scheduleと手動実行の両方に対応する場合は、下記のようになります。
name: Scheduled Workflow
on:
schedule:
- cron: '7 9 * * *'
timezone: 'Asia/Tokyo'
workflow_dispatch:
jobs:
scheduled-job:
runs-on: ubuntu-latest
steps:
- name: Run
run: echo "Scheduled workflow"
この設定では、下記の2つの方法でWorkflowを実行できます。
schedule
│
▼
自動実行
workflow_dispatch
│
▼
手動実行
定期実行が失敗した場合の再実行や、Workflowを作成した際の動作確認などにも利用できます。
定期実行で意識したいこと
ここまでの内容を整理すると、GitHub Actionsで定期実行する場合は下記を意識する必要があります。
- scheduleとcronを利用する
- タイムゾーンを意識する
- 最短実行間隔は5分
- 指定時刻ぴったりに実行されるとは限らない
- 毎時0分付近は混雑しやすい
- 高負荷時には実行されない可能性もある
- デフォルトブランチの最新コミットに対して実行される
- Workflowファイルはデフォルトブランチに存在する必要がある
- パブリックリポジトリでは60日間アクティビティがないと無効化される
- 必要に応じてworkflow_dispatchも設定する
設定自体は非常に簡単ですが、実際に運用する場合にはcronの書き方以外の仕様も理解しておくことが重要になります。
さいごに
GitHub Actionsの定期実行は、scheduleとcronを設定するだけで簡単に利用できます。
一方で指定した時刻に必ず実行されるわけではなく、GitHub Actionsの負荷によって遅延したり、場合によっては実行されなかったりする可能性があります。
定期実行を利用する際には設定方法だけではなくこうした特性も理解した上で、用途に合わせて利用していきたいです。