1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Day20】PR作成時にAPIユニットテストを自動実行する+ブランチ保護設定を作る

Last updated at Posted at 2025-07-02

はじめに

勉強とアウトプットを兼ねて、Webアプリ開発の記録を記事にしてみます。

個人のメモ的な側面が強いです。
Web開発初心者すぎて至らぬところだらけだと思いますが、暖かい目で見ていただければ幸いです。

↓ これまでの内容 ↓
【Day0】アプリが完成するまで毎日投稿
【Day1】開発環境を考える
【Day2】開発環境を構築する、、、はずでした
【Day3】まずはフロントだけ開発環境を構築する
【Day4】バックエンドの開発環境を整えつつ、マルチコンテナ対応のDevcontainerにする
【Day5】お試し実装!ファイルをアップロードしてバックエンドで処理する
【Day6】Docker Desktopが起動しなくなり泣きながら原因調査する
【Day7】画像にフレームとExif情報を付けてみる
【Day8】フロントに表示する画像のサイズを小さくする
【Day9】フロントエンドとバックエンドをそれぞれデプロイする
【Day10】結局コンテナ1つで開発する方が楽かもしれない
【Day11】アプリが一通り完成!!
【Day12】FastAPIのコードをリファクタリングする
【Day13】機能実装!フレームに記載するExif情報を編集できるようにする(前編)
【Day14】ReactのリファクタリングとUI変更を同時にやった
【Day15】機能実装!フレームに記載するExif情報を編集できるようにする(後編)
【Day16】インスタ用のキャプションを生成する(前編)
【Day17】インスタ用のキャプションを生成する(中編)
【Day18】インスタ用のキャプションを生成する(後編)
【Day19】自動テストを実装する(全体の構想&APIユニットテスト編)

前回やったこと

今作っているWebアプリにはどんな種類のテストコードが必要なのかを検討して、PythonのFastAPIで作ったAPIのユニットテストを作成しました!

今回やったこと

前回作成したAPIユニットテストをPR作成時に自動で実行させる仕組みを作りました。

また、masterブランチにはdevelopブランチからしかPRを出せないようにする仕組みも併せて作りました。(理由は後述)

どちらもGitHub Actionsを用意しました。

現在のブランチ構成

そもそもなんですが、今は以下のようなブランチ構成で開発してます。

master         // 確実に動く状態のソースを格納する
 └ develop     // developで全部の動作確認をしてからmasterにマージ
   ├ feature1  // 機能追加はdevelopからトピックブランチを切る
   ├ feature2
   : 
   └ featureX

機能開発はdevelopをベースに行い、最終的に上手くいったらmasterにマージするような運用です。

APIユニットテスト

以下のymlを.github/workflowsに記載することでmasterブランチとdevelopブランチへのPR作成時にpytestを実行するGitHub Actionsを追加しました。

test.yml
name: Run Pytest on PR

on:
  pull_request:
    branches:
      - master
      - develop

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v3

      - name: 🐍 Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: 📦 Install dependencies
        working-directory: backend
        run: |
          python -m venv venv
          source venv/bin/activate
          pip install -r requirements.txt

      - name: 🧪 Run pytest
        working-directory: backend
        env:
          PYTHONPATH: .
        run: |
          source venv/bin/activate
          pytest

また、このユニットテストが成功しないとPRがマージできないような設定も作りました。

GitHubのSettings > BranchesからAdd ruleでBranch protection ruleを作りました。

Branch name patternにdevelopを入れて、Protect matching branchesにはRequire status checks to pass before mergingRequire branches to be up to date before mergingにチェックを入れて、Status checkの対象に今回作成したユニットテストを追加しました。

image.png

Status checkの対象に作成したGitHub Actionsを表示させるためには一度実行する必要があります。
ダミーのブランチでPRを作って動作することを確認してから設定しましょう。

ブランチ保護

masterブランチを保護するために、masterブランチへのPRはdevelopブランチからしか出せないという制約を付けるGitHub Actionsを作成しました。

restrict-master-pr.yml
name: Restrict PR to master from develop only

on:
  pull_request:
    branches:
      - master

jobs:
  restrict_pr_source:
    runs-on: ubuntu-latest
    steps:
      - name: Fail if PR is not from develop
        run: |
          echo "PR from ${{ github.head_ref }} to ${{ github.base_ref }}"
          if [ "${{ github.head_ref }}" != "develop" ]; then
            echo "❌ PR to master must come from develop branch only."
            exit 1
          fi

こちらも上記同様にBranch protection ruleを設定しました。

masterブランチを保護する理由

ブランチ構成を再掲しますが、基本的にmasterブランチはdevelopブランチからしかPRを出さない予定でした。

master         // 確実に動く状態のソースを格納する
 └ develop     // developで全部の動作確認をしてからmasterにマージ
   ├ feature1  // 機能追加はdevelopからトピックブランチを切る
   ├ feature2
   : 
   └ featureX

しかし、どこかのタイミングで間違えたのかfeatureブランチをそのままmasterブランチにマージしてしまい、そのまま気づかず開発を進めていたら、masterブランチとdevelopブランチに謎の差分が出てしまいました。

しかもmasterとdevelop間でPRを作っても差分がないことになるし、git diffでは差分があるけどgit logでコミットログを見てもどれが原因のコミットかわからず、何日も唸っていました。

masterにfeatureをマージするのは1回やったことがあり、そのときはrevertしたのですが、その後ももう一度気づかない間にやってしまったみたいです。

おわりに

今回はGitHub Actionsを使ってユニットテストの自動実行とブランチ保護設定を作成しました。

ヒューマンエラーを防ぐためにブランチ保護設定を作ったのですが、やはりこういったことはシステム的に解決していきたいですね。

今は個人開発ですが、今後もし複数人で開発することになったらこの辺りは絶対設定したいと思いました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?