GitHub Actions で CI/CD を組む実践ガイド|ワークフロー・シークレット・再利用
GitHub Actions の使い方を実例付きで完全解説。CI/CD ワークフローの基礎、再利用可能ワークフロー、シークレット管理、キャッシュ活用まで実務に使えるテクニック。
GitHub Actions は、GitHub が提供する CI/CD プラットフォームです。リポジトリへの push、Pull Request、Issue の更新、時間スケジュールなど、あらゆるイベントをトリガーに自動処理を実行できます。公開リポジトリでは無料、プライベートでも月2000分まで無料と、コストパフォーマンスも優秀です。
GitHub Actions の基本
ワークフローファイルの配置
.github/
└── workflows/
├── ci.yml
├── deploy.yml
└── release.yml
.github/workflows/ 以下に YAML ファイルを置くだけで、自動的に認識されます。
最小のワークフロー
# .github/workflows/ci.yml
name: CI
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "Hello, GitHub Actions!"
ワークフローの構成要素
Workflow (ci.yml)
└ Job (test)
└ Step (checkout)
└ Step (run command)
- Workflow: 1つの YAML ファイル = 1つのワークフロー
- Job: 並行実行される処理単位
- Step: Job 内の各ステップ
トリガー(on)
# push 時
on: push
# 特定ブランチのみ
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# 特定ファイル変更時のみ
on:
push:
paths:
- 'src/**'
- 'package.json'
# タグが付いた時
on:
push:
tags:
- 'v*.*.*'
# 手動実行
on:
workflow_dispatch:
inputs:
environment:
description: '環境'
required: true
type: choice
options: [dev, staging, prod]
# 定時実行(cron)
on:
schedule:
- cron: '0 9 * * *' # 毎日 9:00 UTC
# 複数トリガーの組み合わせ
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 0 * * 0'
Node.js プロジェクトの CI 例
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build
run: npm run build
マトリックスビルド(複数環境テスト)
複数の OS / バージョンで並行テスト:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
上記は 3 OS × 3 Node.js バージョン = 9 並列ジョブが実行されます。
シークレットの管理
シークレットの追加
GitHub リポジトリの Settings → Secrets and variables → Actions で追加。
ワークフローでの使用
- name: Deploy
run: ./deploy.sh
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
重要: シークレットはログに自動マスクされますが、echo "${{ secrets.API_KEY }}" のようにログ出力しないよう注意。
環境別シークレット
jobs:
deploy:
environment: production # production 環境のシークレットを使用
steps:
- run: echo "Deploying..."
env:
DEPLOY_KEY: ${{ secrets.PROD_DEPLOY_KEY }}
Settings → Environments で本番・ステージング等の環境を定義できます。承認ルール(レビュー必須)も設定可能です。
キャッシュで高速化
Node.js 依存関係のキャッシュ
actions/setup-node@v4 には cache オプションが組み込まれています。
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm' # または 'yarn', 'pnpm'
手動キャッシュ
- uses: actions/cache@v4
with:
path: |
~/.npm
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
Next.js ビルドキャッシュ
- uses: actions/cache@v4
with:
path: |
~/.npm
${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
並行実行の制御
concurrency
同じブランチの前のワークフローをキャンセル:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
これにより、プッシュを連続した時も最新のものだけが実行されます。
Job の依存関係
jobs:
test:
runs-on: ubuntu-latest
steps: [...]
build:
needs: test # test が成功したら実行
runs-on: ubuntu-latest
steps: [...]
deploy:
needs: [test, build] # 両方成功したら実行
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps: [...]
再利用可能ワークフロー
複数のリポジトリで共通処理を使う場合、再利用可能ワークフローを定義できます。
定義側(共通リポジトリ)
# .github/workflows/reusable-ci.yml
name: Reusable CI
on:
workflow_call:
inputs:
node-version:
type: string
default: '20'
secrets:
NPM_TOKEN:
required: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- run: npm ci
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: npm test
呼び出し側
# .github/workflows/ci.yml
jobs:
call-reusable:
uses: your-org/shared-workflows/.github/workflows/reusable-ci.yml@main
with:
node-version: '22'
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Composite Action(複合アクション)
一連のステップを1つの Action としてまとめられます。
# .github/actions/setup/action.yml
name: Setup
description: Node.js と依存関係のセットアップ
inputs:
node-version:
description: Node.js version
default: '20'
runs:
using: composite
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
shell: bash
使用例:
- uses: ./.github/actions/setup
with:
node-version: '22'
デプロイの実例
Cloudflare Pages へのデプロイ
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: my-project
directory: dist
Vercel へのデプロイ
- uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
通知の設定
Slack 通知
- name: Slack Notification
if: failure()
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_TITLE: CI Failed
SLACK_COLOR: danger
Discord 通知
- name: Discord Notification
if: always()
uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
デバッグテクニック
デバッグログの有効化
リポジトリの Secrets に以下を追加:
ACTIONS_RUNNER_DEBUG = true
ACTIONS_STEP_DEBUG = true
詳細なログが出力されるようになります。
SSH での接続デバッグ
- name: SSH Debug
if: failure()
uses: mxschmitt/action-tmate@v3
ワークフローが失敗した時に、SSH で接続してデバッグできます(パブリックリポジトリのみ)。
ログをファイル出力
- run: npm test 2>&1 | tee test-output.log
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-output
path: test-output.log
コスト管理
GitHub Actions の無料枠:
| プラン | 月間無料分 |
|---|---|
| Free | 2,000分 |
| Team | 3,000分 |
| Enterprise | 50,000分 |
コスト削減のコツ:
- 並列実行を減らす: マトリックスを必要最小限に
- 不要なジョブを削除: draft PR では CI を実行しない
- パスフィルタ: 関係ないファイル変更では実行しない
- キャッシュ活用: セットアップ時間を削減
- self-hosted runner: 大規模プロジェクトでは自前ホスティング
# draft PR では実行しない
if: github.event.pull_request.draft == false
セキュリティのベストプラクティス
1. サードパーティ Action の固定
# 悪い例: タグで指定
- uses: some-action@v1
# 良い例: コミットハッシュで固定
- uses: some-action@abc123def456
タグは後から変更可能です。セキュリティ重視ならコミットハッシュで固定しましょう。
2. 最小権限の原則
permissions:
contents: read
pull-requests: write
GITHUB_TOKEN に必要最低限の権限のみ付与します。
3. Pull Request からのシークレット保護
外部からの PR ではシークレットが利用できないよう、デフォルトで制限されています。pull_request_target の使用は慎重に。
まとめ
GitHub Actions は、CI/CD 入門として最も簡単かつ強力な選択肢です。
導入のステップ:
- 基本の CI: Lint、Test、Build の自動化から
- デプロイ自動化: main マージ時の自動デプロイ
- マトリックスビルド: 複数環境でのテスト
- 再利用可能ワークフロー: 共通処理の切り出し
- セキュリティ強化: シークレット管理、権限最小化
まずは既存プロジェクトの npm test を GitHub Actions で自動化するところから始めてみましょう。数分で効果を実感できます。