GitHub Actions上級ガイド2026
関連記事: GitHub Actions上級テクニック完全ガイド2026では基本的な上級テクニックを解説しています。本記事ではセルフホストランナー、Composite Actions、高度なキャッシュ戦略など、さらに踏み込んだ内容を扱います。
GitHub Actionsは、CI/CDパイプラインの構築に最も広く使われているプラットフォームの一つです。基本的なテスト・ビルド・デプロイのワークフローから一歩進み、マトリックスビルド、高度なキャッシュ戦略、セルフホストランナー、Reusable Workflowsなどの上級テクニックを活用することで、パイプラインの実行速度とメンテナンス性を大幅に改善できます。
本記事では、GitHub Actionsの上級テクニックを実践的なコード例とともに徹底解説します。
マトリックスビルド
基本的なマトリックス戦略
マトリックスビルドを使うと、複数のOS、ランタイムバージョン、設定の組み合わせを自動的に並列実行できます。
# .github/workflows/test-matrix.yml
name: Test Matrix
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
# 1つのジョブが失敗しても他を継続
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [18, 20, 22]
# 特定の組み合わせを除外
exclude:
- os: windows-latest
node-version: 18
# 特定の組み合わせを追加(追加設定付き)
include:
- os: ubuntu-latest
node-version: 22
coverage: true
experimental: false
- os: ubuntu-latest
node-version: 23
experimental: true
# experimentalフラグがtrueの場合は失敗を許容
continue-on-error: ${{ matrix.experimental || false }}
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'
- run: npm ci
- run: npm test
- name: Upload coverage
if: matrix.coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
動的マトリックス
マトリックスの値をジョブの出力から動的に生成できます。
name: Dynamic Matrix
on:
push:
branches: [main]
jobs:
# Step 1: 変更されたパッケージを検出
detect-changes:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.changes.outputs.packages }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: changes
run: |
# 変更されたパッケージを検出してJSON配列として出力
CHANGED_PACKAGES=$(git diff --name-only HEAD~1 HEAD | \
grep '^packages/' | \
cut -d'/' -f2 | \
sort -u | \
jq -R -s -c 'split("\n")[:-1]')
echo "packages=$CHANGED_PACKAGES" >> $GITHUB_OUTPUT
echo "Changed packages: $CHANGED_PACKAGES"
# Step 2: 変更されたパッケージのみテスト
test:
needs: detect-changes
if: needs.detect-changes.outputs.packages != '[]'
runs-on: ubuntu-latest
strategy:
matrix:
package: ${{ fromJSON(needs.detect-changes.outputs.packages) }}
steps:
- uses: actions/checkout@v4
- name: Test ${{ matrix.package }}
run: |
cd packages/${{ matrix.package }}
npm ci
npm test
マトリックスの最大並列数制御
jobs:
test:
runs-on: ubuntu-latest
strategy:
# 同時実行数を制限(APIレート制限対策等)
max-parallel: 3
matrix:
shard: [1, 2, 3, 4, 5, 6]
steps:
- uses: actions/checkout@v4
- run: npm ci
- name: Run tests (shard ${{ matrix.shard }}/6)
run: |
npx vitest --shard=${{ matrix.shard }}/6
高度なキャッシュ戦略
依存関係キャッシュの最適化
name: Optimized Cache
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# npm キャッシュ(actions/setup-node内蔵)
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
# より高度なキャッシュ: node_modulesを直接キャッシュ
- name: Cache node_modules
id: cache-deps
uses: actions/cache@v4
with:
path: node_modules
key: deps-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
# フォールバックキー
restore-keys: |
deps-${{ runner.os }}-
# キャッシュミス時のみinstall
- name: Install dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
run: npm ci
- run: npm run build
- run: npm test
ビルド成果物のキャッシュ
name: Build Cache
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
# Next.jsビルドキャッシュ
- name: Cache Next.js build
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/.next/cache
key: nextjs-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-${{ hashFiles('**/*.ts', '**/*.tsx') }}
restore-keys: |
nextjs-${{ runner.os }}-${{ hashFiles('package-lock.json') }}-
nextjs-${{ runner.os }}-
# Turborepoキャッシュ(モノレポ用)
- name: Cache Turborepo
uses: actions/cache@v4
with:
path: .turbo
key: turbo-${{ runner.os }}-${{ github.sha }}
restore-keys: |
turbo-${{ runner.os }}-
- run: npm ci
- run: npm run build
test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm test
Docker Layerキャッシュ
name: Docker Build
on:
push:
branches: [main]
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Docker Buildxセットアップ
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Docker Hubログイン
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# キャッシュ付きビルド&プッシュ
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: myapp:latest,myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
# マルチプラットフォーム
platforms: linux/amd64,linux/arm64
セルフホストランナー
セルフホストランナーの設置
# Linux (x64) へのランナーインストール
mkdir actions-runner && cd actions-runner
# ダウンロード
curl -o actions-runner-linux-x64-2.320.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.320.0/actions-runner-linux-x64-2.320.0.tar.gz
tar xzf ./actions-runner-linux-x64-2.320.0.tar.gz
# 設定(GitHubリポジトリURLとトークンが必要)
./config.sh --url https://github.com/YOUR_ORG/YOUR_REPO \
--token YOUR_RUNNER_TOKEN \
--labels self-hosted,linux,x64,gpu \
--name my-runner-01
# サービスとしてインストール・起動
sudo ./svc.sh install
sudo ./svc.sh start
セルフホストランナーの活用
name: GPU Training
on:
workflow_dispatch:
inputs:
model:
description: 'Model to train'
required: true
type: choice
options:
- resnet50
- bert-base
- gpt2-small
jobs:
train:
# セルフホストランナーをラベルで指定
runs-on: [self-hosted, linux, gpu]
timeout-minutes: 360
steps:
- uses: actions/checkout@v4
- name: Check GPU
run: nvidia-smi
- name: Train model
run: |
python train.py \
--model ${{ github.event.inputs.model }} \
--epochs 100 \
--batch-size 32
- name: Upload model artifacts
uses: actions/upload-artifact@v4
with:
name: model-${{ github.event.inputs.model }}
path: output/model.*
retention-days: 30
Kubernetes上のセルフホストランナー(ARC)
# actions-runner-controller のHelmチャート設定
# helm-values.yaml
githubConfigUrl: "https://github.com/YOUR_ORG"
githubConfigSecret:
github_token: "ghp_xxxxx"
containerMode:
type: "kubernetes"
template:
spec:
containers:
- name: runner
image: ghcr.io/actions/actions-runner:latest
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
cpu: "4"
memory: "8Gi"
volumeMounts:
- name: work
mountPath: /home/runner/_work
volumes:
- name: work
ephemeral:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
maxRunners: 10
minRunners: 2
# ARC のインストール
helm install arc \
--namespace arc-systems \
--create-namespace \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
helm install arc-runner-set \
--namespace arc-runners \
--create-namespace \
-f helm-values.yaml \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
Reusable Workflows
再利用可能なワークフローの定義
# .github/workflows/reusable-deploy.yml
name: Reusable Deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
description: 'Target environment (staging/production)'
version:
required: true
type: string
description: 'Version to deploy'
dry-run:
required: false
type: boolean
default: false
secrets:
DEPLOY_KEY:
required: true
SLACK_WEBHOOK:
required: false
outputs:
deploy-url:
description: "Deployed URL"
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
with:
ref: ${{ inputs.version }}
- name: Setup
run: |
echo "Deploying version ${{ inputs.version }} to ${{ inputs.environment }}"
echo "Dry run: ${{ inputs.dry-run }}"
- name: Deploy
id: deploy
if: ${{ !inputs.dry-run }}
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: |
# デプロイスクリプト実行
./scripts/deploy.sh ${{ inputs.environment }}
echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUT
- name: Notify Slack
if: ${{ !inputs.dry-run && secrets.SLACK_WEBHOOK }}
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
-H 'Content-type: application/json' \
-d '{
"text": "Deployed ${{ inputs.version }} to ${{ inputs.environment }}: ${{ steps.deploy.outputs.url }}"
}'
再利用可能なワークフローの呼び出し
# .github/workflows/release.yml
name: Release Pipeline
on:
push:
tags: ['v*']
jobs:
test:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: 22
deploy-staging:
needs: test
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
version: ${{ github.ref_name }}
secrets:
DEPLOY_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
# ステージングデプロイ後にE2Eテスト
e2e-test:
needs: deploy-staging
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
echo "Testing against ${{ needs.deploy-staging.outputs.deploy-url }}"
npm run test:e2e -- --base-url=${{ needs.deploy-staging.outputs.deploy-url }}
deploy-production:
needs: [deploy-staging, e2e-test]
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
version: ${{ github.ref_name }}
secrets:
DEPLOY_KEY: ${{ secrets.PRODUCTION_DEPLOY_KEY }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
Composite Actions
カスタムアクションの作成
# .github/actions/setup-project/action.yml
name: 'Setup Project'
description: 'Setup Node.js project with caching'
inputs:
node-version:
description: 'Node.js version'
required: false
default: '22'
install-playwright:
description: 'Install Playwright browsers'
required: false
default: 'false'
outputs:
cache-hit:
description: 'Whether cache was hit'
value: ${{ steps.cache.outputs.cache-hit }}
runs:
using: 'composite'
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Cache dependencies
id: cache
uses: actions/cache@v4
with:
path: |
node_modules
~/.cache/ms-playwright
key: project-${{ runner.os }}-node${{ inputs.node-version }}-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
run: npm ci
- name: Install Playwright
if: inputs.install-playwright == 'true' && steps.cache.outputs.cache-hit != 'true'
shell: bash
run: npx playwright install --with-deps chromium
- name: Verify installation
shell: bash
run: |
echo "Node.js $(node --version)"
echo "npm $(npm --version)"
echo "Dependencies installed: $(ls node_modules | wc -l) packages"
Composite Actionの使用
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
- run: npm test
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
with:
install-playwright: 'true'
- run: npm run test:e2e
セキュリティ強化
シークレットの管理
name: Secure Pipeline
on:
push:
branches: [main]
# ジョブレベルの権限設定(最小権限の原則)
permissions:
contents: read
packages: write
id-token: write # OIDC認証用
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # Environment保護ルール適用
steps:
- uses: actions/checkout@v4
# OIDC認証(シークレット不要でAWSにアクセス)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions
aws-region: ap-northeast-1
# ステップ間でシークレットをマスク
- name: Fetch secret
id: secret
run: |
SECRET=$(aws secretsmanager get-secret-value \
--secret-id my-app/production \
--query SecretString --output text)
echo "::add-mask::$SECRET"
echo "value=$SECRET" >> $GITHUB_OUTPUT
依存関係のピン留め
# セキュリティのためアクションのバージョンをSHAでピン留め
jobs:
build:
runs-on: ubuntu-latest
steps:
# タグ指定(便利だが改竄リスクあり)
# - uses: actions/checkout@v4
# SHA指定(改竄不可能)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 22
Dependabotとの連携
# .github/dependabot.yml
version: 2
updates:
# npmパッケージの更新
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
groups:
development-dependencies:
dependency-type: "development"
production-dependencies:
dependency-type: "production"
# GitHub Actionsの更新
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
# 自動マージ設定
open-pull-requests-limit: 10
# .github/workflows/dependabot-auto-merge.yml
name: Dependabot Auto Merge
on: pull_request
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
if: github.actor == 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- name: Fetch Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# パッチ・マイナーアップデートのみ自動マージ
- name: Auto-merge minor/patch updates
if: >
steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
steps.metadata.outputs.update-type == 'version-update:semver-minor'
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
高度なワークフロー制御
Concurrency制御
name: Deploy
on:
push:
branches: [main]
# 同一ブランチへの同時デプロイを防止
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: true # 新しいデプロイが来たら古いのをキャンセル
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh
条件分岐とパスフィルタ
name: Smart CI
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/ISSUE_TEMPLATE/**'
pull_request:
paths:
- 'src/**'
- 'tests/**'
- 'package.json'
- 'package-lock.json'
jobs:
# 変更内容に応じてジョブを条件分岐
changes:
runs-on: ubuntu-latest
outputs:
frontend: ${{ steps.filter.outputs.frontend }}
backend: ${{ steps.filter.outputs.backend }}
infra: ${{ steps.filter.outputs.infra }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
frontend:
- 'src/frontend/**'
- 'src/components/**'
backend:
- 'src/api/**'
- 'src/lib/**'
- 'prisma/**'
infra:
- 'terraform/**'
- 'Dockerfile'
- 'docker-compose.yml'
frontend-test:
needs: changes
if: needs.changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run test:frontend
backend-test:
needs: changes
if: needs.changes.outputs.backend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run test:backend
infra-validate:
needs: changes
if: needs.changes.outputs.infra == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: terraform validate
ワークフローの手動トリガーとAPI呼び出し
name: Manual Operations
on:
workflow_dispatch:
inputs:
operation:
description: '実行する操作'
required: true
type: choice
options:
- database-migration
- cache-clear
- rollback
target:
description: '対象環境'
required: true
type: environment
confirm:
description: '本当に実行しますか? (yes と入力)'
required: true
type: string
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Validate confirmation
if: github.event.inputs.confirm != 'yes'
run: |
echo "::error::確認が'yes'ではありません。操作を中止します。"
exit 1
execute:
needs: validate
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.target }}
steps:
- uses: actions/checkout@v4
- name: Execute operation
run: |
case "${{ github.event.inputs.operation }}" in
database-migration)
echo "Running database migration..."
npx prisma migrate deploy
;;
cache-clear)
echo "Clearing cache..."
curl -X POST "$PURGE_URL" -H "Authorization: Bearer $TOKEN"
;;
rollback)
echo "Rolling back..."
./scripts/rollback.sh
;;
esac
# APIからワークフローをトリガー
curl -X POST \
-H "Authorization: token ghp_xxxxx" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/OWNER/REPO/actions/workflows/manual-ops.yml/dispatches \
-d '{
"ref": "main",
"inputs": {
"operation": "cache-clear",
"target": "staging",
"confirm": "yes"
}
}'
パフォーマンス最適化
ジョブの並列化とアーティファクト共有
name: Optimized Pipeline
on:
push:
branches: [main]
jobs:
# ビルドジョブ(1回だけ実行)
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run build
# ビルド成果物をアーティファクトとして保存
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 1
# テスト(並列実行)
unit-test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run test:unit
integration-test:
needs: build
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run test:integration
env:
DATABASE_URL: postgresql://postgres:test@localhost:5432/testdb
e2e-test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: npx playwright install chromium
- run: npm run test:e2e
# 全テスト通過後にデプロイ
deploy:
needs: [unit-test, integration-test, e2e-test]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: echo "Deploying..."
テストシャーディング
name: Sharded Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
# Vitestのシャーディング
- run: npx vitest --shard=${{ matrix.shard }}/4
# Playwrightのシャーディング
- run: npx playwright test --shard=${{ matrix.shard }}/4
# 全シャードの結果を統合
merge-reports:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "All shards passed!"
実践的なCI/CDパイプライン
フルスタックアプリケーションの完全なパイプライン
name: Full CI/CD Pipeline
on:
push:
branches: [main, 'release/**']
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
permissions:
contents: read
packages: write
pull-requests: write
security-events: write
jobs:
# 1. コード品質チェック
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm run format:check
# 2. セキュリティスキャン
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run npm audit
run: npm audit --audit-level=high
- name: Run CodeQL
uses: github/codeql-action/analyze@v3
with:
languages: javascript-typescript
# 3. テスト
test:
needs: quality
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npx vitest --shard=${{ matrix.shard }}/3 --coverage
- uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.shard }}
path: coverage/
# 4. ビルド&プッシュ
build:
needs: [test, security]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Generate version
id: version
run: echo "version=$(date +%Y%m%d)-${GITHUB_SHA::8}" >> $GITHUB_OUTPUT
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
# 5. ステージングデプロイ
deploy-staging:
needs: build
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
version: ${{ needs.build.outputs.version }}
secrets:
DEPLOY_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
# 6. 本番デプロイ(承認必要)
deploy-production:
needs: [build, deploy-staging]
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
version: ${{ needs.build.outputs.version }}
secrets:
DEPLOY_KEY: ${{ secrets.PRODUCTION_DEPLOY_KEY }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
まとめ
GitHub Actionsの上級テクニックを活用することで、CI/CDパイプラインの実行速度、信頼性、メンテナンス性を大幅に向上させることができます。本記事で紹介した内容をまとめます。
- マトリックスビルド: 複数のOS・ランタイムバージョンの組み合わせテストを自動化し、動的マトリックスで変更範囲に応じた効率的なテストを実現
- キャッシュ戦略: node_modules、ビルド成果物、Docker Layerのキャッシュにより、パイプライン実行時間を50-70%削減可能
- セルフホストランナー: GPU演算や大容量ストレージが必要な場合、ARCによるKubernetes上のオートスケールランナーが有効
- Reusable Workflows: 共通パターンを再利用可能なワークフローとして定義し、組織全体でCI/CDの一貫性を維持
- セキュリティ: OIDC認証、SHAピン留め、Dependabot自動マージにより、サプライチェーンセキュリティを強化
- パフォーマンス最適化: テストシャーディング、ジョブ並列化、アーティファクト共有により、大規模プロジェクトでも高速なフィードバックループを実現