注意:この記事はAIが作成しています
参照元の存在、参考元のリンクの信頼度、事実の歪曲がないかをAIによりセルフチェックしています
はじめに
従来、定期的なバッチ処理やタスクの実行には専用のサーバーやcronジョブが必要でした。しかし、GitHub Actionsの登場により、サーバーレスで定期処理を実現できるようになりました。本記事では、GitHub Actions Hooksを活用してサーバーなしで定期処理を実装する方法を詳しく解説します。
GitHub Actionsとは
GitHub Actionsは、GitHubが提供するCI/CD(継続的インテグレーション/継続的デプロイ)プラットフォームです。コードのビルド、テスト、デプロイを自動化できるだけでなく、schedule triggerを使用して定期的なタスクの実行も可能です。
主な特徴
- サーバーレス: インフラストラクチャの管理が不要
- 無料枠: パブリックリポジトリでは無制限、プライベートリポジトリでも月2,000分まで無料
- 豊富なエコシステム: GitHub Marketplaceで多様なActionを利用可能
- 簡単な設定: YAMLファイルでワークフローを定義
定期処理の実装方法
1. ワークフローファイルの作成
リポジトリの.github/workflows/ディレクトリにYAMLファイルを作成します。
name: Scheduled Task
on:
schedule:
- cron: '0 0 * * *' # 毎日午前0時(UTC)に実行
workflow_dispatch: # 手動実行も可能
jobs:
scheduled-job:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Run scheduled task
run: |
echo "定期処理を実行中..."
# ここに実際の処理を記述
2. Cron式の理解
分[0-59] 時[0-23] 日[1-31] 月[1-12] 曜日[0-7]
例:'09 * * 1'=毎週月曜日の9時
例:'30 14 15 * *'=毎月15日の14:30
よく使用されるCron式の例:
| 式 | 実行タイミング |
|---|---|
0 0 * * * |
毎日午前0時 |
0 9 * * 1-5 |
平日の午前9時 |
0 */6 * * * |
6時間ごと |
0 0 1 * * |
毎月1日の午前0時 |
参考
https://qiita.com/nemutas/items/3f5816eabbf0eda5e6a9
3. 実用的な定期処理の例
データバックアップ
name: Daily Backup
on:
schedule:
- cron: '0 2 * * *' # 毎日午前2時
jobs:
backup:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Backup to S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 sync ./data s3://my-backup-bucket/$(date +%Y%m%d)/
ヘルスチェック
name: Health Check
on:
schedule:
- cron: '*/15 * * * *' # 15分ごと
jobs:
health-check:
runs-on: ubuntu-latest
steps:
- name: Check website status
run: |
response=$(curl -s -o /dev/null -w "%{http_code}" https://example.com)
if [ $response != "200" ]; then
echo "Website is down! Status: $response"
# Slack通知やメール送信など
fi
GITHUB_TOKENとは
概要
GITHUB_TOKENは、GitHub Actionsが各ワークフロージョブに対して自動生成するAPIトークンです。このトークンを使用することで、ワークフロー内からGitHub APIへの認証済みリクエストを行うことができます。
特徴
- 自動生成・削除: ジョブごとに新しいトークンが生成され、ジョブ完了時に自動削除
- リポジトリスコープ: トークンの権限は該当リポジトリに限定
- GitHub Appベース: 実際にはGitHub Appのインストールアクセストークン
使用方法
基本的な使い方
name: Use GITHUB_TOKEN
on: push
jobs:
api-call:
runs-on: ubuntu-latest
steps:
# 方法1: secrets経由
- name: Create issue
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Automated issue","body":"Created by GitHub Actions"}' \
https://api.github.com/repos/${{ github.repository }}/issues
# 方法2: github.token経由
- name: Another API call
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh issue list --limit 5
権限設定
GITHUB_TOKENの権限は細かく制御できます:
name: Minimal Permissions
on: push
# ワークフロー全体の権限設定
permissions:
contents: read # リポジトリ内容の読み取り
issues: write # Issue の作成・編集
pull-requests: write # PR の操作
jobs:
limited-job:
runs-on: ubuntu-latest
# ジョブ単位での権限設定(ワークフローレベルを上書き)
permissions:
contents: read
issues: write
steps:
- uses: actions/checkout@v4
- name: Create issue
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 必要最小限の権限でAPI呼び出し
gh issue create --title "Deployment complete" --body "✅ Success"
利用可能な権限一覧
| 権限 | 説明 | 設定値 |
|---|---|---|
contents |
リポジトリコンテンツへのアクセス |
read, write, none
|
issues |
Issueの管理 |
read, write, none
|
pull-requests |
PRの管理 |
read, write, none
|
packages |
GitHub Packagesへのアクセス |
read, write, none
|
actions |
GitHub Actionsの管理 |
read, write, none
|
checks |
チェック実行の管理 |
read, write, none
|
deployments |
デプロイメントの管理 |
read, write, none
|
statuses |
コミットステータスの管理 |
read, write, none
|
GITHUB_TOKEN vs 個人アクセストークン(PAT)
| 項目 | GITHUB_TOKEN | Personal Access Token |
|---|---|---|
| スコープ | 単一リポジトリのみ | ユーザーがアクセス可能な全リポジトリ |
| 有効期限 | ジョブ完了時に自動削除 | 手動設定(最大1年) |
| 権限制御 | 細かく制御可能 | 比較的大きなスコープ単位 |
| セキュリティ | 高(自動管理) | 中(手動管理が必要) |
| 用途 | 同一リポジトリ内の操作 | 複数リポジトリ間の操作 |
実際の活用例
name: Automated Repository Management
on:
schedule:
- cron: '0 1 * * *' # 毎日午前1時
permissions:
contents: read
issues: write
pull-requests: write
jobs:
daily-maintenance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Close stale issues
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 30日以上更新されていないissueを検索
gh issue list --state open --json number,updatedAt --jq '
map(select(
(now - (.updatedAt | fromdateiso8601)) > (30 * 24 * 60 * 60)
)) | .[].number
' | while read issue_number; do
echo "Closing stale issue #$issue_number"
gh issue close $issue_number --comment "This issue has been automatically closed due to inactivity."
done
- name: Create weekly report
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 今週作成されたPRの数をカウント
pr_count=$(gh pr list --state all --search "created:>=$(date -d '7 days ago' --iso-8601)" --json number | jq length)
# レポートissueを作成
gh issue create \
--title "Weekly Report - $(date '+%Y-%m-%d')" \
--body "This week: $pr_count pull requests were created."
セキュリティとベストプラクティス
1. シークレットの管理
機密情報は必ずGitHub Secretsに保存しましょう。
steps:
- name: Use secrets
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: |
# 安全に環境変数を使用
2. 権限の最小化
permissions:
contents: read
issues: write
pull-requests: write
3. タイムアウトの設定
jobs:
scheduled-job:
runs-on: ubuntu-latest
timeout-minutes: 30 # 30分でタイムアウト
制限事項と注意点
GitHub Actionsの制限
サマリー
- 実行時間制限
- ジョブ: 最大6時間]
- ワークフロー: 最大72時間
- 並行実行制限
- 同時実行: 20ジョブ
- キュー待ち: 500ジョブ
- ストレージ制限:アーティファクト: 10GB
- ネットワーク制限:外部API呼び出し制限あり
注意事項
- スケジュール実行の遅延: 高負荷時には最大59分の遅延が発生する可能性
- 最小間隔: 5分より短い間隔での実行は推奨されない
- 非アクティブリポジトリ: 60日間活動がないと自動停止
- 外部API制限: GITHUB_TOKENは1,000リクエスト/時間/リポジトリ、認証なしは60リクエスト/時間
- ネットワーク制限: GitHub-hosted runnersは大量のIPアドレスから発信されるため、相手先でのホワイトリスト登録が困難
###$ 外部API呼び出しの制限
GitHub Actionsでの外部API呼び出しには、以下の制限があります:
1. GitHub API自体の制限
2. セカンダリレート制限
GitHub enforces secondary rate limits in order to prevent abuse:
- 同時リクエスト制限: 最大100並行リクエスト
- エンドポイント制限: RESTは900ポイント/分、GraphQLは2,000ポイント/分
- コンテンツ作成制限: 80リクエスト/分、500リクエスト/時間
3. ネットワーク制限
GitHub-hosted runners:
- 基本的に外部への通信は自由
- ただし、大量のIPアドレスから発信されるため、相手先でIPホワイトリストが困難
- 現在のactions用IPアドレス数: 2,584個(IPv4: 2,156個、IPv6: 428個)
Self-hosted runners:
- 自前のネットワーク環境に依存
- 必要に応じて送信元IPを固定可能
- プライベートネットワークの内部APIに直接アクセス可能
4. 実用的な対処法
# 外部APIレート制限への対策
name: Handle API Rate Limits
on:
schedule:
- cron: '0 */2 * * *'
jobs:
api-cal# GitHub Actions Hooksで定期処理をサーバなしで実現する方法
監視とデバッグ
1. ログの確認
steps:
- name: Debug information
run: |
echo "Current time: $(date)"
echo "Runner: ${{ runner.os }}"
echo "Event: ${{ github.event_name }}"
2. 通知の設定
- name: Notify on failure
if: failure()
uses: 8398a7/action-slack@v3
with:
status: failure
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
応用例
1. 定期的なセキュリティスキャン
name: Security Scan
on:
schedule:
- cron: '0 1 * * 0' # 毎週日曜日の午前1時
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run security audit
run: |
npm audit --audit-level=high
docker run --rm -v $PWD:/app clair-scanner
2. パフォーマンス監視
name: Performance Monitor
on:
schedule:
- cron: '0 */4 * * *' # 4時間ごと
jobs:
performance-test:
runs-on: ubuntu-latest
steps:
- name: Load test
run: |
npx lighthouse https://example.com --output=json
# 結果をダッシュボードに送信
まとめ
GitHub Actions Hooksを活用することで、従来サーバーが必要だった定期処理をサーバーレスで実現できます。コスト削減、運用負荷の軽減、そして高い可用性を同時に実現できる優れたソリューションです。
ただし、実行時間の制限やスケジュールの遅延など、制限事項も理解した上で適切に活用することが重要です。小規模から中規模のタスクであれば、GitHub Actionsは非常に有効な選択肢となるでしょう。