GitHub Actionsでpytestが通った場合のみプルリクがマージできるようにする。

先日、Streamlitの紹介記事を書いた続きです。
(前回の記事を読まなくても多分参考になると思います)

https://qiita.com/The_Past_of_Dice/items/1e32e692134312bbee90

これまではSteamlitの使い方とStreamlit Community Cloud への無料デプロイの方法などをやって来ました。

あまり複雑なことはできませんが、継続的に機能を拡張していきたいと思っているので今回はGitHub Actionsを使用したCI/CDをやってみたいと思います(今回はCIだけですが)。

**目標**
GitHub Actionsを使用して、PullRequestが作成された際にpytestを実行し、テストが通った場合のみマージできるようにする。

## CI/CDって何？

エンジニアをしているとよく聞く言葉で、カッコいいので私もいつかはやってみたいと思っていましたが、説明しろと言われると難しいもの。

**CI: Continuous Integration（継続的インテグレーション）**
インテグレーションとは「複数の異なるものを1つに統合したり、連携させたりすること」を意味していて、プルリクなどがあった際に、自動でビルドやテストを行なって、バグの早期発見や発見コストの低下を目指す取り組みです。

**CD: Continuous Delivery（継続的デリバリー）または Continuous Deployment（継続的デプロイメント）**
略語で2つの意味を持たせるなと文句を言いたくなりますが、どちらも似たようなもので継続的デリバリーがデプロイ前の状態まで自動化しデプロイを人間の手で行い、継続的デプロイメントはデプロイまで自動化してしまうことです。CDでどこまでやっているかは、その組織によってという感じだと思います。

## 実際にGitHub Actionsを使えるようにする

前提；GitHub Actionsの使用は無料アカウントでもできます。Publicリポジトリの場合は無制限で使用できますが、Privateリポジトリの場合はテスト環境のスペックとテスト時間に制限があります。

ソースコードの詳細は下記、リポジトリを確認してください。

https://github.com/boss-kasai/streamlit-mini-apps

### ymlファイル(workflows)の作成
ルートディレクトリ下に下記ファイルを作成します。

```.github/workflows/pytest.yml```

ファイル名は自由ですが、ディレクトリとファイルの拡張子は変更しないでください。

ファイルの中身は下記になります。
説明はなるべくコメントで記載しました。

```yml:pytest.yml

name: Run pytest # ワークフローにはこれが表示される

on:
  pull_request: # プルリクエスト作成に実行
    branches:
      - main  # mainブランチへのプッシュでトリガー

jobs:
  test:
    name: Python Tests # ジョブ名.ブランチ保護のルールではジョブ名を指定することになるみたい
    runs-on: ubuntu-latest # GitHub Actionsで実行する環境を指定

    steps:
      # リポジトリをチェックアウト
      - name: Check out repository
        uses: actions/checkout@v3

      # Pythonをセットアップ
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.13'  # 必要なPythonのバージョンを指定

      # 必要な依存関係をインストール
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r app/requirements.txt # requirements.txtに記載されたパッケージをインストール

      # pytestを実行
      - name: Run pytest
        run: |
          pytest
```

どんなトリガーで何をするのかを記載していくことになります。
その辺は下記Qiitaの記事などが参考になると思います。
複雑なことをするなら、しっかり勉強しましょう。

https://qiita.com/WisteriaWave/items/dbd6bc432d6b5b0b2e86

### GitHubでの設定

テスト自体はこれで動くと思いますが、今回の目標はPullRequest時に自動でテストを実行してもらいたいのでその設定をGitHubでやっていきましょう。

この設定は、GitHubのブランチ保護ルールを使用します(無料アカウントの場合、リポジトリがpublicでないと使えません)。

事前準備

1. workflowsの実施
GitHubの該当リポジトリのActionsタブから、先ほど作成したworkflowsを実施してテストが通ることを確認してください。

2. __init__.pyの作成

基本的な流れは下記です。

**設定方法**
1. リポジトリの「Settings」タブを開きます
2. サイドメニューの「Branches」を選択します
3. 「Branch protection rulesst」をクリックします
4. 「Rulesets/New branch ruleset」の画面で設定を行います
    Ruleset Name：任意の名前をつけてください
    Enforcement status：Activeに設定
    Bypass list：一旦無視
    Targets：「Add Target」から「Include default branch」を選択(デフォルトのブランチなので、このルールがmainにのみ適用される)
    Branch rules：「Require status checks to pass」にチェックを入れる。「Add checkes」をクリックし、検索欄に「P」と入力すると「Python Tests」が選択肢で出てくるので、それを選択
5. 「create」をクリックしてルールを作成する

下記、画像での上記流れになります。


0.事前準備のworkflowsを実施
何度か私は失敗してから成功しました。
![スクリーンショット 2025-01-24 17.43.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/0be9cf92-7c65-a995-319f-48fff14bb030.png)


1. リポジトリの「Settings」タブを開きます
2. サイドメニューの「Branches」を選択します
![スクリーンショット 2025-01-24 17.43.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/4fde6bd5-8ab1-e8da-7047-1b98369484c9.png)

3. Rulesets/New branch ruleset」の画面で設定
![スクリーンショット 2025-01-24 17.45.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/12b20feb-4927-3ef8-03ee-f1d0d360fcf0.png)
![スクリーンショット 2025-01-25 11.12.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/440a8a6d-0bd5-e70f-88d2-9cf3ec41b9f2.png)

6. 実際にやってみる(プルリクを作成すると、画像のようにテストを自動でやってくれます。このテストは30秒くらいかかりました。)
![スクリーンショット 2025-01-25 11.24.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/a5b0b662-912e-f848-5926-ff1b0bb5279f.png)
![スクリーンショット 2025-01-25 11.25.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570453/27715642-b654-78c5-9d95-dfbb4154d73d.png)


## 実際にやってみて

- GitHubの画面が変わったりするので、この記事もすぐに古くなると思います。なるべく最新の記事を探すか、自分で探索的に頑張ってください
私も最新の情報を探すのに苦労しました
- 今回はとりあえずGitHub Actonsでテストの自動化を目的にしましたが、実際はどのような運用をするかとセットで考え細かい設定が必要だと思います
- テストは意外と時間がかかりました。今回の内容で30秒くらいはかかったので、大規模な開発であったりするともっと時間がかかるかもしれません。その場合は、特定の拡張子のファイルの変更のみを拾ってテストするなどすればテスト時間を減らせると思います
- 私が調べた内容で上手くいかず、頑張っていたらなんとなくできた感じもあるので、この記事の内容で上手くいかない方がいましたら、コメントで教えてください