DELOGs
GitHub設定編:最小構成の CI を動かすまで

GitHub設定編:最小構成の CI を動かすまで

GitHub Actions を使った CI(継続的インテグレーション)の最小構成 を体験

初回公開日

最終更新日

GitHub超入門-アカウント作成から初pushまでゆっくりガイドGit 基本コマンド10選を経て、今回は GitHub Actions を使った CI(継続的インテグレーション)の最小構成 を体験します。
今回、以下が実現できるようになりたいと思っています。
  • push や PR 作成のたびに自動でビルド & テスト → 結果を緑 ✓ / 赤 × で確認
  • 成功をブランチ保護ルールで必須化 → テストが通らないとマージできない安全な開発フロー
  • 失敗を体験 → 修正 → 再テスト のサイクルを実践

0. はじめに:CI を使う価値

なぜ CI が必要?
  • ヒューマンエラーの排除: 手元の環境では通っても、クリーン環境や本番と差異があると不具合が発生することが多い
  • 小さな変更でも即座に検証: コミットや PR(Pull Request) のたびにビルド・テストを自動実行し、品質を担保
  • レビューに集中できる: CI が自動チェックするので、レビュワーは実装内容や設計にフォーカス
この記事でやること
  • 最小ワークフロー (echo "✅ build success") を設定し、Actions タブで緑 ✓ を見る
  • 実際のビルド & 型チェック を追加して、Next.js プロジェクトが CI で通ることを確認
  • ブランチ保護ルール を設定し、テスト成功をマージの必須条件に
  • わざとエラーを入れて赤 × を体験 → 修正 → 緑 ✓ までの流れ
  • ESLint追加例を紹介

1. GitHub Actions とは?

GitHub が提供する CI/CD プラットフォームで、リポジトリ直下の .github/workflows/*.yml に記述するだけで クラウド上のクリーン環境(Ubuntu や Windows、macOS ランナー)で自動実行されます。
しかも、公開リポジトリだと無制限・無料で利用できるという、なんともありがたい機能です。「GitHub公式ドキュメント」参照。 プライベートリポジトリでも、無料枠があり、2,000 分/月(Ubuntu ランナー換算で約1時間/日相当)が無料になります。

2. 最小 YAML を置いてみる

shadcnのボタンだけ設置しただけのページがあるリポジトリがdelogs-jp/shadcn-installにあるので、これをCloneして、delogs-jp/shadcn-install-ciリポジトリにPushして、いろいろ試していきます。予めGitHubにshadcn-install-ciリポジトリを新規作成しました。

作業ディレクトリを用意

/xxx/xxx/project配下に各プロジェクトのディレクトリを配置しているものとします。
zsh
1cd /xxx/xxx/project 2 3# クローンコマンドでソースをもってきます 4git clone https://github.com/delogs-jp/shadcn-install.git shadcn-install-ci 5 6cd shadcn-install-ci 7 8# とりあえずnpm install 9npm install

.github/workflows/ci.yml を作成

Cursorエディタなどでshadcn-install-ci直下に.github/workflows/ci.ymlを作成して下記のように編集します。
yml : ci.yml
1name: CI (echo only) 2 3on: 4 push: [] 5 pull_request: [] 6 7jobs: 8 test: 9 runs-on: ubuntu-latest 10 steps: 11 - uses: actions/checkout@v4 12 - run: echo "✅ build success"
name: CI (echo only)
  • 役割: このワークフロー(CI の定義ファイル)に付ける「人間が見る名前」です。
  • 表示場所: GitHub 上の Actions タブ で、このラベルが一覧に出ます。
  • ポイント: 「echo だけのテスト用 CI」という趣旨が一目で伝わる命名にしています。
トリガー部分: on:
push: []
  • 意味: どのブランチに対してプッシュしても Workflow を起動する
  • 空の配列 ([]) を使うと「すべてのブランチ」が対象
pull_request: []
  • 意味: Pull Request が 作成 もしくは 更新 されたときに起動する
  • これも空配列で「すべてのターゲットブランチへの PR」をカバー
つまり、コミットをプッシュしたらすぐ走る、PR を開いたり更新したらすぐ走るという意味になります。
ジョブ定義: jobs:
  • jobs: 複数の「独立した実行単位(ジョブ)」を定義できるブロック
  • test:: ジョブの識別子。好きな名前を付けられますが、後で保護ルールに使うので分かりやすい名称が吉
  • ポイント: 今回はジョブは1つだけなので test という名前にしています。
ランナー指定: runs-on: ubuntu-latest
  • 役割: GitHub が用意する 仮想マシン環境 を指定
  • ubuntu-latest → 最新の Ubuntu (Linux) コンテナ(当サイトのWebサーバのOSはUbuntuなので)
  • 他にも windows-latest / macos-latest などが選べます
  • 何が起きる?: GitHub 側でクリーンな Ubuntu インスタンスを立ち上げ、その上で以降のステップが実行される
ステップ定義: steps:
uses: actions/checkout@v4
  • 役割: リポジトリのソースコードを ランナー環境にチェックアウト(コピー) する公式アクション
  • なぜ必要?: Workflow は “空のマシン” で動き出すため、まずソースがないと何もテストできません
  • バージョン指定 (@v4): actions/checkout は頻繁にアップデートされるので、安定して動く メジャーバージョン を指定
run: echo "✅ build success"
  • 役割: シェルコマンドをそのまま実行するステップ
  • 今回の目的: Workflow が正しく走るか を確認。ログに ✅ build success が出れば「CI は動いている」と一目瞭然
  • ポイント:本格的なビルドやテストはまだ書いていない「最小限のお試しステップ」です

コミット & Push

zsh
1# 当サイトのGitHubはSSH接続なので下記のようにPush先を指定 2git remote set-url origin git@github-delogs:delogs-jp/shadcn-install-ci.git 3 4git add .github/workflows/ci.yml 5git commit -m "ci: add 最小のワークフロー" 6git push -u origin main

GitHubのActions画面で確認

プッシュが完了したら、GitHub管理画面を開きます。
  • プッシュしたリポジトリの「Actions」をクリック
プッシュしたリポジトリのActions画面
上記のように緑のチェックマークがついた状態でコミットが表示されます。この緑のチェックマークがCIが正常終了したことを意味します。 さらにそのコミットをクリックします。
  • プッシュしたリポジトリの「Actions」に表示されたコミットをクリックすると詳細を確認できます。
プッシュしたリポジトリのActions画面のコミットの詳細
  • さらにコミットの詳細でJOBで指定した“test” ジョブの詳細が確認できます。
プッシュしたリポジトリのActions画面のコミットの詳細
上記のようにrun: echo "✅ build success"が出力されていることが確認できます。これで「CI がちゃんと動くこと」「GitHub Actions がきちんとトリガーされること」を体感できました。

3. ビルド & 型チェックを追加

次に、Next.js プロジェクトのビルドと TypeScript 型チェックを Workflow に追加します。

Workflow を更新

.github/workflows/ci.ymlを下記のように変更します。
yml
1name: CI 2 3on: [push, pull_request] 4 5jobs: 6 build: 7 runs-on: ubuntu-latest 8 steps: 9 # まずはリポジトリをチェックアウト 10 - uses: actions/checkout@v4 11 12 # Node.js + npm 環境をセットアップ 13 - uses: actions/setup-node@v4 14 with: 15 node-version: 22.17.0 # Node.js バージョンを指定 16 17 # 依存をクリーンインストール 18 - run: npm ci 19 # package-lock.json と完全一致する形で node_modules を再生成します。 20 21 # TypeScript 型チェック 22 - run: npx tsc --noEmit 23 # 型エラーがないか検証。--noEmit でファイル出力は行いません。 24 25 # Next.js の本番ビルド 26 - run: npm run build 27 # next build コマンドを実行し、ビルドエラーや最適化結果をチェックします。

各ステップの詳しい解説

npmを使った私には馴染みのあるステップです。
on: [push, pull_request]
これは、
yml
1on: 2 push: [] 3 pull_request: []
と同じ意味になります。
actions/checkout@v4
  • これがないとエラーになります。上掲でも記載したリポジトリのソースコードを ランナー環境にチェックアウト(コピー) する公式アクションですね。
actions/setup-node@v4
  • Node.js と npm をインストールし、npm install / npm ci コマンドが使える環境を用意します。
npm ci
  • CI 向けの完全インストールモード。ローカルの node_modules をクリアし、package-lock.json と厳密に同じ依存セットをインストールします。
run: npx tsc --noEmit
  • npx tsc なら npm scripts に依存せず、インストール済みの typescript CLI を直接呼び出します。ファイル生成なし。
npm run build
  • Next.js プロジェクトを本番用にビルド (next build) し、ビルドエラーがないかを検証します。

コミット & Push

zsh
1git add .github/workflows/ci.yml 2git commit -m "ci: ビルドと型チェックを追加" 3git push

GitHubのAction画面

GitHubのAction画面を表示します。npm ciとビルドが走るので、チェック完了まで少し時間がかかります。
ビルドと型チェック追加後のActions画面
私がci.ymlの記述を一部間違えて、2回エラーを起こしてしまいました(- uses: actions/checkout@v4の記述漏れとrun: npx tsc --noEmitnpmで記述してしまうミス)。。上図は完成版をPushしたものです。緑のチェックマークがつきました。
これで、とりあえず、ビルドと型チェックを自動でおこなってくれるようになりました。

4. ブランチ保護ルールを設定

次に、テストが通らないとmainブランチにマージできないよう、GitHub 側で保護ルールを設定します。
  • 対象リポジトリの Settings → Branchesを開き 「Add classic branch protection rule」をクリックします
GitHubの対象リポジトリのブランチの保護設定を追加する画面
  • 保護設定の画面で下記のように設定します
今回は、mainブランチに対する保護なので:
Branch name patternmain
(任意)Require a pull request before merging にチェックを入れると直接 push/merge を禁止できます。必ず、PR =>確認 =>マージの手順を踏むことになります。
Require status checks to pass before merging にチェックを入れて、先ほど作成したジョブ名(build)を検索窓に入力して選択します。これで、buildジョブを経由してOKならないとマージ不可になります。
GitHubの対象リポジトリのブランチの保護設定の画面
上記のようにしたら、画面下部の「Create」をクリックします。一度、管理画面パスワード入力を求められて、完了すると下記のようになります。
GitHubの対象リポジトリのブランチの保護設定が完了した後の画面
これで、mainブランチに対しての保護ルールの設定が完了しました。これで CI が成功しない限り main へマージできない 安全なフローが完成です。修正したい場合は「Edit」でいつでも編集できます。
ちなみに:
Require a pull request before mergingのサブ選択肢の内容
  • Require approvals:Pull Request をマージする前にレビュー承認を必須化します。ドロップダウンで「何名の承認が必要か」を設定可能。小規模プロジェクトなら 1 名、チーム開発なら 2 名以上にする例が多いです。
  • Dismiss stale pull request approvals when new commits are pushed:承認済みの PR に対してさらにコミットが追加された場合、既存の承認をすべて無効化します。新しい変更にレビューが追いつかないリスクを防ぎたいときに有効です。
  • Require review from Code Owners:リポジトリルートの CODEOWNERS ファイルで指定された責任者(Code Owner)の承認を必須にします。特定ディレクトリやファイルを専門チームが管理している場合に使います。
  • Require approval of the most recent reviewable push:最新のコミットだけをレビュー対象にします。過去コミットは再レビュー不要としつつ、新たに追加された一番最後の変更は別のユーザーが承認する必要があります。
Require status checks to pass before mergingのサブ選択肢の内容
  • Require branches to be up to date before merging:Pull Request のベースブランチ(通常は main)に 新しいコミットが追加されていた場合、そのままマージできず、あらためて “最新の main” を取り込んでからでないとマージ不可にする設定です。複数人での開発ではあった方がいいルールかもしれません。
これらのオプションは、チームの開発フローやリスク許容度に応じて組み合わせて使い分けることで、より安全で柔軟なブランチ保護が可能になります。

5. PR で赤 × を体験する

つづいては、せっかく保護ルールを設定したので、失敗パターンを体感してみたいと思います。

ソースコードに故意にビルドエラーを追加

zsh
1# 新しいブランチを作成 2git switch -c feature/error-sample 3 4# ソースに文法エラーを挿入 5# 終端にこんな感じで JSX/TSX 構文の外で意味不明な文字列を追加(エディタで即エラー判定になりますが、一旦無視) 6echo "syntax error <<<<" >> src/app/page.tsx 7 8# commit & push 9git add src/app/page.tsx 10git commit -m "test: ビルドエラーを体感" 11git push -u origin feature/error-sample
feature/error-sampleブランチを作成してからPushしました。

GitHub 上で Pull Request

GitHubの対象リポジトリを見ると、Pushされたfeature/error-sampleブランチの内容が通知されています。
GitHubのPush通知が表示されている画面
ここで「Compare & pull request」ボタンをクリックすると、下記の画面になります。
GitHubのPull Requestの画面
「Add a description」欄は空のまま「Create pull request」ボタンをクリックします。 ちなみに、.github/workflows/ci.ymlでPush時もチェック対象にしているので、上記ページの下部にはチェックエラーが出ていますが、これは一旦無視して、pull requestを体感します。
すると下記のようにチェックが動作して判定された結果が表示されます。
GitHubのPull Requestのチェック結果画面
赤字で**Merge without waiting for requirements to be met (bypass rules) **というのがありますが、これは、保護ルールを無視して強制的にマージする機能です。緊急対応として使えますが、誤って品質ゲートを通過していないコードを本番へ反映するリスクがあります。通常はチェックを外さず、このオプションは使用しない運用をおすすめします。

エラーを修正して再Push

page.tsx をエディタで修正しておきます。
diff : page.tsx
1import { Button } from "@/components/ui/button"; 2 3export default function Home() { 4 return ( 5 <main className="flex min-h-screen flex-col items-center justify-center p-8"> 6 <h1 className="mb-4 text-2xl font-bold"> 7 Shadcn/uiボタンの表示テスト 8 </h1> 9 <Button className="cursor-pointer font-semibold">クリックしてね</Button> 10 </main> 11 ); 12} 13- syntax error <<<<
zsh
1git add src/app/page.tsx 2git commit -m "fix: ダミーエラーテキストを削除" 3git push
すると、GitHubの方は下記のようになります。
GitHubの再Push後のチェック結果画面
一度開いた Pull Request は、そのブランチに対する “生きたリンク” になっています。 そのため、同じブランチにコミットを追加して git push すると、
  • PR の Commits タブに新しいコミットが自動で追加され
  • Checks も再実行され、結果(赤×/緑✓)が更新され
  • 最後に緑✓ になったら、そのまま下の Merge pull request ボタンで統合できます。
新たに PR を作り直す必要はありません。ブランチと PR は紐づいたまま自動で同期される仕組みです。

6. ESLint を追加して品質ゲートを強化

私のような初心者だとローカルPCでNext.jsを利用して開発しているときnpm run devの実行しながら開発をすすめて、特にエラーがないので、いざnpm run buildを実行するとany型に対する警告や、利用していないコンポーネントをインポートしているとの警告が結構な数リストアップされることがあります。これらはESLintからの警告です。
Next.js プロジェクトでは、npx create-next-app@latestでインストールする際に、ESLintをYesにしていれば、Flat Config 形式の eslint.config.mjs が自動生成されています。ローカルと CI 両環境で同じ設定を使うには、このファイルをそのまま活用し、CI 側では next lint コマンドを実行するのがおすすめです。ということで、CI 定義 (.github/workflows/ci.yml) に追加の設定を行います。

eslint.config.mjsの確認

js : eslint.config.mjs
1import { dirname } from "path"; 2import { fileURLToPath } from "url"; 3import { FlatCompat } from "@eslint/eslintrc"; 4 5const __filename = fileURLToPath(import.meta.url); 6const __dirname = dirname(__filename); 7 8const compat = new FlatCompat({ baseDirectory: __dirname }); 9 10export default [ 11 ...compat.extends("next/core-web-vitals", "next/typescript"), 12];
  • next/core-web-vitals, next/typescript のルールセットが適用済み
  • プロジェクトルートにこのファイルがあるか確認してください

デフォルトの lint スクリプトを利用

Next.js の新規プロジェクトでは、package.json の scripts に既に
json
1"lint": "next lint"
が含まれています。そのままローカルでも CI でも、以下のコマンドで lint を実行できます。
zsh
1npm run lint

Workflow への組み込み

CI 定義 (.github/workflows/ci.yml) の build ジョブに、ビルド前に lint を走らせるステップを挿入します。
その前に、これまでfeature/error-sampleで作業していたので、mainへ戻ります。
zsh
1# 1. main に戻る 2git switch main 3 4# 2. 最新の main を取り込む 5git pull 6# または、git pull --ff-only origin main 7 8# 3. 新規ブランチを main から作成 9git switch -c feature/add-eslint
yml : ci.yml
1jobs: 2 build: 3 runs-on: ubuntu-latest # 最新の LTS(Ubuntu 24.04) 4 steps: 5 - uses: actions/checkout@v4 6 - uses: actions/setup-node@v4 7 with: { node-version: 22.17.0 } 8 - run: npm ci 9 10 # ここで ESLint を実行 11 - name: Run ESLint 12 run: npm run lint 13 14 - name: Run TypeScript Check 15 run: npx tsc --noEmit 16 17 - name: Build Next.js 18 run: npm run build
  • next lint は自動的に eslint.config.mjs を読み込み、設定済みのルールに沿って静的解析を行います

コミットとPush

zsh
1# ワークフローをステージ 2git add .github/workflows/ci.yml 3 4# コミット 5git commit -m "ci: ESLint ステップを追加" 6 7# 新ブランチをリモートにプッシュ 8git push -u origin feature/add-eslint
GithubでPRして、
GitHubのESLintステップ追加Push後のチェック結果画面
「Merge pull request」をクリックしてマージを実行して完了です。
以上、今回のGitHub Actions を使った CI(継続的インテグレーション)の最小構成 を体験が一通り完了しました。
少しGitとGitHubが使える気分を味合うことができました。少し進歩した気がします。何度も繰り返してGitとGitHubを使いこなせるようになりたいと思います。
この記事の執筆・編集担当
DE

松本 孝太郎

DELOGs編集部/中年新米プログラマー

ここ数年はReact&MUIのフロントエンドエンジニアって感じでしたが、Next.jsを学んで少しずつできることが広がりつつあります。その実践記録をできるだけ共有していければと思っています。