GitHub Actions cronをJST運用する設定と誤デプロイ対策

GitHub Actionsの定時実行って、JSTで回したいだけなのにUTC換算メモを毎回見直して、地味に神経を使いますよね。2026年3月19日の更新で、cronにIANAタイムゾーンを直接指定できるようになりました。さらにdeployment: falseを組み合わせると、環境シークレットは使いながら誤デプロイだけを防げます。この記事では、非IT部門とも連携しながら運用している僕の視点で、今日から使える実装手順までまとめます。

公開前確認(2026年5月時点):GitHub ActionsのcronはUTC基準です。JST運用では混雑しやすい毎時0分を避け、遅延・スキップを前提に再実行手順と通知を用意してください。

こんな方におすすめ

  • GitHub Actions cron JST運用で、UTC換算ミスをなくしたい方
  • GitHub Actions タイムゾーン 設定を、チームで読みやすく管理したい方
  • stagingの環境シークレットは使いたいけど、デプロイ履歴は汚したくない方
  • 本番誤反映を避けるワークフロー設計を作りたい方

この記事でわかること

  • 2026年3月アップデートの要点と、何が楽になったのか
  • timezone: Asia/Tokyoへ安全に移行する具体手順
  • 高負荷遅延・既定ブランチ制約・60日停止・DSTを踏まえた運用ルール
  • deployment: falseでCIと本番デプロイ責務を分ける実務テンプレート
僕は福祉事業のIT全般を担当するCTOとして、複数環境のワークフロー運用と承認フロー設計を担当しています。並行してAI×SaaSの開発案件や受託も回しているので、時刻ズレと誤デプロイの事故コストには毎週向き合っています。

2026年3月更新の要点|GitHub Actionsの運用設計が変わった

まず押さえたいのは、今回の変更が「時刻指定」と「デプロイ責務分離」の2本立てだという点です。GitHub公式Changelog(2026-03-19)で、timezone対応とdeployment: false追加が同時に案内されました。つまり、今まで別々に悩んでいた「JST運用のズレ」と「CIジョブの履歴管理問題」を、同じタイミングで見直せるようになったということです。

結論として、GitHub Actions cron JST運用の実装コストは確実に下がりました。 以前はUTC換算の小ワザが必要でしたが、今は設定ファイルの可読性を保ったまま運用できます。

  • 更新日が明確 — 機能追加日は2026年3月19日で、仕様は公式ページに明示されています。
  • 運用の見通しが良いtimezone: Asia/Tokyoと書けば、JSTで読む人全員が同じ認識を持てます。
  • 責務分離がしやすいdeployment: falseで、検証ジョブは環境を使ってもデプロイ記録を作らずに済みます。
比較項目 従来(更新前) 2026年3月以降
JST 9:00実行 UTCへ手計算してcron記述 timezone: Asia/Tokyoを直書き
環境シークレット活用 使えるが履歴設計が複雑 deployment: falseで履歴を分離
運用ドキュメント 換算表の保守が必要 YAMLと同じ言葉で説明しやすい

僕がよく言う「異世界転生」視点で見ると、IT設定を非ITメンバーにも通じる言葉に翻訳しやすくなったのが大きいです。設定が読みやすいだけで、運用合意のスピードはかなり変わります。

GitHub Actions タイムゾーン 設定の実装手順|timezone: Asia/Tokyoへ移行

実装そのものはシンプルですが、移行の順番を間違えると実行時刻がズレます。なので最初に「いまのcronが何時を意図しているか」を棚卸ししてから置換するのがおすすめです。仕様はworkflow syntax公式ドキュメントにまとまっています。

  1. 既存cronの意図時刻を一覧化 — 例: 0 0 * * 1-5は「JST平日9:00」なのかを確認します。
  2. IANAタイムゾーンへ置換 — 目的時刻をそのままcronに書き、timezoneを追加します。
  3. 2週間だけ二重監視 — 旧ジョブログと新ジョブログを見比べ、ズレがないことを確認します。
# Before: UTC換算が必要
on:
  schedule:
    - cron: '0 0 * * 1-5' # JST 9:00をUTCで記述

# After: JSTを直接指定
on:
  schedule:
    - cron: '0 9 * * 1-5'
      timezone: 'Asia/Tokyo'

注意点として、scheduleの最短間隔は5分です。 検証用ジョブを1分刻みで増やす設計はできないので、最初は平日1回のように範囲を絞って確認するのが安全です。

以前のZennやQiitaでよく紹介されていたUTC換算トリックは、既存資産を読むときには今も役立ちます。ただ、新規で組むならIANAタイムゾーン直指定の方が読みやすく、引き継ぎコストも下げやすいです。つまり、個人の工夫ではなくチームの再現性で勝てる形になります。

“正確運用”の落とし穴|遅延・既定ブランチ制約・60日停止・DST

タイムゾーン対応で楽になった一方で、scheduleイベント特有の制約は残っています。ここを見落とすと「設定は合ってるのに実行されない」事故が起きます。詳細はevents公式ドキュメントに明記されています。

  • 高負荷遅延 — 毎時00分付近は遅延しやすく、条件次第でキュー済みジョブが落ちる可能性があります。
  • 既定ブランチ制約 — scheduleはデフォルトブランチ上の最新コミットのみ実行対象です。
  • 公開リポジトリの自動停止 — 60日活動がないとscheduleが自動無効化されます。
  • DSTの繰り上がり — 例として2:30 AMが3:00 AMへ繰り上がるケースがあります。

実務での回避ルール

  • 分0を避ける — 例: 17 9 * * 1-5 のようにオフセットします。
  • 監視を二段構え — 実行有無監視と遅延監視を分けて通知します。
  • DST地域はジョブ分離Asia/Tokyo運用ジョブと別workflowに分けると管理しやすいです。

「正しいcron式」だけでは足りず、「実行される前提条件」まで含めて設計するのが安定運用のコツです。 この視点があると、運用トラブルはかなり減らせます。

deployment: falseで誤デプロイを防ぐ|使える場面と非互換ポイント

deployment: falseは、環境を使うジョブに「デプロイ記録を作らない」意思を明示できる設定です。仕様はcontrol deployments公式にあります。stagingのスモークテストや負荷テストでは、この設定がかなり扱いやすいです。

jobs:
  smoke-test:
    runs-on: ubuntu-latest
    environment:
      name: staging
      deployment: false

ポイントは「環境シークレット・環境変数は使える」ことです。 その上でデプロイ履歴は増えないので、監査ログの意図がブレにくくなります。

運用パターン 環境シークレット デプロイ履歴 Wait timer/Required reviewers カスタム保護ルール
environment未使用 使えない 作られない 適用なし 適用なし
deployment: true 使える 作られる 適用される 利用可能
deployment: false 使える 作られない 適用される 非互換で失敗
補足です。deployment: falseでもWait timerとRequired reviewersは有効です。一方で、カスタムdeployment protection rule appを使っている環境ではジョブが失敗するので、その場合はdeployment: trueへ戻すか保護ルール設計の見直しが必要です。

「安全そうだから全部false」に寄せるのは逆効果になることがあります。 本番は履歴を残す、検証は履歴を残さない、という責務分離で使い分けるのが現実的です。

実務テンプレート|CIはdeployment: false、本番はtrueで分離する

ここまでの内容を、すぐ試せる形にまとめます。以下は「JSTの平日定時で検証ジョブを動かし、成功時だけ本番デプロイを通す」テンプレートです。分0を避けるために17分開始にしています。

name: scheduled-smoke-and-release

on:
  workflow_dispatch:
  schedule:
    - cron: '17 9 * * 1-5'
      timezone: 'Asia/Tokyo'

jobs:
  smoke-test:
    runs-on: ubuntu-latest
    environment:
      name: staging
      deployment: false
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run smoke

  deploy-production:
    needs: smoke-test
    if: github.ref_name == 'main' && needs.smoke-test.result == 'success'
    runs-on: ubuntu-latest
    environment:
      name: production
      deployment: true
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run deploy
  1. 先にstagingだけ有効化 — 1週間ログを見て、遅延や実行漏れを確認します。
  2. 次に本番ジョブを追加 — Required reviewersを設定し、承認フローを固定化します。
  3. 最後に運用ドキュメント更新 — 「JST直指定」「分0回避」「失敗時の再実行手順」を1ページ化します。

運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。

この更新を知らないまま1年運用すると何が起きるか

UTC換算のまま運用を続けると、引き継ぎ時に「このcronは何時想定なのか」がブラックボックス化しやすいです。さらに、scheduleの遅延特性や60日停止を知らないと、障害時に原因切り分けが遅れて復旧時間が伸びます。つまり、知らないままだと“たまに起きる不具合”が組織の信用コストに変わる可能性があります。 早めに設計を揃えておく価値は大きいです。

この記事を書いている理由

僕自身、2025年10月に結婚式Web招待状サービスを短期間でリリースして、90日以上ログイン継続率を維持する運用を続けてきました。リリース後は機能追加より「安定して予定通り動く仕組み」の価値が上がると、現場で何度も感じています。いまは福祉事業のIT全般を担当しつつ、Mac miniを24時間稼働させたNode.js/TypeScript運用も回しています。だからこそ、僕自身が時刻ズレと環境統制の難しさを経験して、同じ悩みを減らしたいと思ってこのテーマを書いています。

次のアクション

運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。

今日からできるアクション

  • 既存workflowのcronを棚卸しして、JST意図時刻をコメントに残す
  • timezone: Asia/Tokyoへ1本だけ移行して、1週間ログ比較する
  • stagingはdeployment: false、本番はtrueの方針を文書化する