「忘れる」を仕組みで防ぐ - GitHub Actions CI/CD の話

はじめに
開発では、コードを書いてからリリースするまでにさまざまな確認工程が発生します。
CI/CDを活用すれば、設定した確認工程を自動化し、確実に実行できます。
本記事では、GitHub Actionsでの実装を通じて理解した内容をまとめています。
目次
- CI/CDとは
- 実際にGitHub Actionsで動かしてみた
- 使うことのメリット
- 気づいたこと
CI/CDとは
![]()
CI:Continuous Integration(継続的インテグレーション)
CD:Continuous Delivery(継続的デリバリー)
CIとは、トリガーを設定し、テストとビルドを自動実行する仕組みです。
GitHub ActionsはこのCIを実現するツールのひとつです。
CDとは、CIを通過したコードを、本番にいつでもリリースできる状態に自動で準備する仕組みです。
この一連の流れをパイプラインと呼び、テスト・ビルド・デプロイの各工程が順番に流れていきます。
現代の開発では、一度リリースして終わりではなく、ユーザーの反応をもとに継続的に改善していくスタイルが増えています。
そのためには、安全で頻繁なデプロイができる環境が必要になります。CI/CDはその環境を整えるための手段として使われています。
また、CDにはContinuous Deployment(継続的デプロイメント)という意味を持つ場合もあります。
こちらは、本番へのデプロイまで自動で行います。そのためより迅速なリリースが実現できます。本記事での実装はContinuous Deploymentです。
2. 実際にGitHub Actionsで動かしてみた
| 項目 | 内容 |
| フロントエンド | Vue.js |
| テスト | Vitest |
| デプロイ環境 | Vercel |
|
CI/CD |
GitHub Actions |
| ブランチ構成 | main・feature |
今回の実装環境は以下の通りです。
2-1. 通常のデプロイ(CI/CDを使用しない)
CI/CDを導入する前に、まず手動で一通りの作業をやってみました。手順は以下の流れです。
- ローカルのfeatureでコードを変更する
- テストコマンドを実行する
- GitHubにfeatureをpushしてプルリクエストを作成する
- featureをmainにマージする
- mainを本番環境にデプロイする
やってみると、デプロイ自体はVercelのおかげで驚くほど簡単でした。
ただ、2の ”テスト実行” は誰も強制してくれません。手順を飛ばしてそのままpushしても、問題なくデプロイが完了します。
「テストを実行し忘れたままリリースできてしまう」という構造的なリスクがここにありました。
2-2. 最小構造でGitHub Actionsを動かす
まずGitHub Actionsがどう動くかを理解するため、CI/CDの実装前に動作確認をしました。
ci.yml を作成して以下の内容を記述します。
featureからmainへのプルリクエストを作成すると、GitHub Actionsが自動で起動します。
GitHubの「Actions」タブから、該当のワークフローを選択すると、記述したテキストが出力されていることを確認できます。
# .github/workflows/ci.yml
name: Frontend CI
# どのタイミングで起動するか
on:
pull_request:
branches:
- main
# 処理のまとまり
jobs:
test:
# GitHub Actionsの実行環境
runs-on: ubuntu-latest
# 実行する手順を上から順番に列挙する
steps:
- name: 動作確認
run: echo "GitHub Actionsの動作確認"
![]()
2-3. プルリクエストをトリガーにCIでテストを自動実行する
動作確認ができたので、ci.ymlの中身をテストが実行される内容に変更します。
実行環境準備と、テスト実行を記述します。
name: Frontend CI
on:
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
# 実行環境にリポジトリのコードを持ってくる
- name: リポジトリをチェックアウト
uses: actions/checkout@v4
# Node.jsを使えるようにする
- name: Node.jsをセットアップ
uses: actions/setup-node@v4
with:
node-version: 20
# 依存パッケージをインストールする
- name: 依存パッケージをインストール
working-directory: frontend
run: npm ci
# テストを実行する
- name: テストを実行
working-directory: frontend
run: npm run test:unit -- --run
![]()
featureからmainへプルリクエストを作成すると、このワークフローが自動で起動してテストが実行されます。
2-1でやっていた ”テストコマンドを実行” が、プルリクエスト作成と同時に自動で走るようになりました。「実行し忘れる」という選択肢が構造上なくなります。
2-4. マージをトリガーにCDでデプロイまで自動実行する
続いて、featureをmainにマージしたタイミングでVercelへ自動デプロイされるCDを実装しました。
cd.yml を新たに作成して以下の内容を書きます。
CIと同様に実行環境を準備したあと、Vercelへのデプロイを記述します。
# .github/workflows/cd.yml
name: Frontend CD
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 実行環境にリポジトリのコードを持ってくる
- name: リポジトリをチェックアウト
uses: actions/checkout@v4
# Node.jsを使えるようにする
- name: Node.jsをセットアップ
uses: actions/setup-node@v4
with:
node-version: 20
# VercelをCLIで操作できるようにする
- name: Vercel CLIをインストール
run: npm install -g vercel
# 本番環境にデプロイ。secretsはVercelから発行する。
- name: Vercelにデプロイ
run: vercel deploy --prod --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
![]()
mainへのマージをトリガーにGitHub Actionsが起動し、Vercel CLIを通じてデプロイが実行されます。
デプロイの記述で使用するsecretsトークンやIDはVercelの管理画面から取得し、GitHubリポジトリの設定画面から登録します。
2-1では "本番環境にデプロイ" していました。この実装によってデプロイの制御主体がGitHub Actionsに変わり、「いつ・どの条件でデプロイするか」をコードで管理できる状態になります。
3. 使うことのメリット
- テストの実行を仕組みとして保証できる
CIを導入する前は、テストを実行するかどうかは開発者任せとなっていました。
テストをスキップしたままプルリクエストを作成し、そのままデプロイが完了する状況が起こりえました。
CIを導入すると、設定したトリガーに応じて、GitHub Actionsが自動でテストを実行します。
「実行し忘れる」という選択肢が仕組みとして存在しなくなります。
- デプロイを自動制御できるようになる
CDを導入することで、「いつ・どの条件で・デプロイするかしないか」をコードで定義できます。「このブランチへのマージ時だけデプロイする」「テストが通った場合のみデプロイする」「マージはするがデプロイはしない」といったパターンを、YAMLファイルに明示的に記述して管理できる状態になります。
4. 気づいたこと
今回は1人で最小構造での実装だったため、CI/CDの恩恵を大きく実感できた場面は多くありませんでした。
チーム開発では複数人が同時に異なるコードを変更するため、マージのたびに「動いていたものが動かなくなる」リスクが生まれます。そういった環境でこそ、CIが統合時の問題を自動で検知する価値が最大化されると感じました。
一方で、明確に「これは意味がある」と感じたのがテスト実行漏れをなくせるという点でした。
テストの実行漏れを確実になくせる環境があることは、積み重ねると大きな意味を持ちます。「忘れない」を人間の注意力に頼らず、設計で担保できることがCI/CDの強みだと感じました。
Search
よく読まれている記事
カテゴリ
アーカイブ
あなたに最適な解決策を一緒に考えます。
状況に応じた最適なご提案で、お客様の課題解決をサポートいたします