1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

開発停止した GitHub リポジトリで失敗し続ける定期実行を止める:GitHub Actions の基礎から確認・停止まで

1
Last updated at Posted at 2026-06-18

はじめに

AIを使った開発をしていると GitHubリポジトリが増えがちです。開発が止まった GitHubリポジトリを放置していると、GitHub Actions の定期実行が残り続けることがあります。

典型例は次のような workflow です。

  • Security Audit
  • Security Scanning
  • Dependency Security Check
  • Docker Security Scan
  • Monitoring
  • Benchmark

これらは開発中は有用ですが、開発停止後は依存関係、Secrets、外部サービス、Docker image、クラウド権限などが古くなり、毎日失敗通知を出すだけのノイズになることがあります。

この記事では、GitHub Actions の基礎から、定期実行の確認、停止、停止確認までを整理します。

この記事で分かること

  • GitHub では何が自動実行されるのか
  • GitHub Actions の workflow / event / job / step / runner の関係
  • schedule による定期実行の仕組み
  • gh コマンドで scheduled workflow を確認する方法
  • workflow を停止する方法
  • schedule だけを削除する方法
  • run 履歴ベースの確認で見落とすケース
  • 開発停止リポジトリの棚卸し用スクリプト

前提

この記事では GitHub CLI を使います。

gh --version
gh auth status

認証していない場合は以下でログインします。

gh auth login

以降の例では、リポジトリ名は OWNER/REPO の形式で表記します。

OWNER/REPO
例: octocat/example

1. GitHub の自動実行の中心は GitHub Actions

GitHub Actions は、GitHub 上のイベントを契機に処理を自動実行する仕組みです。

主な用途は以下です。

分類
CI push / Pull Request ごとの lint、test、build
CD main merge 後の staging / production deploy
セキュリティ CodeQL、依存関係監査、Docker image scan
品質管理 coverage、静的解析、型チェック
運用 定期 health check、監視、レポート生成
リポジトリ管理 Issue ラベル付け、古い Issue の close
外部連携 外部サービスから API 経由で workflow 起動
再利用 共通 workflow を複数 repo から呼び出す

GitHub Actions の設定ファイルは、通常リポジトリ内の以下に置きます。

.github/workflows/*.yml
.github/workflows/*.yaml

1 つのリポジトリに複数の workflow を置けます。

2. GitHub Actions の基本構造

GitHub Actions は、次の構造で理解すると分かりやすいです。

event
  ↓
workflow
  ↓
workflow run
  ↓
job
  ↓
step
  ↓
action または shell command

用語を整理します。

用語 意味
workflow 自動化処理の定義。.github/workflows/*.yml に書く
event / trigger workflow を起動する契機
workflow run workflow が 1 回実行された履歴
job workflow 内の実行単位
step job 内の処理単位
action 再利用可能な処理部品
runner job を実行する環境
artifact 実行結果として保存するファイル
secret / variable workflow に渡す機密情報・設定値

最小構成の例です。

name: CI

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source
        uses: actions/checkout@v4

      - name: Run tests
        run: |
          npm ci
          npm test

この workflow は以下で起動します。

  • main branch への push
  • Pull Request
  • 手動実行

3. workflow を起動する event

GitHub Actions の on: に指定するものが event です。

代表的なものは以下です。

event いつ動くか 用途
push commit が push されたとき 通常の CI
pull_request PR 作成・更新時 PR 検証
release release 作成・公開時 package publish / deploy
schedule cron による定期実行 定期 scan / 定期監視
workflow_dispatch 手動実行 任意タイミングの実行
repository_dispatch GitHub API 経由の外部 trigger 外部システム連携
workflow_run 他 workflow の実行後 workflow chaining
workflow_call 他 workflow から呼び出し reusable workflow

この記事で問題にしているのは schedule です。

4. schedule による定期実行

schedule は cron 形式で workflow を定期実行します。

例:

name: Security Audit

on:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm audit

cron の形式は次の 5 フィールドです。

┌───────────── minute: 0-59
│ ┌───────────── hour: 0-23
│ │ ┌───────────── day of month: 1-31
│ │ │ ┌───────────── month: 1-12
│ │ │ │ ┌───────────── day of week: 0-6
│ │ │ │ │
0 0 * * *

0 0 * * * は毎日 0:00 の意味です。

GitHub Actions の scheduled workflow では、デフォルトの時刻は UTC です。現在の GitHub Actions では、必要に応じて timezone も指定できます。

on:
  schedule:
    - cron: "30 5 * * 1-5"
      timezone: "Asia/Tokyo"

なお、scheduled workflow は default branch 上の workflow file を対象に動作します。

5. 開発停止リポジトリで scheduled workflow が問題になる理由

開発が止まったリポジトリでは、次の理由で scheduled workflow が失敗しやすくなります。

  • 依存パッケージが古くなる
  • lock file が現行 registry と合わなくなる
  • Docker image が消える、または脆弱性検出で落ちる
  • GitHub Secrets が失効する
  • 外部 API token が失効する
  • クラウド側の権限やリソースが消える
  • テスト前提のサービスが動いていない
  • セキュリティ scanner の仕様が変わる
  • ベンチマークや監視対象がなくなる

この状態で schedule が残っていると、毎日または毎週、同じ失敗通知が発生します。

運用上の判断として、開発停止リポジトリでは次のどちらかを選ぶことになります。

方針 内容
workflow 全体を止める gh workflow disable で停止
定期実行だけ止める YAML から on.schedule を削除

6. まず run 履歴を見る

過去に schedule で動いていたかを確認します。

gh run list -R OWNER/REPO --event schedule --limit 20

例:

gh run list -R octocat/example --event schedule --limit 20

出力例:

STATUS  TITLE              WORKFLOW           BRANCH  EVENT     ID           ELAPSED  AGE
X       Security Scanning  Security Scanning  main    schedule  12345678901  53s      about 4 hours ago
X       Security Scanning  Security Scanning  main    schedule  12345678902  58s      about 1 day ago
X       Security Scanning  Security Scanning  main    schedule  12345678903  53s      about 2 days ago

EVENTschedule なら、定期実行で起動した run です。

複数リポジトリを見る場合:

repos=(
  "OWNER/REPO1"
  "OWNER/REPO2"
  "OWNER/REPO3"
)

for repo in "${repos[@]}"; do
  echo "== $repo =="
  gh run list -R "$repo" --event schedule --limit 20
done

7. run 履歴から workflow ID を取得する

停止するときは workflow 名より workflow ID を使う方が安全です。

理由は、同じ名前の workflow が複数存在することがあるためです。

gh run list \
  -R OWNER/REPO \
  --event schedule \
  --limit 100 \
  --json workflowDatabaseId,workflowName \
  --jq '.[] | select(.workflowDatabaseId != null) | [.workflowDatabaseId, .workflowName] | @tsv' \
| sort -u

出力例:

165629470       Test Suite
165641572       Security Audit
169535038       Security Audit
171484537       Optimized CI/CD Pipeline

ここで Security Audit が 2 件あります。名前ではなく ID で止めるべき理由が分かります。

8. run 履歴だけでは不十分

ここが重要です。

gh run list --event schedule は、あくまで「過去に実行された run の履歴」を見ています。

次のような workflow は見落とす可能性があります。

  • YAML に schedule: はあるが、まだ実行履歴がない
  • 最近は失敗していないが、将来実行される scheduled workflow
  • run 履歴の取得件数に入らなかった workflow
  • 一度も完走していない、または別の理由で履歴確認から漏れた workflow

したがって、正確には active workflow の YAML を確認して schedule: が残っていないかを見る 必要があります。

9. active な scheduled workflow を検出する

以下は、複数リポジトリに対して active workflow の YAML を確認し、schedule: が残っているものを出力するスクリプトです。

repos=(
  "OWNER/REPO1"
  "OWNER/REPO2"
  "OWNER/REPO3"
)

for repo in "${repos[@]}"; do
  echo "== $repo =="

  gh workflow list -R "$repo" --all --limit 1000 --json id,name,path,state \
    --jq '.[] | select(.state == "active") | [.id, .name, .path] | @tsv' |
  while IFS=$'\t' read -r id name path; do
    yaml="$(gh workflow view "$id" -R "$repo" --yaml 2>/dev/null || true)"
    yaml_without_comments="$(printf '%s\n' "$yaml" | sed 's/[[:space:]]*#.*$//')"

    if printf '%s\n' "$yaml_without_comments" | grep -Eq '(^|[[:space:]{,])schedule[[:space:]]*:'; then
      printf 'ACTIVE schedule remains: repo=%s id=%s path=%s name=%s\n' \
        "$repo" "$id" "$path" "$name"
    fi
  done
done

出力例:

== OWNER/REPO1 ==
ACTIVE schedule remains: repo=OWNER/REPO1 id=171172891 path=.github/workflows/enhanced-security-scanning.yml name=.github/workflows/enhanced-security-scanning.yml
ACTIVE schedule remains: repo=OWNER/REPO1 id=171233734 path=.github/workflows/monitoring-observability.yml name=.github/workflows/monitoring-observability.yml
== OWNER/REPO2 ==

ACTIVE schedule remains: が出たものは、まだ active 状態で定期実行が残っています。

注意点として、この検出は実務向けの簡易検出です。YAML を厳密に parse したい場合は yq などを使ってください。ただし、通常の GitHub Actions workflow 棚卸しではこの程度でも十分に役立ちます。

10. workflow を停止する

workflow ID が分かっている場合は、次で止めます。

gh workflow disable WORKFLOW_ID -R OWNER/REPO

例:

gh workflow disable 171172891 -R OWNER/REPO
gh workflow disable 171233734 -R OWNER/REPO

停止後、--all を付けて確認します。

gh workflow list -R OWNER/REPO --all

期待する状態:

NAME                                              STATE              ID
.github/workflows/enhanced-security-scanning.yml  disabled_manually  171172891
.github/workflows/monitoring-observability.yml    disabled_manually  171233734

disabled_manually になっていれば手動停止済みです。

11. workflow disable の注意点

gh workflow disable は、schedule だけを止めるコマンドではありません。

workflow 全体を止めます。

たとえば次の workflow があるとします。

on:
  push:
  pull_request:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:

この workflow を gh workflow disable すると、以下すべてが止まります。

  • push
  • pull_request
  • schedule
  • workflow_dispatch

開発停止リポジトリなら問題になりにくいですが、まだ保守しているリポジトリでは注意が必要です。

12. 定期実行だけ止める場合

CI は残したいが、定期実行だけ止めたい場合は YAML を編集します。

変更前:

on:
  push:
    branches: [main]
  pull_request:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:

変更後:

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

完全に手動実行だけ残すなら:

on:
  workflow_dispatch:

この方法なら、workflow 自体は active のままですが、cron による定期実行は止まります。

13. 複数リポジトリの scheduled workflow を一括停止する

開発停止リポジトリ群で、active な scheduled workflow をまとめて止めたい場合のスクリプトです。

まずは dry-run で確認します。

#!/usr/bin/env bash
set -euo pipefail

repos=(
  "OWNER/REPO1"
  "OWNER/REPO2"
  "OWNER/REPO3"
)

apply="${APPLY:-0}"

for repo in "${repos[@]}"; do
  echo "== $repo =="

  gh workflow list -R "$repo" --all --limit 1000 --json id,name,path,state \
    --jq '.[] | select(.state == "active") | [.id, .name, .path] | @tsv' |
  while IFS=$'\t' read -r id name path; do
    yaml="$(gh workflow view "$id" -R "$repo" --yaml 2>/dev/null || true)"
    yaml_without_comments="$(printf '%s\n' "$yaml" | sed 's/[[:space:]]*#.*$//')"

    if printf '%s\n' "$yaml_without_comments" | grep -Eq '(^|[[:space:]{,])schedule[[:space:]]*:'; then
      if [[ "$apply" == "1" ]]; then
        echo "disable: $repo / $id / $path / $name"
        gh workflow disable "$id" -R "$repo"
      else
        echo "would disable: $repo / $id / $path / $name"
      fi
    fi
  done
done

dry-run:

bash disable-scheduled-workflows.sh

実行:

APPLY=1 bash disable-scheduled-workflows.sh

14. 停止確認

一括停止後、再度 active workflow に schedule: が残っていないか確認します。

repos=(
  "OWNER/REPO1"
  "OWNER/REPO2"
  "OWNER/REPO3"
)

for repo in "${repos[@]}"; do
  echo "== $repo =="

  gh workflow list -R "$repo" --all --limit 1000 --json id,name,path,state \
    --jq '.[] | select(.state == "active") | [.id, .name, .path] | @tsv' |
  while IFS=$'\t' read -r id name path; do
    yaml="$(gh workflow view "$id" -R "$repo" --yaml 2>/dev/null || true)"
    yaml_without_comments="$(printf '%s\n' "$yaml" | sed 's/[[:space:]]*#.*$//')"

    if printf '%s\n' "$yaml_without_comments" | grep -Eq '(^|[[:space:]{,])schedule[[:space:]]*:'; then
      printf 'ACTIVE schedule remains: repo=%s id=%s path=%s name=%s\n' \
        "$repo" "$id" "$path" "$name"
    fi
  done
done

何も出なければ、active 状態の scheduled workflow は残っていません。

出力例:

== OWNER/REPO1 ==
== OWNER/REPO2 ==
== OWNER/REPO3 ==

これは正常です。

15. 翌日確認

gh workflow disable をしても、過去の run 履歴は残ります。

そのため、次のような表示が残っていても異常ではありません。

X       Security Audit  Security Audit  main  schedule  12345678901  1m33s  about 1 day ago

見るべきなのは、停止後の時刻より新しい schedule run が増えていないかです。

for repo in "${repos[@]}"; do
  echo "== $repo =="

  gh run list \
    -R "$repo" \
    --event schedule \
    --limit 10 \
    --json createdAt,status,conclusion,workflowName,databaseId,url \
    --jq '.[] | [.createdAt, .status, .conclusion, .workflowName, .databaseId, .url] | @tsv'
done

停止後より新しい createdAt の run がなければ、定期実行は止まっています。

16. UI から止める方法

GitHub の Web UI でも停止できます。

Repository
  → Actions
  → 左側の workflow を選択
  → 右上の「...」
  → Disable workflow

少数の workflow だけ止めるなら UI でも十分です。

複数リポジトリを棚卸しする場合は、gh コマンドの方が現実的です。

17. GitHub Actions 以外の自動化:Dependabot

GitHub の自動化は Actions だけではありません。

代表例が Dependabot です。

Dependabot は依存パッケージや GitHub Actions の参照 version を確認し、更新 Pull Request を作成します。

設定ファイルは通常これです。

.github/dependabot.yml

例:

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"

開発停止リポジトリで Dependabot PR も不要なら、次の対応を検討します。

  • .github/dependabot.yml を削除する
  • 対象 ecosystem を削除する
  • open-pull-requests-limit: 0 を設定する
  • GitHub の repository settings 側で Dependabot 設定を見直す

Actions の schedule と Dependabot の schedule は別物です。混同しないでください。

18. 使うコマンドの整理

目的 コマンド
schedule run の履歴を見る gh run list -R OWNER/REPO --event schedule
workflow 一覧を見る gh workflow list -R OWNER/REPO
disabled workflow も含めて見る gh workflow list -R OWNER/REPO --all
workflow YAML を見る gh workflow view WORKFLOW_ID -R OWNER/REPO --yaml
workflow を止める gh workflow disable WORKFLOW_ID -R OWNER/REPO
workflow を再開する gh workflow enable WORKFLOW_ID -R OWNER/REPO
workflow を手動実行する gh workflow run WORKFLOW_ID -R OWNER/REPO

19. 判断基準

開発停止リポジトリでは、原則として次の判断でよいです。

状況 推奨対応
完全に開発停止 scheduled workflow を disable
CI も不要 workflow 全体を disable
push / PR の CI は残したい YAML から schedule だけ削除
手動実行だけ残したい workflow_dispatch だけ残す
Dependabot PR も不要 dependabot.yml を削除または制限
外部サービスを叩いている 早めに disable
課金 API / cloud を使っている 最優先で disable

20. よくある落とし穴

run 履歴と workflow 定義を混同する

gh run list は過去の実行履歴です。

.github/workflows/*.yml は今後の実行定義です。

履歴が残っているからといって、今も動いているとは限りません。逆に、履歴に出ていなくても YAML に schedule: が残っていれば、将来動く可能性があります。

gh workflow disable は schedule だけを止めるわけではない

workflow 全体が止まります。

CI を残したい場合は YAML を編集します。

workflow 名は重複する

Security Audit のような名前は複数存在できます。

停止は ID でやる方が安全です。

disabled workflow は普通の list では見えない

確認時は --all を付けます。

gh workflow list -R OWNER/REPO --all

Dependabot は GitHub Actions とは別

以下は別系統です。

.github/workflows/*.yml  → GitHub Actions
.github/dependabot.yml   → Dependabot

21. まとめ

開発停止リポジトリで GitHub Actions の定期実行が失敗し続けている場合、見るべきポイントは次の順番です。

1. gh run list --event schedule で過去の schedule run を確認
2. workflowDatabaseId を取得
3. gh workflow disable WORKFLOW_ID で停止
4. gh workflow list --all で disabled_manually を確認
5. active workflow の YAML を見て schedule が残っていないか確認
6. 翌日、停止後の新しい schedule run が増えていないか確認

特に重要なのは、run 履歴だけで判断しないことです。

最終確認では、active な workflow の YAML に schedule: が残っていないことを確認するのが確実です。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?