CI/CD入門
GitHub Actionsでテストとデプロイを自動化しよう
CI/CDとは?
CI(Continuous Integration / 継続的インテグレーション)は、 コードの変更を頻繁にメインブランチに統合し、自動でテストを実行する手法です。CD(Continuous Delivery / 継続的デリバリー)は、 テストに通ったコードを自動的に本番環境にデプロイする仕組みです。
CI/CDの流れ
コード変更 → push → 自動テスト → 自動ビルド → 自動デプロイ
↑ ↓
└──── 失敗通知 ←─── テスト失敗で停止
CI(継続的インテグレーション):
1. 開発者がコードをpush
2. 自動でリント・テスト・ビルドを実行
3. 問題があれば開発者に通知
CD(継続的デリバリー/デプロイ):
4. テスト通過後、ステージング環境に自動デプロイ
5. 承認後(または自動で)本番環境にデプロイCI/CDを導入することで、バグの早期発見、デプロイの高速化、手動作業によるミスの防止が実現できます。
GitHub Actionsの基本
GitHub Actionsは、GitHubに組み込まれたCI/CDサービスです。 リポジトリの.github/workflows/ディレクトリにYAMLファイルを置くだけで自動化が設定できます。
パブリックリポジトリでは無料、プライベートリポジトリでも月2,000分の無料枠があります。
Workflow(ワークフロー)
自動化の全体定義。YAMLファイル1つが1ワークフロー。
Event(イベント/トリガー)
ワークフローを起動する条件(push、PR作成、スケジュールなど)。
Job(ジョブ)
ワークフロー内の処理グループ。並列または順次実行が可能。
Step(ステップ)
ジョブ内の個々のタスク。コマンド実行やアクションの利用。
ワークフローYAMLの書き方
実際のワークフローファイルを見てみましょう。Next.jsアプリのCI設定例です。
# .github/workflows/ci.yml
name: CI
# トリガー:mainブランチへのpushとPR
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# リント・型チェック・テスト
test:
runs-on: ubuntu-latest
steps:
# リポジトリのコードを取得
- name: Checkout code
uses: actions/checkout@v4
# Node.jsのセットアップ
- 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: Type check
run: npx tsc --noEmit
# テスト
- name: Run tests
run: npm test
# ビルド確認
- name: Build
run: npm run buildusesで公開されたアクション(再利用可能な処理)を利用し、runでシェルコマンドを実行します。cache: "npm"で依存関係のキャッシュが効き、2回目以降のインストールが高速になります。
トリガー(イベント)の種類
ワークフローを起動するトリガーはさまざまな種類があります。 用途に応じて適切なトリガーを選びましょう。
# pushトリガー(特定ブランチ)
on:
push:
branches: [main, develop]
paths:
- "src/**" # srcディレクトリの変更時のみ
- "!*.md" # Markdownの変更は除外
# PRトリガー
on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
# スケジュールトリガー(cron式)
on:
schedule:
- cron: "0 9 * * 1" # 毎週月曜の9:00 UTC
# 手動トリガー
on:
workflow_dispatch:
inputs:
environment:
description: "デプロイ先"
required: true
default: "staging"
type: choice
options:
- staging
- production
# タグトリガー(リリース時)
on:
push:
tags:
- "v*" # v1.0.0 のようなタグpathsフィルターを使えば、 変更されたファイルに応じてワークフローを実行するかどうかを制御できます。 ドキュメントの変更でCIが走るのを防ぐ場合などに便利です。
自動テストの実行
CI環境でテストを自動実行し、問題があればPRにフィードバックを返す設定例です。 複数のNode.jsバージョンでテストを実行するマトリックス戦略も活用できます。
# .github/workflows/test.yml
name: Test
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
# マトリックス戦略:複数バージョンでテスト
strategy:
matrix:
node-version: [18, 20, 22]
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 test -- --coverage
# テストカバレッジをPRにコメント
- name: Upload coverage
if: matrix.node-version == 20
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
# E2Eテスト(テスト完了後に実行)
e2e:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- run: npx playwright install --with-deps
- run: npm run build
- run: npx playwright testneedsキーワードでジョブ間の依存関係を定義し、 ユニットテストが通ってからE2Eテストを実行するという順序制御ができます。
自動デプロイの設定
テストが通ったら自動的に本番環境にデプロイするワークフローを構築しましょう。 以下はVercelへの自動デプロイの例です。
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
test:
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 lint
- run: npm test
- run: npm run build
deploy:
needs: test # テスト成功後にデプロイ
runs-on: ubuntu-latest
# 環境(GitHub上でシークレットを管理)
environment:
name: production
url: https://myapp.vercel.app
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"シークレットはGitHubリポジトリの Settings > Secrets and variables > Actions から設定します。コードに直接書かないようにしましょう。
# シークレットの使い方
# リポジトリ設定で以下を登録:
# VERCEL_TOKEN : Vercelのアクセストークン
# VERCEL_ORG_ID : Vercelの組織ID
# VERCEL_PROJECT_ID : VercelのプロジェクトID
# ワークフロー内でシークレットを参照
${{ secrets.VERCEL_TOKEN }}
# 環境変数として使う場合
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}まとめ
- CIはコード変更ごとに自動テスト、CDは自動デプロイを実現する手法
- GitHub Actionsはリポジトリ内のYAMLファイルでCI/CDを定義できる
- Workflow、Job、Stepの階層構造でパイプラインを構成する
- push、PR、スケジュール、手動など多様なトリガーが利用できる
- マトリックス戦略で複数バージョンのテストを並列実行できる
- シークレットでAPIキーやトークンを安全に管理する