github-research-tool/features/05-github-actions.md
marketing-shibata50 59b60ace06 feat: add comprehensive GitHub guides expansion
🆕 New Guides Added:
- GitHub Actions complete guide (CI/CD automation)
- GitHub Security comprehensive guide (enterprise security)
- GitHub Pages detailed guide (website publishing)

🔗 Navigation Improvements:
- Updated index.md with all 7 guides
- Added cross-navigation between all guides
- Enhanced learning paths for different user types
- Comprehensive learning flow diagrams

📚 Content Highlights:
- Jenkins/CircleCI migration strategies
- Enterprise security best practices
- WordPress to GitHub Pages migration
- Advanced automation workflows
- Complete external tool replacements

🎯 User Experience:
- Role-based learning recommendations
- Consistent navigation structure
- Progressive learning paths
- Cross-reference linking

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-20 13:22:23 +09:00

1681 lines
No EOL
45 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
layout: default
title: "GitHub Actions完全ガイド"
description: "Jenkins・CircleCI代替のCI/CD自動化とGitHub Actions完全活用法"
---
# ⚡ GitHub Actions - 完全なCI/CD自動化
GitHub Actionsを活用して、Jenkins・CircleCI・GitLab CI・Azure DevOpsなどの外部CI/CDツールに依存しない、統合された自動化環境を構築する完全ガイド。コードのビルド・テスト・デプロイから、複雑なワークフロー自動化まで網羅します。
## 🎯 学習目標
- GitHub Actions の全機能理解と実践的活用
- 外部CI/CDツールからの完全移行戦略
- セキュアで効率的なワークフロー設計
- 高度な自動化とDevOps実践
- コスト最適化と運用効率向上
## 📚 目次
1. [GitHub Actions 基本概念](#1-github-actions-基本概念)
2. [CI/CDパイプライン構築](#2-cicdパイプライン構築)
3. [高度なワークフロー設計](#3-高度なワークフロー設計)
4. [セキュリティ・シークレット管理](#4-セキュリティシークレット管理)
5. [外部ツールからの移行](#5-外部ツールからの移行)
6. [運用最適化・監視](#6-運用最適化監視)
---
## 1. GitHub Actions 基本概念
### 🏗️ アーキテクチャ理解
#### 核心コンポーネント
```yaml
# GitHub Actions の基本構造
Workflow (ワークフロー)
├── Events (イベント) - トリガー条件
├── Jobs (ジョブ) - 実行単位
│ ├── Steps (ステップ) - 個別タスク
│ │ ├── Actions (アクション) - 再利用可能な処理
│ │ └── Commands (コマンド) - シェル実行
│ └── Runner (ランナー) - 実行環境
├── Secrets (シークレット) - 機密情報
└── Environment (環境) - デプロイメント設定
```
#### 基本ワークフロー例
```yaml
# .github/workflows/basic-ci.yml
name: Basic CI Pipeline
# イベント定義
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 2 * * 1' # 毎週月曜 2時
# グローバル環境変数
env:
NODE_VERSION: '18'
CACHE_KEY: node-modules
jobs:
# ジョブ1: コード品質チェック
quality-check:
name: Code Quality
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint check
run: npm run lint
- name: Type check
run: npm run type-check
- name: Security audit
run: npm audit --audit-level high
# ジョブ2: テスト実行
test:
name: Test Suite
runs-on: ubuntu-latest
needs: quality-check
strategy:
matrix:
node-version: [16, 18, 20]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test:coverage
env:
CI: true
- name: Upload coverage
uses: codecov/codecov-action@v3
if: matrix.node-version == 18 && matrix.os == 'ubuntu-latest'
with:
token: ${{ secrets.CODECOV_TOKEN }}
```
### 🎛️ イベントトリガーの活用
#### 包括的なトリガー設定
```yaml
# 高度なイベント設定例
on:
# プッシュイベント
push:
branches:
- main
- 'release/**'
- 'hotfix/**'
paths:
- 'src/**'
- 'package.json'
- '.github/workflows/**'
tags:
- 'v*'
# プルリクエストイベント
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches: [main, develop]
paths-ignore:
- 'docs/**'
- '*.md'
# Issue イベント
issues:
types: [opened, labeled, assigned]
# リリースイベント
release:
types: [published, prereleased]
# スケジュール実行
schedule:
- cron: '0 2 * * 1-5' # 平日 2時
- cron: '0 10 * * 6' # 土曜 10時
# 手動実行
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
debug:
description: 'Enable debug logging'
required: false
default: false
type: boolean
version:
description: 'Version to deploy'
required: false
type: string
# 他のワークフローからの呼び出し
workflow_call:
inputs:
config-path:
required: true
type: string
secrets:
api-key:
required: true
```
---
## 2. CI/CDパイプライン構築
### 🔄 フルスタックCI/CDパイプライン
#### Node.js アプリケーション用
```yaml
# .github/workflows/nodejs-cicd.yml
name: Node.js CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# ステージ1: ビルド・テスト
build-and-test:
name: Build and Test
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
image-digest: ${{ steps.build.outputs.digest }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Generate version
id: version
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
else
VERSION=$(git describe --tags --always --dirty)
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run type checking
run: npm run type-check
- name: Run unit tests
run: npm run test:unit -- --coverage
- name: Run integration tests
run: npm run test:integration
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
- name: Build application
run: npm run build
env:
NODE_ENV: production
VERSION: ${{ steps.version.outputs.version }}
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: |
dist/
package.json
package-lock.json
retention-days: 7
# ステージ2: セキュリティスキャン
security-scan:
name: Security Scanning
runs-on: ubuntu-latest
needs: build-and-test
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
- name: OWASP Dependency Check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'my-project'
path: '.'
format: 'SARIF'
args: >
--enableRetired
--enableExperimental
--failOnCVSS 7
# ステージ3: E2Eテスト
e2e-tests:
name: E2E Tests
runs-on: ubuntu-latest
needs: build-and-test
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: testdb
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
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Setup test database
run: |
npm run db:migrate
npm run db:seed
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
- name: Install Playwright
run: npx playwright install --with-deps
- name: Start application
run: |
npm start &
npx wait-on http://localhost:3000 --timeout 60000
env:
NODE_ENV: test
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
REDIS_URL: redis://localhost:6379
- name: Run E2E tests
run: npm run test:e2e
env:
BASE_URL: http://localhost:3000
- name: Upload test results
uses: actions/upload-artifact@v3
if: failure()
with:
name: e2e-results
path: |
test-results/
playwright-report/
# ステージ4: Dockerイメージビルド
build-image:
name: Build Docker Image
runs-on: ubuntu-latest
needs: [build-and-test, security-scan]
if: github.event_name == 'push'
permissions:
contents: read
packages: write
outputs:
image: ${{ steps.image.outputs.image }}
digest: ${{ steps.build.outputs.digest }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
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 image
id: build
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ needs.build-and-test.outputs.version }}
- name: Output image
id: image
run: echo "image=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build-and-test.outputs.version }}" >> $GITHUB_OUTPUT
# ステージ5: ステージング環境デプロイ
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: [build-image, e2e-tests]
if: github.ref == 'refs/heads/develop'
environment:
name: staging
url: https://staging.example.com
steps:
- name: Deploy to staging
uses: azure/webapps-deploy@v2
with:
app-name: 'my-app-staging'
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE_STAGING }}
images: ${{ needs.build-image.outputs.image }}
- name: Run smoke tests
run: |
curl -f https://staging.example.com/health || exit 1
curl -f https://staging.example.com/api/status || exit 1
# ステージ6: 本番環境デプロイ
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [build-image, deploy-staging]
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://example.com
steps:
- name: Deploy to production
uses: azure/webapps-deploy@v2
with:
app-name: 'my-app-production'
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE_PRODUCTION }}
images: ${{ needs.build-image.outputs.image }}
- name: Run production smoke tests
run: |
curl -f https://example.com/health || exit 1
curl -f https://example.com/api/status || exit 1
- name: Notify deployment
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
channel: '#deployments'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
if: always()
```
### 🐍 Python アプリケーション用
```yaml
# .github/workflows/python-cicd.yml
name: Python CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
name: Test Suite
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: testdb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Lint with flake8
run: |
flake8 src/ tests/ --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 src/ tests/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Type check with mypy
run: mypy src/
- name: Test with pytest
run: |
pytest tests/ --cov=src/ --cov-report=xml --cov-report=html
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
security:
name: Security Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install safety bandit
- name: Run safety check
run: safety check
- name: Run bandit security check
run: bandit -r src/ -f json -o bandit-report.json
- name: Upload security scan results
uses: actions/upload-artifact@v3
if: failure()
with:
name: security-reports
path: bandit-report.json
build-and-deploy:
name: Build and Deploy
runs-on: ubuntu-latest
needs: [test, security]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Build package
run: |
python -m pip install --upgrade pip build
python -m build
- name: Deploy to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
```
---
## 3. 高度なワークフロー設計
### 🔄 再利用可能ワークフロー
#### 共通CI/CDテンプレート
```yaml
# .github/workflows/reusable-ci.yml
name: Reusable CI Workflow
on:
workflow_call:
inputs:
node-version:
required: false
type: string
default: '18'
environment:
required: false
type: string
default: 'development'
run-e2e:
required: false
type: boolean
default: false
secrets:
NPM_TOKEN:
required: false
CODECOV_TOKEN:
required: false
outputs:
build-version:
description: "Built application version"
value: ${{ jobs.build.outputs.version }}
artifact-name:
description: "Build artifact name"
value: ${{ jobs.build.outputs.artifact-name }}
jobs:
build:
name: Build and Test
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
artifact-name: ${{ steps.artifact.outputs.name }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
- name: Generate version
id: version
run: |
VERSION=$(date +%Y%m%d)-$(git rev-parse --short HEAD)
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Install dependencies
run: npm ci
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Run tests
run: npm run test:coverage
- name: Upload coverage
if: secrets.CODECOV_TOKEN != ''
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Build application
run: npm run build
env:
NODE_ENV: ${{ inputs.environment }}
VERSION: ${{ steps.version.outputs.version }}
- name: Create artifact
id: artifact
run: |
ARTIFACT_NAME="build-${{ steps.version.outputs.version }}"
echo "name=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact.outputs.name }}
path: dist/
e2e-tests:
name: E2E Tests
runs-on: ubuntu-latest
needs: build
if: inputs.run-e2e
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: ${{ needs.build.outputs.artifact-name }}
path: dist/
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run E2E tests
run: npm run test:e2e
```
#### ワークフローの呼び出し
```yaml
# .github/workflows/main-ci.yml
name: Main CI Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
ci:
name: Continuous Integration
uses: ./.github/workflows/reusable-ci.yml
with:
node-version: '18'
environment: 'production'
run-e2e: true
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
deploy:
name: Deploy Application
runs-on: ubuntu-latest
needs: ci
if: github.ref == 'refs/heads/main'
steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: ${{ needs.ci.outputs.artifact-name }}
- name: Deploy to production
run: |
echo "Deploying version ${{ needs.ci.outputs.build-version }}"
# デプロイメントロジック
```
### 🎯 コンポジットアクション
#### カスタムアクション作成
```yaml
# .github/actions/setup-app/action.yml
name: 'Setup Application'
description: 'Setup Node.js application with caching and dependencies'
inputs:
node-version:
description: 'Node.js version to use'
required: false
default: '18'
cache-dependency-path:
description: 'Path to dependency file'
required: false
default: 'package-lock.json'
install-command:
description: 'Command to install dependencies'
required: false
default: 'npm ci'
outputs:
cache-hit:
description: 'Cache hit status'
value: ${{ steps.cache.outputs.cache-hit }}
node-version:
description: 'Installed Node.js version'
value: ${{ steps.setup-node.outputs.node-version }}
runs:
using: 'composite'
steps:
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
cache-dependency-path: ${{ inputs.cache-dependency-path }}
- name: Cache node modules
id: cache
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles(inputs.cache-dependency-path) }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
shell: bash
run: ${{ inputs.install-command }}
env:
NODE_AUTH_TOKEN: ${{ env.NODE_AUTH_TOKEN }}
- name: Verify installation
shell: bash
run: |
echo "Node.js version: $(node --version)"
echo "npm version: $(npm --version)"
echo "Dependencies installed successfully"
```
#### アクションの使用
```yaml
# ワークフローでの使用例
steps:
- uses: actions/checkout@v4
- name: Setup application
uses: ./.github/actions/setup-app
with:
node-version: '18'
install-command: 'npm ci --production'
- name: Build application
run: npm run build
```
---
## 4. セキュリティ・シークレット管理
### 🔐 シークレット管理戦略
#### 環境別シークレット設定
```yaml
# セキュリティベストプラクティス
name: Secure Deployment
on:
push:
branches: [main]
jobs:
deploy:
name: Secure Deployment
runs-on: ubuntu-latest
# 環境の設定
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v4
- 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: ${{ vars.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
role-session-name: GitHubActions
- 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: ${{ vars.ECR_REPOSITORY }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster ${{ vars.ECS_CLUSTER }} \
--service ${{ vars.ECS_SERVICE }} \
--force-new-deployment
```
#### OIDC プロバイダー認証
```yaml
# クラウドプロバイダーとのOIDC認証
name: OIDC Authentication
on:
push:
branches: [main]
permissions:
id-token: write # OIDC トークン取得に必要
contents: read
jobs:
deploy-aws:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
role-session-name: GitHubActions
aws-region: us-east-1
- name: Deploy to AWS
run: |
aws s3 sync ./dist s3://${{ vars.S3_BUCKET }}/
deploy-azure:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy to Azure
run: |
az webapp deployment source config-zip \
--resource-group ${{ vars.AZURE_RESOURCE_GROUP }} \
--name ${{ vars.AZURE_APP_NAME }} \
--src ./dist.zip
```
### 🛡️ セキュリティスキャン自動化
#### 包括的セキュリティチェック
```yaml
# .github/workflows/security-scan.yml
name: Security Scanning
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 3 * * 1' # 毎週月曜 3時
permissions:
security-events: write
contents: read
jobs:
code-scanning:
name: Code Scanning
runs-on: ubuntu-latest
strategy:
matrix:
language: ['javascript', 'python']
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: security-extended,security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
dependency-scanning:
name: Dependency Scanning
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
- name: Snyk security scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high --sarif-file-output=snyk.sarif
- name: Upload Snyk results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: snyk.sarif
container-scanning:
name: Container Scanning
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t test-image .
- name: Run Trivy container scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'test-image'
format: 'sarif'
output: 'trivy-container.sarif'
- name: Upload container scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-container.sarif'
secret-scanning:
name: Secret Scanning
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: TruffleHog OSS
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: main
head: HEAD
extra_args: --debug --only-verified
```
---
## 5. 外部ツールからの移行
### 🔄 Jenkins からの移行
#### Jenkinsfile → GitHub Actions 変換例
```groovy
// 元のJenkinsfile
pipeline {
agent any
environment {
NODE_VERSION = '18'
DOCKER_REGISTRY = 'myregistry.com'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'npm run test:unit'
}
post {
always {
publishTestResults testResultsPattern: 'test-results.xml'
}
}
}
stage('E2E Tests') {
steps {
sh 'npm run test:e2e'
}
}
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh 'docker build -t $DOCKER_REGISTRY/myapp:$BUILD_NUMBER .'
sh 'docker push $DOCKER_REGISTRY/myapp:$BUILD_NUMBER'
}
}
}
post {
always {
cleanWs()
}
failure {
mail to: 'team@example.com',
subject: "Build Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
body: "Build failed. Check console output."
}
}
}
```
```yaml
# 変換後のGitHub Actions
name: Migrated from Jenkins
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '18'
DOCKER_REGISTRY: 'myregistry.com'
jobs:
build:
name: Build Application
runs-on: ubuntu-latest
outputs:
build-number: ${{ steps.build-number.outputs.number }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate build number
id: build-number
run: echo "number=${{ github.run_number }}" >> $GITHUB_OUTPUT
- 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 application
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: dist/
test:
name: Test Suite
runs-on: ubuntu-latest
needs: build
strategy:
matrix:
test-type: [unit, e2e]
steps:
- 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: Download artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
path: dist/
- name: Run tests
run: npm run test:${{ matrix.test-type }}
- name: Publish test results
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: ${{ matrix.test-type }} Tests
path: test-results.xml
reporter: jest-junit
deploy:
name: Deploy Application
runs-on: ubuntu-latest
needs: [build, test]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ env.DOCKER_REGISTRY }}/myapp:${{ needs.build.outputs.build-number }}
- name: Notify on failure
if: failure()
uses: 8398a7/action-slack@v3
with:
status: failure
channel: '#alerts'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
message: |
Build Failed: ${{ github.workflow }} - ${{ github.run_number }}
Check the console output for details.
```
### 📊 移行比較表
| 機能 | Jenkins | CircleCI | GitLab CI | GitHub Actions | 備考 |
|------|---------|----------|-----------|----------------|------|
| **セットアップ** | 複雑 | 簡単 | 中程度 | 最も簡単 | GitHub統合 |
| **設定ファイル** | Groovy | YAML | YAML | YAML | GitHub Actionsが最も直感的 |
| **並列実行** | ✅ | ✅ | ✅ | ✅ | matrix戦略が優秀 |
| **キャッシュ** | プラグイン | ✅ | ✅ | ✅ | 設定が最もシンプル |
| **シークレット管理** | プラグイン | ✅ | ✅ | ✅ | 環境別管理が優秀 |
| **コスト(中規模)** | 高 | 中 | 中 | 低 | 無料枠が大きい |
| **学習コスト** | 高 | 中 | 中 | 低 | 広く普及 |
| **拡張性** | 高 | 中 | 高 | 高 | Marketplaceが充実 |
---
## 6. 運用最適化・監視
### 📊 パフォーマンス最適化
#### 高速ビルド戦略
```yaml
# .github/workflows/optimized-ci.yml
name: Optimized CI Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
frontend: ${{ steps.changes.outputs.frontend }}
backend: ${{ steps.changes.outputs.backend }}
docs: ${{ steps.changes.outputs.docs }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v2
id: changes
with:
filters: |
frontend:
- 'frontend/**'
- 'package.json'
backend:
- 'backend/**'
- 'requirements.txt'
docs:
- 'docs/**'
- '*.md'
frontend-ci:
name: Frontend CI
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.frontend == 'true'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js with cache
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: 'frontend/package-lock.json'
- name: Restore node_modules cache
uses: actions/cache@v3
with:
path: frontend/node_modules
key: ${{ runner.os }}-nodemodules-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-nodemodules-
- name: Install dependencies
run: npm ci --prefix frontend
- name: Parallel build and test
run: |
npm run build --prefix frontend &
npm run test --prefix frontend &
wait
backend-ci:
name: Backend CI
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.backend == 'true'
steps:
- uses: actions/checkout@v4
- name: Setup Python with cache
uses: actions/setup-python@v4
with:
python-version: '3.11'
cache: 'pip'
cache-dependency-path: 'backend/requirements.txt'
- name: Install dependencies
run: |
cd backend
pip install -r requirements.txt
- name: Run tests
run: |
cd backend
pytest --maxfail=1 --disable-warnings -q
docs-check:
name: Documentation Check
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.docs == 'true'
steps:
- uses: actions/checkout@v4
- name: Check documentation
run: |
# ドキュメントの軽量チェック
echo "Checking documentation..."
# 実際のドキュメントビルド・リンクチェック等
```
### 📈 モニタリング・メトリクス
#### 詳細メトリクス収集
```yaml
# .github/workflows/metrics-collection.yml
name: CI/CD Metrics Collection
on:
workflow_run:
workflows: ["Main CI", "Deploy Pipeline"]
types: [completed]
jobs:
collect-metrics:
name: Collect CI/CD Metrics
runs-on: ubuntu-latest
steps:
- name: Collect workflow metrics
uses: actions/github-script@v6
with:
script: |
const workflowRun = context.payload.workflow_run;
// ワークフロー実行時間の計算
const startTime = new Date(workflowRun.created_at);
const endTime = new Date(workflowRun.updated_at);
const duration = (endTime - startTime) / 1000; // 秒
// メトリクスデータの作成
const metrics = {
workflow_name: workflowRun.name,
status: workflowRun.conclusion,
duration_seconds: duration,
commit_sha: workflowRun.head_sha,
branch: workflowRun.head_branch,
trigger_event: workflowRun.event,
run_number: workflowRun.run_number,
timestamp: workflowRun.created_at
};
// メトリクスをログ出力
console.log('CI/CD Metrics:', JSON.stringify(metrics, null, 2));
// 外部監視システムに送信DataDog、Prometheus等
if (process.env.DATADOG_API_KEY) {
await fetch('https://api.datadoghq.com/api/v1/series', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'DD-API-KEY': process.env.DATADOG_API_KEY
},
body: JSON.stringify({
series: [{
metric: 'github_actions.workflow.duration',
points: [[Math.floor(Date.now() / 1000), duration]],
tags: [
`workflow:${workflowRun.name}`,
`status:${workflowRun.conclusion}`,
`branch:${workflowRun.head_branch}`
]
}]
})
});
}
env:
DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}
- name: Generate weekly report
if: github.event.schedule == '0 9 * * 1' # 毎週月曜日
uses: actions/github-script@v6
with:
script: |
// 過去1週間のワークフロー実行データを取得
const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100,
created: `>=${new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString()}`
});
// メトリクス集計
const metrics = runs.workflow_runs.reduce((acc, run) => {
const duration = (new Date(run.updated_at) - new Date(run.created_at)) / 1000;
if (!acc[run.name]) {
acc[run.name] = {
total_runs: 0,
successful_runs: 0,
failed_runs: 0,
total_duration: 0,
avg_duration: 0
};
}
acc[run.name].total_runs++;
acc[run.name].total_duration += duration;
if (run.conclusion === 'success') {
acc[run.name].successful_runs++;
} else if (run.conclusion === 'failure') {
acc[run.name].failed_runs++;
}
acc[run.name].avg_duration = acc[run.name].total_duration / acc[run.name].total_runs;
return acc;
}, {});
// レポート生成
let report = '# GitHub Actions Weekly Report\n\n';
for (const [workflow, data] of Object.entries(metrics)) {
const successRate = ((data.successful_runs / data.total_runs) * 100).toFixed(2);
report += `## ${workflow}\n`;
report += `- **Total Runs**: ${data.total_runs}\n`;
report += `- **Success Rate**: ${successRate}%\n`;
report += `- **Average Duration**: ${Math.round(data.avg_duration)}s\n`;
report += `- **Failed Runs**: ${data.failed_runs}\n\n`;
}
// Issueとしてレポートを投稿
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Weekly CI/CD Report - ${new Date().toISOString().split('T')[0]}`,
body: report,
labels: ['metrics', 'weekly-report']
});
```
---
## 🎓 実践演習
### 演習1: フルスタックCI/CDパイプライン構築
1. **多言語対応** - Node.js + Python のモノレポ
2. **並列実行** - 言語別の独立したジョブ
3. **条件分岐** - 変更検知による最適化
4. **成果物管理** - アーティファクトの効率的な受け渡し
### 演習2: セキュリティファーストパイプライン
1. **コード解析** - CodeQL・Semgrep統合
2. **依存関係スキャン** - Snyk・Trivy活用
3. **シークレット検知** - TruffleHog導入
4. **コンテナセキュリティ** - イメージスキャン自動化
### 演習3: 外部ツール移行プロジェクト
1. **現状分析** - 既存CI/CDの機能・設定調査
2. **移行戦略** - 段階的移行計画立案
3. **並行運用** - リスク軽減・検証期間設定
4. **完全移行** - 旧システム停止・運用移管
---
## 🔗 関連リソース
### 公式ドキュメント
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
- [Workflow Syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
- [GitHub Actions Marketplace](https://github.com/marketplace?type=actions)
### 移行・活用ツール
- [Jenkins to GitHub Actions Migration](https://github.com/actions/importer)
- [Actions Toolkit](https://github.com/actions/toolkit)
- [Runner Images](https://github.com/actions/runner-images)
### 監視・最適化ツール
- [ActionLint](https://github.com/rhymond/actionlint) - ワークフロー検証
- [GitHub Actions Usage Metrics](https://github.com/github/actions-usage-metrics)
- [Workflow Optimization Guide](https://docs.github.com/en/actions/using-workflows/about-workflows#using-starter-workflows)
---
## 📝 まとめ
GitHub Actions を効果的に活用することで:
**外部ツール不要** - Jenkins・CircleCIからの完全移行
**コスト大幅削減** - インフラ・ライセンス費用の最適化
**統合開発環境** - コードとCI/CDの一元管理
**高度な自動化** - セキュリティ・品質・デプロイの自動化
**スケーラビリティ** - 企業レベルの大規模開発対応
次は[GitHub Security編](06-github-security.md)で、総合的なセキュリティ対策を学習しましょう。
## 🔗 関連ガイド
- **前のステップ**: [GitHub Projects編](04-github-projects.md) - プロジェクト管理の最適化
- **次のステップ**: [GitHub Security編](06-github-security.md) - 総合的なセキュリティ対策
- **さらに学習**: [GitHub Pages編](07-github-pages.md) - Webサイト・ドキュメント公開
- **基礎知識**: [Pull Request編](03-pull-requests.md) - CI/CD連携の基礎
- **総合ガイド**: [GitHub完全活用ガイド](../GITHUB_COMPLETE_GUIDE.md) - 全機能の詳細解説
## 📖 学習フロー
```mermaid
graph LR
A[リポジトリ基礎] --> B[Issues管理]
B --> C[Pull Request]
C --> D[GitHub Projects]
D --> E[GitHub Actions]
E --> F[Security]
F --> G[Pages]
G --> H[完全活用]
style A fill:#f3e5f5
style B fill:#f3e5f5
style C fill:#f3e5f5
style D fill:#f3e5f5
style E fill:#e1f5fe
style F fill:#e8f5e8
style G fill:#fff3e0
style H fill:#fce4ec
```