ci-cd-pipeline-patterns について
ci-cd-pipeline-patterns は、DevOps や開発チーム向けの CI/CD スキルガイドで、GitHub Actions のワークフローを中心に扱います。テスト、デプロイ、セキュリティ、キャッシュ、リリース自動化のパターンを解説します。
主な機能
- 01GitHub Actions ワークフローの設定
- 02マトリックスビルドとキャッシュ
- 03CI のテスト戦略
- 04複数環境と段階的デプロイ
- 05シークレットと OIDC のセキュリティ実践
- 06バージョン管理とリリース自動化
活用シーン
- 01プロジェクトの自動ビルドとテストの設定
- 02ステージング環境と本番環境のデプロイフロー作成
- 03CI/CD の認証情報保護と OIDC 設定
- 04変更履歴とバージョンの自動化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ manutej/ luxor-claude-marketplace --skill ci-cd-pipeline-patternsインストール後、Claude Code で/ci-cd-pipeline-patternsを入力して読み込まれたか確認します。
同梱ファイルEXAMPLES.mdREADME.md
詳細
CI/CD パイプラインのパターン
GitHub Actions と最新の DevOps プラクティスを使用して、CI/CD パイプラインを設計、実装、最適化するための包括的なスキルです。ワークフローの自動化、テスト戦略、デプロイパターン、リリース管理を習得し、ソフトウェアの継続的なデリバリーを実現します。
このスキルを使用する場面
次のような場合に、このスキルを使用します。
- プロジェクトの継続的インテグレーションおよびデプロイパイプラインを設定する
- ビルド、テスト、デプロイのワークフローを自動化する
- 複数環境へのデプロイ戦略(ステージング、本番環境)を実装する
- リリースの自動化とバージョン管理を行う
- 複数プラットフォームのテスト用にマトリックスビルドを設定する
- シークレットと OIDC を使用して CI/CD パイプラインを保護する
- キャッシュと並列化を使用してパイプラインのパフォーマンスを最適化する
- CI で Docker を使用してコンテナ化アプリケーションをビルドする
- クラウドプラットフォーム(AWS、Azure、GCP、Vercel、Netlify)にデプロイする
- Terraform/CloudFormation を使用してコードとしてのインフラストラクチャを実装する
- モノレポの CI/CD パターンを設定する
- 再利用可能なワークフローテンプレートとカスタムアクションを作成する
- デプロイ戦略(ブルーグリーン、カナリア、ローリング)を実装する
- 変更履歴の生成とセマンティックバージョニングを自動化する
- 品質ゲートとコードカバレッジチェックを統合する
コアコンセプト
CI/CD の基礎
継続的インテグレーション(CI):開発者がリポジトリにコミットするたびに、コードの変更を自動的にビルドしてテストします。
継続的デプロイ(CD):テストに合格した後、コードの変更を本番環境に自動的にデプロイします。
継続的デリバリー:コードをいつでもデプロイできる状態に保ち、本番環境へのデプロイには手動承認を必要とします。
GitHub Actions のアーキテクチャ
GitHub Actions は、リポジトリに直接統合されたイベント駆動型の自動化を提供します。
ワークフロー
自動化されたプロセスを定義する .github/workflows/ 内の YAML ファイルです。
name: CI Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build project
run: npm run build
主な構成要素:
- name:人が読みやすいワークフロー名
- on:ワークフローをトリガーするイベント(push、pull_request、schedule、workflow_dispatch)
- jobs:順次または並列で実行されるステップの集まり
- runs-on:ランナー環境(ubuntu-latest、windows-latest、macos-latest)
ジョブ
同じランナー上で実行されるステップのグループです。
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
deploy:
needs: test # Runs after 'test' job completes
runs-on: ubuntu-latest
steps:
- run: npm run deploy
ジョブの機能:
- needs:ジョブの依存関係を定義します(順次実行)
- if:式に基づいて条件付きで実行します
- strategy:複数の構成に対応するマトリックスビルドを設定します
- outputs:ジョブ間でデータを共有します
- environment:保護ルールを設定したデプロイ環境を指定します
ステップ
ジョブ内の個々のタスクです。
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
ステップの種類:
- uses:マーケットプレイスまたはリポジトリから、ビルド済みのアクションを実行します
- run:シェルコマンドを実行します
- with:アクションに入力を渡します
- env:ステップの環境変数を設定します
アクション
特定のタスクを実行する、再利用可能なコードの単位です。
公式アクション:
actions/checkout@v4:リポジトリのコードをチェックアウトしますactions/setup-node@v4:Node.js 環境をセットアップしますactions/cache@v4:依存関係をキャッシュしますactions/upload-artifact@v4:ビルド成果物をアップロードしますactions/download-artifact@v4:以前のジョブから成果物をダウンロードします
マーケットプレイスのアクション:
docker/build-push-action@v5:Docker イメージをビルドしてプッシュしますaws-actions/configure-aws-credentials@v4:AWS 認証情報を設定しますcodecov/codecov-action@v4:コードカバレッジをアップロードしますgoogle-github-actions/auth@v2:Google Cloud で認証します
シークレットと変数
シークレット:暗号化された機密データ(API キー、認証情報、トークン)です。
steps:
- name: Deploy to production
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: npm run deploy
変数:機密情報ではない構成データです。
env:
NODE_ENV: ${{ vars.NODE_ENV }}
API_ENDPOINT: ${{ vars.API_ENDPOINT }}
シークレットの種類:
- リポジトリシークレット:リポジトリ内のすべてのワークフローで使用できます
- 環境シークレット:特定の環境(本番環境、ステージング)に限定されます
- 組織シークレット:組織内の複数のリポジトリで共有されます
成果物
ワークフローによって生成され、ダウンロードしたり、他のジョブで使用したりできるファイルです。
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist-files
path: dist/
retention-days: 7
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist-files
path: ./dist
ワークフローのトリガー
イベントトリガー
プッシュイベント:
on:
push:
branches:
- main
- develop
- 'release/**'
paths:
- 'src/**'
- 'package.json'
tags:
- 'v*'
プルリクエストイベント:
on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
paths-ignore:
- 'docs/**'
- '**.md'
スケジュール(Cron):
on:
schedule:
- cron: '0 0 * * *' # Daily at midnight UTC
- cron: '0 */6 * * *' # Every 6 hours
手動トリガー(workflow_dispatch):
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy to'
required: true
type: choice
options:
- staging
- production
version:
description: 'Version to deploy'
required: true
type: string
リリースイベント:
on:
release:
types: [published, created, released]
ワークフロー呼び出し(再利用可能なワークフロー):
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
api-key:
required: true
マトリックスビルド
複数の設定でジョブを並行して実行します:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
include:
- os: ubuntu-latest
node-version: 20
coverage: true
exclude:
- os: macos-latest
node-version: 18
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm test
- if: matrix.coverage
run: npm run coverage
マトリックス機能:
- 並列実行:すべての組み合わせを同時に実行します
- include:特定の設定を追加します
- exclude:特定の組み合わせを除外します
- fail-fast:1つのジョブが失敗した場合、すべてのジョブを停止します(デフォルト:true)
- max-parallel:同時に実行するジョブ数を制限します
キャッシュ戦略
依存関係をキャッシュしてワークフローを高速化します:
Node.js のキャッシュ:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # Automatically caches npm dependencies
カスタムキャッシュ:
- uses: actions/cache@v4
with:
path: |
~/.npm
~/.cache
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
Docker レイヤーキャッシュ:
- uses: docker/build-push-action@v5
with:
context: .
cache-from: type=gha
cache-to: type=gha,mode=max
CI でのテスト戦略
ユニットテスト
個々のコンポーネントを対象とした、高速で独立したテストです:
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:unit -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/coverage-final.json
flags: unit-tests
token: ${{ secrets.CODECOV_TOKEN }}
統合テスト
コンポーネントやサービス間の連携をテストします:
jobs:
integration-tests:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run database migrations
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
run: npm run migrate
- name: Run integration tests
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
REDIS_URL: redis://localhost:6379
run: npm run test:integration
エンドツーエンドテスト
ユーザーのワークフロー全体をテストします:
jobs:
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run E2E tests
run: npm run test:e2e
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30
パフォーマンステスト
ベンチマークとパフォーマンスのリグレッションテストを実施します:
jobs:
performance-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build for production
run: npm run build
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v11
with:
urls: |
http://localhost:3000
http://localhost:3000/dashboard
uploadArtifacts: true
temporaryPublicStorage: true
- name: Run load tests
run: npm run test:load
コード品質とリンティング
コード標準と品質ゲートを適用します:
jobs:
code-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Run Prettier check
run: npm run format:check
- name: Run TypeScript check
run: npm run type-check
- name: Run security audit
run: npm audit --audit-level=moderate
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
デプロイパターン
ブルーグリーンデプロイ
同一の環境を2つ維持し、ダウンタイムなしでデプロイします:
jobs:
deploy-blue-green:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Green environment
run: |
# Deploy new version to green environment
./deploy.sh green
- name: Run smoke tests on Green
run: |
# Verify green environment is healthy
curl -f https://green.example.com/health
- name: Switch traffic to Green
run: |
# Update load balancer to point to green
aws elbv2 modify-rule --rule-arn $RULE_ARN \
--actions Type=forward,TargetGroupArn=$GREEN_TG
- name: Monitor Green environment
run: |
# Monitor for 5 minutes
./monitor.sh green 300
- name: Rollback if needed
if: failure()
run: |
# Switch back to blue
aws elbv2 modify-rule --rule-arn $RULE_ARN \
--actions Type=forward,TargetGroupArn=$BLUE_TG
カナリアデプロイ
一部のユーザーに段階的にロールアウトします:
jobs:
canary-deployment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy canary (10% traffic)
run: |
kubectl set image deployment/app app=myapp:${{ github.sha }}
kubectl scale deployment/app-canary --replicas=1
kubectl annotate service app-service \
traffic-split='{"canary": 10, "stable": 90}'
- name: Monitor canary metrics
run: |
# Monitor error rates, latency for 15 minutes
./monitor-canary.sh 900
- name: Increase canary traffic (50%)
run: |
kubectl annotate service app-service \
traffic-split='{"canary": 50, "stable": 50}' --overwrite
- name: Monitor again
run: ./monitor-canary.sh 600
- name: Full rollout (100%)
run: |
kubectl set image deployment/app-stable app=myapp:${{ github.sha }}
kubectl scale deployment/app-canary --replicas=0
- name: Rollback canary
if: failure()
run: |
kubectl scale deployment/app-canary --replicas=0
ローリングデプロイ
インスタンスを順次更新します:
jobs:
rolling-deployment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy with rolling update
run: |
kubectl set image deployment/app \
app=myapp:${{ github.sha }} \
--record
- name: Wait for rollout to complete
run: |
kubectl rollout status deployment/app --timeout=10m
- name: Verify deployment
run: |
kubectl get pods -l app=myapp
curl -f https://api.example.com/health
- name: Rollback on failure
if: failure()
run: |
kubectl rollout undo deployment/app
マルチ環境デプロイ
承認を経て、ステージング環境から本番環境へデプロイします:
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: ./deploy.sh staging
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: ./deploy.sh production
セキュリティのベストプラクティス
シークレット管理
GitHub Secrets の使用:
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
環境ごとのシークレット:
jobs:
deploy:
environment: production # Uses production-scoped secrets
steps:
- name: Deploy
env:
API_KEY: ${{ secrets.PRODUCTION_API_KEY }}
run: ./deploy.sh
OIDC(OpenID Connect)
長期間有効な認証情報を使わずに認証します:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: us-east-1
- name: Deploy to AWS
run: aws s3 sync ./dist s3://my-bucket
Google Cloud OIDC:
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: 'projects/123/locations/global/workloadIdentityPools/pool/providers/provider'
service_account: '[email protected]'
セキュアなワークフロー
権限を制限する:
permissions:
contents: read # Read repository contents
pull-requests: write # Comment on PRs
id-token: write # OIDC token generation
actions: read # Read workflow runs
アクションのバージョンを SHA で固定する:
# Less secure (tag can be moved)
- uses: actions/checkout@v4
# More secure (immutable SHA)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
スクリプトインジェクションを防止する:
# Vulnerable to injection
- run: echo "Hello ${{ github.event.issue.title }}"
# Safe approach
- run: echo "Hello $TITLE"
env:
TITLE: ${{ github.event.issue.title }}
CI/CD での Docker
Docker イメージのビルド
jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: myorg/myapp
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
マルチステージ Docker ビルド
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["npm", "start"]
コンテナのスキャン
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myorg/myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
リリースの自動化
セマンティックバージョニング
コミットメッセージに基づいてリリースのバージョンを自動設定します:
jobs:
release:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Semantic Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
設定(.releaserc.json):
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
["@semantic-release/git", {
"assets": ["CHANGELOG.md", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}]
]
}
変更履歴の生成
- name: Generate changelog
uses: mikepenz/release-changelog-builder-action@v4
with:
configuration: '.github/changelog-config.json'
outputFile: 'CHANGELOG.md'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release
uses: ncipollo/release-action@v1
with:
tag: ${{ steps.version.outputs.tag }}
name: Release ${{ steps.version.outputs.tag }}
bodyFile: 'CHANGELOG.md'
artifacts: 'dist/*'
リリースノートの自動化
- name: Build Release Notes
id: release_notes
uses: mikepenz/release-changelog-builder-action@v4
with:
configurationJson: |
{
"categories": [
{
"title": "## 🚀 Features",
"labels": ["feature", "enhancement"]
},
{
"title": "## 🐛 Fixes",
"labels": ["bug", "fix"]
},
{
"title": "## 📝 Documentation",
"labels": ["documentation"]
}
]
}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
モノレポの CI/CD パターン
パスベースのトリガー
特定のパッケージが変更された場合にのみワークフローを実行します:
name: Frontend CI
on:
push:
paths:
- 'packages/frontend/**'
- 'package.json'
- 'pnpm-lock.yaml'
jobs:
test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Test frontend
run: pnpm --filter frontend test
影響を受けるパッケージの検出
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
affected: ${{ steps.affected.outputs.packages }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect affected packages
id: affected
run: |
# Use tools like Nx or Turborepo to detect changes
AFFECTED=$(npx nx affected:apps --base=origin/main --plain)
echo "packages=$AFFECTED" >> $GITHUB_OUTPUT
test-affected:
needs: detect-changes
runs-on: ubuntu-latest
strategy:
matrix:
package: ${{ fromJson(needs.detect-changes.outputs.affected) }}
steps:
- uses: actions/checkout@v4
- name: Test ${{ matrix.package }}
run: npm run test --workspace=${{ matrix.package }}
Turborepo CI
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build with Turborepo
run: npx turbo build --cache-dir=.turbo
- name: Cache Turbo
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
パフォーマンスの最適化
ジョブの並列実行
jobs:
# These jobs run in parallel
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run lint
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run test:unit
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
# This job waits for all above to complete
deploy:
needs: [lint, unit-test, build]
runs-on: ubuntu-latest
steps:
- run: npm run deploy
条件付きジョブ実行
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh staging
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh production
依存関係のキャッシュ
steps:
# Node.js with npm
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# Python with pip
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
# Ruby with bundler
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
# Go modules
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: true
再利用可能なワークフロー
再利用可能なワークフローの作成
# .github/workflows/reusable-deploy.yml
name: Reusable Deploy Workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
version:
required: false
type: string
default: 'latest'
secrets:
deploy-key:
required: true
outputs:
deployment-url:
description: "URL of the deployment"
value: ${{ jobs.deploy.outputs.url }}
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
outputs:
url: ${{ steps.deploy.outputs.url }}
steps:
- uses: actions/checkout@v4
- name: Deploy
id: deploy
env:
DEPLOY_KEY: ${{ secrets.deploy-key }}
run: |
./deploy.sh ${{ inputs.environment }} ${{ inputs.version }}
echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUT
再利用可能なワークフローの呼び出し
# .github/workflows/main.yml
name: Main Pipeline
on: [push]
jobs:
deploy-staging:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
version: ${{ github.sha }}
secrets:
deploy-key: ${{ secrets.STAGING_DEPLOY_KEY }}
deploy-production:
needs: deploy-staging
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
version: ${{ github.sha }}
secrets:
deploy-key: ${{ secrets.PRODUCTION_DEPLOY_KEY }}
Infrastructure as Code
Terraform のデプロイ
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.0
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Init
run: terraform init
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -out=tfplan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve tfplan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS CloudFormation
jobs:
deploy-cloudformation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Deploy CloudFormation stack
run: |
aws cloudformation deploy \
--template-file infrastructure/template.yml \
--stack-name my-app-stack \
--parameter-overrides \
Environment=production \
Version=${{ github.sha }} \
--capabilities CAPABILITY_IAM
ベストプラクティス
ワークフローの構成
- 関心事を分離する:CI、CD、スケジュールタスクにはそれぞれ異なるワークフローを使用します
- わかりやすい名前を付ける:ワークフローとジョブには明確な名前を付けます
- ディレクトリで整理する:関連するワークフローをまとめます
- バージョン管理する:コードと同様にワークフローの変更を追跡します
効率性
- 依存関係をキャッシュする:ビルド時間を大幅に短縮します
- 並列実行する:独立したジョブを同時に実行します
- 条件付きで実行する:不要なジョブをスキップします
- マトリックス戦略を使う:複数の設定を効率的にテストします
- アーティファクトを再利用する:ジョブ間でビルド成果物を共有します
セキュリティ
- 権限を最小限にする:最小権限の原則を適用します
- OIDC を使用する:長期間有効な認証情報を避けます
- シークレットをローテーションする:シークレットを定期的に更新します
- 依存関係のバージョンを固定する:特定のバージョンまたは SHA を使用します
- 脆弱性をスキャンする:セキュリティチェックを自動化します
信頼性
- タイムアウト設定:ジョブのハングを防止します
- 再試行ロジック:一時的な障害に対処します
- 障害通知:重大な障害を通知します
- ロールバック機構:デプロイに失敗した場合に迅速に復旧します
- ヘルスチェック:完了とする前にデプロイを検証します
可観測性
- 詳細なログ記録:明確で実用的なログを残します
- ステータスチェック:失敗したビルドのマージを防止します
- デプロイの追跡:何がどこにデプロイされているか把握できます
- メトリクスの収集:パイプラインのパフォーマンスを追跡します
- 監査証跡:誰がいつ何をデプロイしたか追跡します
障害への対処
失敗したステップを再試行する
steps:
- name: Deploy with retry
uses: nick-fields/retry-action@v2
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 30
command: npm run deploy
エラーが発生しても続行する
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run optional check
continue-on-error: true
run: npm run optional-check
- name: Run required tests
run: npm test
条件付きクリーンアップ
steps:
- name: Deploy
id: deploy
run: ./deploy.sh
- name: Rollback on failure
if: failure() && steps.deploy.conclusion == 'failure'
run: ./rollback.sh
- name: Cleanup
if: always()
run: ./cleanup.sh
高度なパターン
動的なマトリックス生成
jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- id: set-matrix
run: |
# Generate matrix based on project structure
MATRIX=$(find packages -maxdepth 1 -type d -not -name packages | \
jq -R -s -c 'split("\n")[:-1]')
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
test:
needs: generate-matrix
runs-on: ubuntu-latest
strategy:
matrix:
package: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- run: npm test --workspace=${{ matrix.package }}
コンポジットアクション
再利用可能なアクションの組み合わせを作成します:
# .github/actions/setup-project/action.yml
name: 'Setup Project'
description: 'Setup Node.js and install dependencies'
inputs:
node-version:
description: 'Node.js version'
required: false
default: '20'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
shell: bash
- run: npm run build
shell: bash
使用方法:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
with:
node-version: '20'
セルフホストランナー
jobs:
deploy:
runs-on: [self-hosted, linux, production]
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: ./deploy.sh
利点:
- ハードウェア/ソフトウェア要件をカスタマイズできます
- ビルドを高速化できます(依存関係を事前にキャッシュ)
- 内部ネットワークにアクセスできます
- CI/CD の実行量が多い場合にコストを削減できます
プラットフォーム固有のデプロイ
Vercel へのデプロイ
jobs:
deploy-vercel:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to 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'
Netlify へのデプロイ
jobs:
deploy-netlify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: npm run build
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v3
with:
publish-dir: './dist'
production-branch: main
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: 'Deploy from GitHub Actions'
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
AWS ECS へのデプロイ
jobs:
deploy-ecs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: my-app
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Update ECS service
run: |
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--force-new-deployment
Kubernetes へのデプロイ
jobs:
deploy-k8s:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure kubeconfig
run: |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig.yml
echo "KUBECONFIG=$(pwd)/kubeconfig.yml" >> $GITHUB_ENV
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/myapp \
myapp=myregistry/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp
スキルのバージョン: 1.0.0 最終更新日: 2025年10月 スキルのカテゴリ: DevOps、CI/CD、自動化、デプロイ 対応環境: GitHub Actions、Docker、Kubernetes、AWS、Azure、GCP、Vercel、Netlify