演習:初めてのCI/CDワークフロー
ストーリー
「座学はここまでだ。実際にワークフローを作ってみよう」
木村先輩がGitHubリポジトリを用意してくれた。
「Node.jsのWebアプリケーションプロジェクトがある。 これに対して、CI/CDワークフローをゼロから構築してくれ。 PRを出した時にテストが走り、mainにマージされたらビルドされる。 段階的に進めていこう」
演習の概要
Node.jsプロジェクトに対して、GitHub Actionsワークフローを構築してください。
プロジェクト構成
my-webapp/
├── .github/
│ └── workflows/ ← ここにワークフローを作成
├── src/
│ ├── index.ts
│ ├── app.ts
│ └── utils/
│ └── validator.ts
├── tests/
│ ├── app.test.ts
│ └── validator.test.ts
├── package.json
├── tsconfig.json
└── README.md
package.jsonのscripts
json
{
"scripts": {
"lint": "eslint src/ --ext .ts",
"typecheck": "tsc --noEmit",
"test": "jest --coverage",
"build": "tsc && node -e \"console.log('Build successful')\"",
"start": "node dist/index.js"
}
}課題1: CIワークフローの作成
PRが作成・更新された時に、Lint、型チェック、テストを実行するワークフローを作成してください。
要件
- ファイル名:
.github/workflows/ci.yml - トリガー:
pull_request(mainブランチへのPR) - Node.js バージョン: 20
- 実行するステップ: checkout → setup-node → npm ci → lint → typecheck → test
- タイムアウト: 15分
yaml
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [ main ]
permissions:
contents: read
jobs:
ci:
name: Lint, Type Check & Test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
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 ESLint
run: npm run lint
- name: Type check
run: npm run typecheck
- name: Run tests
run: npm test課題2: ビルド & アーティファクトの保存
課題1のCIが成功した後に、ビルドを行いアーティファクトとして保存するワークフローを追加してください。
要件
- CIジョブ成功後にビルドジョブを実行(
needsを使用) - ビルド成果物(
dist/)をアーティファクトとしてアップロード - アーティファクトの保持期間: 7日
yaml
# .github/workflows/ci.yml(課題1を拡張)
name: CI
on:
pull_request:
branches: [ main ]
permissions:
contents: read
jobs:
lint-and-test:
name: Lint, Type Check & Test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
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 ESLint
run: npm run lint
- name: Type check
run: npm run typecheck
- name: Run tests
run: npm test
build:
name: Build
needs: lint-and-test
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
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: Build
run: npm run build
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 7課題3: mainブランチへのpush時のCD
mainブランチにマージされた時に、ビルド → デプロイ(模擬)を実行するワークフローを作成してください。
要件
- ファイル名:
.github/workflows/cd.yml - トリガー:
push(mainブランチのみ) - ジョブ構成: test → build → deploy
- deploy ジョブは build の成功後に実行
- deploy ジョブでは
echoでデプロイメッセージを出力 - deploy ジョブには環境名(
environment: production)を設定
yaml
# .github/workflows/cd.yml
name: CD
on:
push:
branches: [ main ]
permissions:
contents: read
env:
NODE_VERSION: '20'
jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
build:
name: Build Application
needs: test
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: production-build
path: dist/
retention-days: 3
deploy:
name: Deploy to Production
needs: build
runs-on: ubuntu-latest
environment: production
timeout-minutes: 10
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: production-build
path: dist/
- name: Deploy
run: |
echo "=========================================="
echo " Deploying to production environment"
echo " Commit: ${{ github.sha }}"
echo " Actor: ${{ github.actor }}"
echo " Time: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
echo "=========================================="
echo "Deploying files from dist/..."
ls -la dist/
echo "Deployment complete!"課題4: 手動実行ワークフロー
緊急時に手動でデプロイできるワークフローを作成してください。
要件
- ファイル名:
.github/workflows/manual-deploy.yml - トリガー:
workflow_dispatch - 入力パラメータ: environment(staging/production の選択)、version(文字列)
- 選択した環境とバージョンに応じたデプロイメッセージを出力
yaml
# .github/workflows/manual-deploy.yml
name: Manual Deploy
on:
workflow_dispatch:
inputs:
environment:
description: 'Deploy target environment'
required: true
type: choice
options:
- staging
- production
version:
description: 'Version to deploy (e.g., v1.2.3)'
required: true
type: string
permissions:
contents: read
jobs:
confirm:
name: Confirm Deployment
runs-on: ubuntu-latest
steps:
- name: Display deployment info
run: |
echo "============================================"
echo " Manual Deployment Request"
echo "============================================"
echo " Environment: ${{ inputs.environment }}"
echo " Version: ${{ inputs.version }}"
echo " Triggered by: ${{ github.actor }}"
echo " Time: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
echo "============================================"
deploy:
name: Deploy to ${{ inputs.environment }}
needs: confirm
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install & Build
run: |
npm ci
npm run build
- name: Deploy
run: |
echo "Deploying version ${{ inputs.version }} to ${{ inputs.environment }}..."
echo "Deployment successful!"達成度チェック
| 課題 | 内容 | 完了 |
|---|---|---|
| 課題1 | CIワークフロー(Lint + テスト) | [ ] |
| 課題2 | ビルド & アーティファクト保存 | [ ] |
| 課題3 | CDワークフロー(テスト → ビルド → デプロイ) | [ ] |
| 課題4 | 手動実行ワークフロー | [ ] |
まとめ
| ポイント | 内容 |
|---|---|
| CI | PRトリガーで Lint + テスト + ビルドを自動実行 |
| CD | mainへのpushでテスト → ビルド → デプロイを自動化 |
| アーティファクト | ジョブ間でビルド成果物を受け渡し |
| 手動実行 | workflow_dispatch で緊急時の手動デプロイに対応 |
チェックリスト
- CI用ワークフローを作成できた
-
needsでジョブの依存関係を設定できた - アーティファクトのアップロード/ダウンロードを実装できた
- CDワークフローでデプロイジョブを構成できた
- workflow_dispatch で手動実行ワークフローを作成できた
次のステップへ
演習が完了したら、Step 2 のチェックポイントクイズに挑戦しましょう。
推定所要時間: 60分