Github Actionsを使って自動テスト(PHPunit)をパスしないとマージできないようにする

自分でもCI/CD環境を構築したい!と思いつつ、CircleCIはチョット敷居が高い・・・。
と思ったら、GithubでもGithub Actionsを使って自動テストができるらしいことを知ったので設定してみました!

### Githubアクションとは何なのか？

>  設定ファイル(yml)を元にイベント駆動で処理を実行してくれるCI/CDサービス。
Githubで用意した仮装サーバー([ランナー](https://docs.github.com/ja/free-pro-team@latest/actions/learn-github-actions/introduction-to-github-actions#%E3%83%A9%E3%83%B3%E3%83%8A%E3%83%BC)と呼ぶ)使ってジョブを実行する
個人利用の範囲なら無料で利用できる。

### 手順
1.アカウント連携
2.ワークフローファイル(./github/workflows/test.yml)を作成(編集)
3.プルリクを立ててActions実行の確認
4.ブランチ保護設定でワークフローを指定
5.テストに失敗するプルリクを立ててブランチが保護されているのを確認

#### アカウント連携をする
Github Actionsはリポジトリ管理の拡張機能なので、普通にgithubを使っている方でも利用のための設定をする必要があります。

といってもそれほど難しいことはなく、githubにログインした状態でリポジトリを閲覧できるページとかで表示されるGithub Actionsボタンを押すだけです。

＊ここに画像挿入

これでアカウントとしてGithub Actionsを使えるようになりました。

### ワークフローファイルの作成
アカウント連携をした後でリポジトリページを開くと、タブメニューに`Actions`が追加されているので、これをクリックします。
すると、↓のようにリポジトリの内容からワークフローの内容をサジェストしてくれているはずです!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/fb77b6e3-0d4f-7791-3d96-413024f22666.png)

`Set up this workflow`ボタンを押すと、ymlのテンプレートが表示されます。

#### ymlファイルの項目解説

```yml
name: Laravel

on:
  # masterブランチへのpush時
  push:
    branches: [ master ]
  # masterブランチへのプルリク作成時
  pull_request:
    branches: [ master ]

#
jobs:
  laravel-tests:

    runs-on: ubuntu-latest

    steps:
    # 自動テスト用.envのを作成(.env.exampleをコピー)し、ライブラリインストール
    - uses: actions/checkout@v2
    - name: Copy .env
      run: php -r "file_exists('.env') || copy('.env.example', '.env');"
    - name: Install Dependencies
      run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
    # laravelの初期設定コマンド
    - name: Generate key
      run: php artisan key:generate
    - name: Directory Permissions
      run: chmod -R 777 storage bootstrap/cache
    # テスト用DB作成
    - name: Create Database
      run: |
        mkdir -p database
        touch database/database.sqlite
    # .envにテスト用環境変数を書き込みphpunit実行
    - name: Execute tests (Unit and Feature tests) via PHPUnit
      env:
        DB_CONNECTION: sqlite
        DB_DATABASE: database/database.sqlite
      run: vendor/bin/phpunit
```

ファイル内にコメントを書いてますが、
各項目の役割はこんな感じです↓

| 項目 | 役割 |
|:-:|:-:|
| [name](https://docs.github.com/ja/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#name) |ワークフローの名前|
| [on](https://docs.github.com/ja/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#on) | どんな操作があった時にジョブを起動するか  |
| [jobs](https://docs.github.com/ja/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobs) | ワークフローで行われるジョブのグループ |
| [runs-on](https://docs.github.com/ja/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on) | ジョブを実行するランナー(CI/CD処理を行うサーバー)の設定 |
| [steps](https://docs.github.com/ja/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idsteps) | ジョブで段階的に実行される処理 |
| [uses](https://docs.github.com/ja/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses) |コマンドを再利用可能な形に定義したもの。ワークフロー、パブリックリポジトリ、公開Dockerコンテナイメージで定義されているアクションを指定・使用できる|
| name | 各stepsの名前 |
| runs | stepsで実行するコマンド|
|env|ワークフローを実行する時の環境変数|

参考:[公式:ワークフローファイルを理解する](https://docs.github.com/ja/free-pro-team@latest/actions/learn-github-actions/introduction-to-github-actions#%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B)

CI/CDを自分の手で設定したので備忘録として書いておくと、
ワークフロー・ジョブ・ステップの違いは
・ジョブはファイルによって実行されるCI/CD処理(自動テスト)内容のこと
・ステップはジョブを実行するための段階的手順のこと
・起動イベントを含めた処理全体をワークフロー
と捉えておけばいいのかな、と思いました。

### ワークフロー実行の確認
ymlファイルを作るページからそのままプルリクエストを作りましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/a507e73f-140d-415f-d5c1-5696d3b96886.png)
※ テンプレートをそのまま使った場合、マージ先が`master`に向いてないとワークフローが実行されないので注意

また、Actionsタブからもワークフローの経過・結果を確認することができます。


### ブランチ保護設定
最後に、ブランチ保護設定([ステータス](https://docs.github.com/ja/free-pro-team@latest/rest/reference/repos#%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9))でワークフローと結びつける設定を行います。

Settings画面の左メニュー`Branches`を選択後、
`Branch protection rules`>`Add Rules`をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/ebd1bb90-a6bf-cba1-2daa-1ff003129985.png)

・`Branch name pattern`に保護したいブランチの名前
・`Require status checks to pass before merging`にチェックを入れ、先ほど追加したワークフローを選択
・管理者にも保護ルールを適用させたい場合は`Include administrators`にチェック
をして、画面下部のCreateボタンで設定を確定します。

### テスト失敗時にマージできないうことの確認
設定は全て完了したので、最後にテストコードが失敗した時にマージできなくなっていることを確認します。

```
class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');
        // 200でパスするケースを失敗するよう編集
        $response->assertStatus(300);
    }
}
```
↑をpushした後にプルリクのマージボタンを確認すると、マージできなくなっているのが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420171/1ebeed1a-a4c2-a1a3-5b34-33a2458f6c05.png)

また、自分の場合は`Include administrators`にチェックを入れてなかったため、`Use your administrator...`にチェックを入れて制約を無視したマージができるようになっています。

#### 補足
・設定に使うymlファイルの名前はなんでもOK。Githubは`./github/workflows`にあるymlファイルを読み込んでGithub Actionsに使用する
・パブリックリポジトリである必要がある
・sqlite以外のDBを使用する場合はymlファイルの編集が必要

#### 参考資料
[Github Actions公式リファレンス](https://docs.github.com/ja/free-pro-team@latest/actions)
[Github Actions 8ヶ月使ってみてわかったことまとめ](https://qiita.com/bigwheel/items/2ab7deb237122db2fb8d)
[【Github Actions】プッシュ時にgithubに自動でテストを実行してもらおう！](https://www.pnkts.net/2020/03/22/github-actions-phpunit)
[GitHub Actionsを使ってLaravelアプリケーションをCI/CDする](https://www.seeds-std.co.jp/blog/creators/2020-08-19-233031/)