コードをプッシュするたびにテストを手動で実行し、本番環境に手作業でデプロイする――こうしたワークフローは、チームの生産性を大きく損ないます。GitHub Actionsを使えば、CI(継続的インテグレーション)とCD(継続的デリバリー)のパイプラインをGitHub上で完結して自動構築できます。
この記事では、GitHub Actionsの基本概念から実践的なCI/CDパイプラインの構築方法まで、コード例とともに解説します。
GitHub Actionsとは?基本概念を理解する
GitHub Actionsは、GitHubに統合されたCI/CDおよびワークフロー自動化プラットフォームです。リポジトリ内にYAMLファイルを配置するだけで、コードのプッシュ、プルリクエスト、スケジュールなど、さまざまなイベントをトリガーに処理を自動実行できます。
主要な構成要素
GitHub Actionsの構成要素を理解しましょう。
- Workflow(ワークフロー):自動化プロセス全体の定義。YAMLファイルで記述
- Event(イベント):ワークフローを起動するトリガー(push、pull_request等)
- Job(ジョブ):ワークフロー内の実行単位。複数のジョブは並列実行可能
- Step(ステップ):ジョブ内の個々の処理。コマンドの実行やActionの利用
- Action(アクション):再利用可能な処理パーツ。Marketplaceで公開されているものも利用可能
- Runner(ランナー):ワークフローを実行するサーバー環境
ワークフローファイルの配置場所
ワークフローファイルは、リポジトリの.github/workflows/ディレクトリに配置します。
my-project/
├── .github/
│ └── workflows/
│ ├── ci.yml # テスト・リント
│ ├── cd.yml # デプロイ
│ └── codeql.yml # セキュリティスキャン
├── src/
├── package.json
└── README.md
最初のワークフローを作成する
まずは最もシンプルなワークフローから始めましょう。コードがプッシュされたらテストを実行する基本的なCIワークフローです。
Hello Worldワークフロー
# .github/workflows/hello.yml
name: Hello World
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
greeting:
runs-on: ubuntu-latest
steps:
- name: Say Hello
run: echo "Hello, GitHub Actions!"
- name: Show environment info
run: |
echo "Event: ${{ github.event_name }}"
echo "Branch: ${{ github.ref }}"
echo "Repository: ${{ github.repository }}"
echo "Runner OS: ${{ runner.os }}"
Node.jsプロジェクトのCIワークフロー
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- name: Checkout code
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 linter
run: npm run lint
- name: Run type check
run: npm run type-check
- name: Run tests
run: npm run test -- --coverage
- name: Upload coverage
if: matrix.node-version == 20
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
このワークフローのポイントを解説します。
strategy.matrix:Node.jsの複数バージョンで並列テストを実行actions/setup-node@v4のcacheオプション:npm依存関係をキャッシュして高速化if: matrix.node-version == 20:特定の条件でのみステップを実行actions/upload-artifact@v4:テスト結果をアーティファクトとして保存
実践的なCI/CDパイプラインの構築
実際のプロジェクトでは、テスト・ビルド・デプロイを段階的に実行するパイプラインが必要です。
テスト → ビルド → デプロイのパイプライン
# .github/workflows/pipeline.yml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# ジョブ1: テスト
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 run test
# ジョブ2: ビルド(テスト成功後に実行)
build:
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: npm run build
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
# ジョブ3: デプロイ(mainブランチのpushのみ)
deploy:
needs: build
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- name: Deploy to production
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: |
echo "Deploying to production..."
# デプロイスクリプトをここに記述
needsキーワードでジョブ間の依存関係を定義し、if条件で特定の条件でのみジョブを実行できます。
Dockerイメージのビルドとプッシュ
# .github/workflows/docker.yml
name: Docker Build & Push
on:
push:
branches: [main]
tags: ['v*']
jobs:
docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=sha,prefix=
type=ref,event=branch
type=semver,pattern={{version}}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
Secretsと環境変数の管理
APIキーやデプロイトークンなどの機密情報は、GitHub Secretsで安全に管理します。
Secretsの設定と使用
# GitHubリポジトリの Settings > Secrets and variables > Actions で設定
# ワークフローでの参照
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: |
# 環境変数としてSecretsを利用
npm run deploy
Environment(環境)の活用
# 環境ごとにSecretsを分ける
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging # staging環境のSecretsを使用
steps:
- name: Deploy to staging
env:
API_URL: ${{ vars.API_URL }} # 環境変数(非機密)
API_KEY: ${{ secrets.API_KEY }} # 機密情報
run: npm run deploy
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production # production環境のSecretsを使用
steps:
- name: Deploy to production
env:
API_URL: ${{ vars.API_URL }}
API_KEY: ${{ secrets.API_KEY }}
run: npm run deploy
Environment機能を使うと、本番環境へのデプロイに承認フローを設定することも可能です。
キャッシュ戦略による高速化
CI/CDパイプラインの実行時間を短縮するには、キャッシュの活用が不可欠です。
依存関係のキャッシュ
# setup-nodeの組み込みキャッシュ(推奨)
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
# 手動でキャッシュを設定する場合
- name: Cache node_modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
ビルドキャッシュ
# Next.jsのビルドキャッシュ
- name: Cache Next.js build
uses: actions/cache@v4
with:
path: |
.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package-lock.json') }}-${{ hashFiles('**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('package-lock.json') }}-
${{ runner.os }}-nextjs-
再利用可能なワークフロー
複数のリポジトリや複数のワークフローで同じ処理を繰り返す場合、再利用可能なワークフロー(Reusable Workflows)を活用しましょう。
再利用可能なワークフローの定義
# .github/workflows/reusable-test.yml
name: Reusable Test Workflow
on:
workflow_call:
inputs:
node-version:
required: false
type: string
default: '20'
working-directory:
required: false
type: string
default: '.'
secrets:
CODECOV_TOKEN:
required: false
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
cache-dependency-path: ${{ inputs.working-directory }}/package-lock.json
- run: npm ci
- run: npm run test -- --coverage
再利用可能なワークフローの呼び出し
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test-frontend:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: '20'
working-directory: './frontend'
test-backend:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: '20'
working-directory: './backend'
コスト管理とベストプラクティス
GitHub Actionsは無料枠がありますが、使い方によっては想定以上のコストが発生することがあります。
無料枠と料金体系
- パブリックリポジトリ:無制限に無料
- プライベートリポジトリ(Freeプラン):月2,000分(Linux)
- プライベートリポジトリ(Teamプラン):月3,000分(Linux)
- macOSランナー:Linuxの10倍の消費レート
- Windowsランナー:Linuxの2倍の消費レート
コスト削減のテクニック
# 1. 不要なトリガーを減らす
on:
push:
branches: [main]
paths-ignore:
- '**.md' # ドキュメントの変更ではCIを実行しない
- '.gitignore'
- 'LICENSE'
pull_request:
paths:
- 'src/**' # ソースコードの変更時のみ実行
- 'package*.json'
# 2. ジョブの並列実行を活用
# 3. concurrencyで重複実行をキャンセル
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # 同じブランチの古い実行をキャンセル
# 4. タイムアウトを設定
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15 # 最大15分で打ち切り
セキュリティのベストプラクティス
# 1. Actionsのバージョンをピン留め(SHA指定推奨)
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# 2. 最小限のパーミッション
permissions:
contents: read
pull-requests: write
# 3. GITHUB_TOKENの権限を制限
# リポジトリ Settings > Actions > General >
# "Workflow permissions" を "Read repository contents" に設定
まとめ:GitHub Actionsを始めるためのステップ
GitHub Actionsは、GitHubを使っている開発チームにとって最も手軽に始められるCI/CDプラットフォームです。段階的に導入することで、無理なく自動化の恩恵を受けられます。
- ステップ1:プッシュ時にリントとテストを自動実行するCIワークフローを作成
- ステップ2:キャッシュを設定してビルド時間を短縮
- ステップ3:ステージング環境への自動デプロイ(CD)を追加
- ステップ4:本番環境へのデプロイに承認フローを設定
- ステップ5:セキュリティスキャンや依存関係の自動更新を追加
最初から完璧なパイプラインを目指す必要はありません。まずはシンプルなCIワークフローから始め、プロジェクトの成長に合わせて段階的に機能を追加していきましょう。自動化に投資した時間は、長期的に何倍もの生産性向上として返ってきます。
関連記事
AIエージェント開発入門|自律型AIの仕組みと構築方法を解説【2026年版】
AI駆動コーディングワークフロー|Claude Code・Cursor・Copilotの実践的使い分け
プロンプトエンジニアリング上級編|Chain-of-Thought・Few-Shot・ReActの実践
APIレート制限の設計と実装|トークンバケット・スライディングウィンドウ解説
APIバージョニング戦略|URL・ヘッダー・クエリパラメータの使い分け
BIツール入門|Metabase・Redash・Looker Studioでデータ可視化する方法
チャットボット開発入門|LINE Bot・Slack Botの構築方法と活用事例
CI/CDパイプラインの基礎|継続的インテグレーション・デリバリーの全体像