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 Actions Hooksで定期処理をサーバなしで実現する方法

Posted at

注意:この記事は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への認証済みリクエストを行うことができます。

特徴

  1. 自動生成・削除: ジョブごとに新しいトークンが生成され、ジョブ完了時に自動削除
  2. リポジトリスコープ: トークンの権限は該当リポジトリに限定
  3. 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の制限

サマリー

  1. 実行時間制限
    • ジョブ: 最大6時間]
    • ワークフロー: 最大72時間
  2. 並行実行制限
    • 同時実行: 20ジョブ
    • キュー待ち: 500ジョブ
  3. ストレージ制限:アーティファクト: 10GB
  4. ネットワーク制限:外部API呼び出し制限あり

注意事項

  1. スケジュール実行の遅延: 高負荷時には最大59分の遅延が発生する可能性
  2. 最小間隔: 5分より短い間隔での実行は推奨されない
  3. 非アクティブリポジトリ: 60日間活動がないと自動停止
  4. 外部API制限: GITHUB_TOKENは1,000リクエスト/時間/リポジトリ、認証なしは60リクエスト/時間
  5. ネットワーク制限: 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は非常に有効な選択肢となるでしょう。


参考リンク

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?