[SAMPLE] GitHub ActionsでCI CDパイプラインを構築する実践ガイド

先月
4

GitHub ActionsでCI/CDパイプラインを構築する実践ガイド

GitHub Actionsを使用することで、テストからデプロイまでの一連のプロセスを自動化できます。本記事では、Next.jsアプリケーションを例に、実践的なCI/CDパイプラインの構築方法を段階的に解説します。

GitHub Actionsの基礎

ワークフローの構成要素

GitHub Actionsは以下の要素で構成されます。

  • Workflow: 自動化プロセス全体の定義
  • Job: 同じランナーで実行される一連のステップ
  • Step: 個別のタスク(アクションまたはシェルコマンド)
  • Action: 再利用可能な処理のまとまり

ワークフローファイルの配置

.github/ └── workflows/ ├── ci.yml # CI(継続的インテグレーション) ├── cd.yml # CD(継続的デプロイ) └── release.yml # リリース自動化

基本的なCIワークフロー

リンターとテストの実行

# .github/workflows/ci.yml name: CI on: pull_request: branches: [main, develop] push: branches: [main, develop] jobs: lint: name: ESLint と TypeScript チェック runs-on: ubuntu-latest steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: Node.js のセットアップ uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: 依存関係のインストール run: npm ci - name: ESLint 実行 run: npm run lint - name: TypeScript 型チェック run: npm run type-check test: name: ユニットテストと統合テスト runs-on: ubuntu-latest steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: Node.js のセットアップ uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: 依存関係のインストール run: npm ci - name: ユニットテスト実行 run: npm run test:unit - name: 統合テスト実行 run: npm run test:integration - name: カバレッジレポートのアップロード uses: codecov/codecov-action@v3 with: files: ./coverage/lcov.info flags: unittests name: codecov-umbrella build: name: ビルド確認 runs-on: ubuntu-latest steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: Node.js のセットアップ uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: 依存関係のインストール run: npm ci - name: Next.js ビルド run: npm run build env: NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }} - name: ビルド成果物のキャッシュ uses: actions/cache@v3 with: path: .next/cache key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-nextjs-

E2Eテストの実行

Playwright を使用したE2Eテスト

# .github/workflows/e2e.yml name: E2E Tests on: pull_request: branches: [main] schedule: - cron: '0 2 * * *' # 毎日午前2時に実行 jobs: e2e: name: Playwright E2E テスト runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: Node.js のセットアップ uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: 依存関係のインストール run: npm ci - name: Playwright のインストール run: npx playwright install --with-deps - name: Next.js ビルド run: npm run build env: NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }} - name: E2E テスト実行 run: npm run test:e2e env: BASE_URL: http://localhost:3000 - name: テスト失敗時のスクリーンショット保存 uses: actions/upload-artifact@v3 if: failure() with: name: playwright-screenshots path: test-results/ retention-days: 7 - name: Playwright レポートのアップロード uses: actions/upload-artifact@v3 if: always() with: name: playwright-report path: playwright-report/ retention-days: 14

CDワークフロー : Vercelへの自動デプロイ

プレビュー環境とプロダクション環境

# .github/workflows/cd.yml name: CD - Deploy to Vercel on: push: branches: [main, develop] pull_request: branches: [main] jobs: deploy-preview: name: プレビュー環境へのデプロイ runs-on: ubuntu-latest if: github.event_name == 'pull_request' steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: 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 }} scope: ${{ secrets.VERCEL_ORG_ID }} - name: デプロイURLをコメント uses: actions/github-script@v7 with: script: | github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: '✅ Preview deployed to Vercel\n\nURL: ${{ steps.deploy.outputs.preview-url }}' }) deploy-production: name: 本番環境へのデプロイ runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' && github.event_name == 'push' needs: [lint, test, build] # CIジョブが成功した場合のみ実行 steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: 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' scope: ${{ secrets.VERCEL_ORG_ID }} - name: Slack 通知 uses: slackapi/slack-github-action@v1 with: webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} payload: | { "text": "✅ Production deployment successful", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "*Production Deployment*\n\n✅ Successfully deployed to production\n\nCommit: ${{ github.sha }}\nAuthor: ${{ github.actor }}" } } ] }

セキュリティチェック

依存関係の脆弱性スキャン

# .github/workflows/security.yml name: Security Scan on: push: branches: [main, develop] schedule: - cron: '0 3 * * 1' # 毎週月曜日午前3時に実行 jobs: dependency-scan: name: 依存関係の脆弱性スキャン runs-on: ubuntu-latest steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: npm audit 実行 run: npm audit --audit-level=moderate continue-on-error: true - name: Snyk による脆弱性スキャン uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high code-scan: name: コードの静的解析 runs-on: ubuntu-latest steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: CodeQL 初期化 uses: github/codeql-action/init@v2 with: languages: javascript, typescript - name: CodeQL 解析 uses: github/codeql-action/analyze@v2 - name: SonarCloud スキャン uses: SonarSource/sonarcloud-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

パフォーマンステスト

Lighthouse CI の統合

# .github/workflows/lighthouse.yml name: Lighthouse CI on: pull_request: branches: [main] jobs: lighthouse: name: Lighthouse パフォーマンステスト runs-on: ubuntu-latest steps: - name: コードのチェックアウト uses: actions/checkout@v4 - name: Node.js のセットアップ uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: 依存関係のインストール run: npm ci - name: Next.js ビルド run: npm run build - name: Lighthouse CI 実行 uses: treosh/lighthouse-ci-action@v10 with: urls: | http://localhost:3000 http://localhost:3000/about http://localhost:3000/blog uploadArtifacts: true temporaryPublicStorage: true configPath: './lighthouserc.json' - name: Lighthouse スコアの確認 run: | if [ $(cat lhci_reports/manifest.json | jq '.[0].summary.performance') -lt 0.9 ]; then echo "Performance score is below 90!" exit 1 fi

lighthouserc.json の設定

{ "ci": { "collect": { "startServerCommand": "npm start", "url": [ "http://localhost:3000/", "http://localhost:3000/about" ], "numberOfRuns": 3 }, "assert": { "preset": "lighthouse:recommended", "assertions": { "categories:performance": ["error", { "minScore": 0.9 }], "categories:accessibility": ["error", { "minScore": 0.95 }], "categories:best-practices": ["error", { "minScore": 0.9 }], "categories:seo": ["error", { "minScore": 0.95 }] } }, "upload": { "target": "temporary-public-storage" } } }

リリース自動化

セマンティックバージョニングと自動リリース

# .github/workflows/release.yml name: Release on: push: branches: [main] jobs: release: name: セマンティックリリース runs-on: ubuntu-latest steps: - name: コードのチェックアウト uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - name: Node.js のセットアップ uses: actions/setup-node@v4 with: node-version: '20' - name: 依存関係のインストール run: npm ci - name: semantic-release 実行 env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npx semantic-release - name: リリースノート生成 uses: release-drafter/release-drafter@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.releaserc.json の設定

{ "branches": ["main"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", [ "@semantic-release/npm", { "npmPublish": false } ], [ "@semantic-release/git", { "assets": ["package.json", "CHANGELOG.md"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ], "@semantic-release/github" ] }

マトリックスビルド

複数のNode.jsバージョンでテスト

name: Matrix Build on: push: branches: [main, develop] jobs: test-matrix: name: Node ${{ matrix.node-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: node-version: [18, 20, 21] os: [ubuntu-latest, windows-latest, macos-latest] exclude: - os: windows-latest node-version: 18 steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - run: npm run build - run: npm test

キャッシュ戦略

依存関係とビルドのキャッシュ

steps: - name: キャッシュの復元 uses: actions/cache@v3 with: path: | ~/.npm .next/cache node_modules key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} restore-keys: | ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} ${{ runner.os }}-node- - name: 依存関係のインストール run: npm ci

ベストプラクティス

1. シークレットの管理

env: DATABASE_URL: ${{ secrets.DATABASE_URL }} API_KEY: ${{ secrets.API_KEY }} # 決してシークレットをハードコードしない

2. ジョブの依存関係

jobs: build: runs-on: ubuntu-latest steps: - run: npm run build test: needs: build # buildが成功した後に実行 runs-on: ubuntu-latest steps: - run: npm test deploy: needs: [build, test] # buildとtestが両方成功した後に実行 runs-on: ubuntu-latest steps: - run: npm run deploy

3. タイムアウトの設定

jobs: test: runs-on: ubuntu-latest timeout-minutes: 15 # 15分でタイムアウト steps: - run: npm test

まとめ

GitHub Actionsを活用することで、以下のメリットが得られます。

  • 開発効率の向上: 手動作業の削減
  • 品質の保証: 自動テストによる品質維持
  • デプロイの高速化: 自動デプロイによるリードタイム短縮
  • セキュリティの強化: 脆弱性の早期発見

本記事で紹介したワークフローをベースに、プロジェクトのニーズに合わせてカスタマイズしてください。

0
0
0
0
投稿
0
フォロワー
0
いいね

プロパティ

ページ
PCゲームストレージDocker
まつもとゆきひろビル・ゲイツ