GitHub Actions と CI/CD の基礎
CI/CD の概念と、GitHub Actions のワークフローファイル(.github/workflows/*.yml)の書き方をまとめた。
CI/CD とは
CI(継続的インテグレーション)
コードを push するたびに自動でテスト・ビルドを実行する仕組み。
push → テスト実行 → ビルド確認 → 問題があれば通知
「インテグレーション」は「複数人の変更を main に統合する」という意味。手動でテストを実行するのを忘れたり、ローカル環境の差異でバグを見落としたりするのを防ぐ。
CD(継続的デリバリー / デプロイ)
テストが通ったら自動でデプロイまで走らせる仕組み。
- Continuous Delivery(継続的デリバリー): デプロイできる状態を常に保つ。本番反映は手動承認
- Continuous Deployment(継続的デプロイ): テストが通れば自動で本番まで反映
個人開発では後者(テスト通過 → そのまま本番反映)が多い。
パイプライン
CI/CD の一連の処理フロー全体を指す言葉。
push → lint → test → build → deploy
各ステップが前のステップの成功を前提に続く「パイプ」のようなイメージ。
GitHub Actions の構成要素
ワークフロー(Workflow)
.github/workflows/ 以下に置く YAML ファイル1つ = ワークフロー1つ。複数置ける。
.github/
└── workflows/
├── deploy.yml # デプロイ用
└── test.yml # テスト用
イベント(Event)
ワークフローを起動するトリガー。on: で指定する。
on:
push: # push 時
branches: [main] # main ブランチのみ
pull_request: # PR 作成・更新時
branches: [main]
schedule:
- cron: '0 9 * * 1' # 毎週月曜 9:00 UTC
workflow_dispatch: # 手動実行ボタンを表示
ジョブ(Job)
jobs: 以下に定義する実行単位。デフォルトで並列実行される。
jobs:
test: # ジョブ名(任意)
runs-on: ubuntu-latest
steps: ...
deploy:
needs: test # test ジョブが成功してから実行
runs-on: self-hosted
steps: ...
needs: で依存関係を指定すると直列にできる。
ステップ(Step)
ジョブ内の処理の1単位。上から順番に実行される。1つ失敗すると以降はスキップ。
steps:
- name: チェックアウト # name は省略可。ログに表示される
uses: actions/checkout@v4 # 公式 Action を使う
- name: テスト実行
run: uv run pytest # シェルコマンドを実行
uses と run の使い分け:
- uses: 誰かが作った Action(処理のまとまり)を再利用する
- run: シェルコマンドをそのまま書く
ランナー(Runner)
ジョブを実行するマシン。
| 種類 | 説明 |
|---|---|
ubuntu-latest / windows-latest / macos-latest |
GitHub が管理するクラウドマシン。無料枠あり |
self-hosted |
自分のサーバーに Runner をインストールして使う |
Self-hosted は GitHub に課金せずに使えるが、サーバーの管理は自前。
ワークフロー YAML の書き方
基本構造
name: ワークフロー名(GitHub UI に表示される)
on:
push:
branches: [main]
jobs:
job-name:
runs-on: ubuntu-latest
steps:
- name: ステップ名
run: echo "hello"
環境変数
jobs:
deploy:
runs-on: self-hosted
env:
APP_DIR: /home/<username>/app # ジョブ全体で使える変数
steps:
- name: 変数を使う
run: echo "$APP_DIR"
env:
STEP_VAR: ステップ限定の変数 # このステップだけで使える
Secrets(秘密情報)
API キーなどは ${{ secrets.変数名 }} で参照。GitHub の Settings → Secrets で登録する。
steps:
- name: デプロイ
run: curl -H "Authorization: Bearer $TOKEN" https://api.example.com
env:
TOKEN: ${{ secrets.API_TOKEN }} # ログに *** でマスクされる
公式 Action の使い方
uses: owner/repo@version の形式。
steps:
- uses: actions/checkout@v4 # リポジトリをチェックアウト
- uses: actions/setup-python@v5 # Python のセットアップ
with:
python-version: '3.12' # Action へのパラメータは with: で渡す
よく使う公式 Actions:
| Action | 用途 |
|---|---|
actions/checkout@v4 |
リポジトリのコードを取得 |
actions/setup-python@v5 |
Python バージョンを指定してセットアップ |
actions/setup-node@v4 |
Node.js のセットアップ |
actions/cache@v4 |
依存関係のキャッシュ |
actions/upload-artifact@v4 |
ビルド成果物を保存 |
$GITHUB_PATH — PATH の追加
Runner の実行環境は .bashrc を読まないため、インストール済みのツールが PATH に入っていないことがある。$GITHUB_PATH に追記することで後続ステップ全体に反映できる。
- name: uv を PATH に追加
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: uv を使う(PATH が通っている)
run: uv sync
export PATH=... をステップ内に書いてもそのステップ限りで消える。$GITHUB_PATH への追記が正しい方法。
$GITHUB_ENV — 後続ステップへの変数渡し
- name: バージョンを取得して変数にセット
run: echo "VERSION=$(git describe --tags)" >> $GITHUB_ENV
- name: 変数を使う
run: echo "デプロイバージョン: $VERSION"
ステップ間で値を渡したいときに使う。
working-directory
- name: テスト実行
working-directory: ./backend # このステップだけ作業ディレクトリを変更
run: uv run pytest
if — 条件付き実行
- name: 失敗時の通知
if: failure() # 前のステップが失敗した場合のみ実行
run: echo "失敗した"
- name: main のみ実行
if: github.ref == 'refs/heads/main'
run: ./deploy.sh
豆知識
ワークフローファイルは複数置ける
test.yml と deploy.yml を分けることで、「テストは PR でも走らせ、デプロイは main push のみ」といった使い分けができる。1ファイルに全部書く必要はない。
ジョブはデフォルトで並列
needs: を書かなければジョブは同時に走る。テストとリントを並列にしてパイプライン全体を速くできる。
Self-hosted Runner はセキュリティリスクに注意
パブリックリポジトリで Self-hosted Runner を使うと、悪意ある PR が fork から runner 上でコードを実行できてしまう。プライベートリポジトリか、信頼できる contributor のみのリポジトリに限定して使うのが安全。
actions/checkout を使わないケースがある
Self-hosted Runner で「リポジトリは既にサーバーに clone 済みで、pull するだけでよい」場合は actions/checkout が不要。runner がサーバー上で直接 git fetch + reset --hard するほうがシンプル(自宅サーバーへの自動デプロイ での構成)。
ログは自動的にマスクされる
${{ secrets.XXX }} で渡した値はログ出力時に自動で *** に置き換わる。誤って echo $SECRET してもログに漏れない。
workflow_dispatch で手動実行ボタンを追加できる
on:
push:
branches: [main]
workflow_dispatch: # これを追加するだけで GitHub UI に "Run workflow" ボタンが出る
緊急の再デプロイや、push なしで試し実行したいときに便利。