GitHub Actionsを利用してLaravelのテストを自動化してみた

GitHub Actionsを利用してLaravelのテストを自動化するのに少しハマったのでメモ。


## 前提

Laravel Sailで作成したプロジェクトの[GitHubリポジトリ](https://github.com/kai-kou/laravel-sail-sample-projects)にワークフローを追加する手順となります。

## 手順

### ローカルでワークフロー実行ができるツールのインストール

ローカルでワークフロー実行ができるツールがありました🚀🚀🚀

nektos/act: Run your GitHub Actions locally 🚀
https://github.com/nektos/act

インストール方法も簡単なので導入しやすいです。

```console:Macの場合
> brew install act
```

セットアップスクリプトも提供されているので、Mac以外でもインストールは簡単です。

```console
> curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
```

### ワークフローを設定する

ツールがインストールできたらワークフローを作成します。
GitHubのサイトでもワークフローが作成でき、テンプレートも提供されていますが、修正しないと動作しないケースが多かったので、色々とサイトを参考にしつつ設定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/0f3402c9-ac54-28f7-f48d-3c30a94a41a5.png)

```console
> cd <プロジェクトのディレクトリ>
> mkdir -p .github/workflows
> touch .github/workflows/unittest.yml
```

定義したワークフローは以下となります。

```yaml:unittest.yml

name: Laravel

on:
  push:
    branches:
    - main
    - feature/**
  pull_request:
    branches:
    - main

jobs:
  laravel-tests:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: cache vendor
      id: cache
      uses: actions/cache@v1
      with:
        path: ./vendor
        key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
        restore-keys: |
          ${{ runner.os }}-composer-
    - name: composer install
      if: steps.cache.outputs.cache-hit != 'true'
      run: composer install -n --prefer-dist
    - name: copy .env
      run: cp .env.example .env
    - name: generate key
      run: php artisan key:generate
    - name: Create Database
      run: |
        mkdir -p database
        touch database/database.sqlite
    - name: migrate
      run: php artisan migrate
      env:
        DB_CONNECTION: sqlite
        DB_DATABASE: database/database.sqlite
    - name: Execute tests (Unit and Feature tests) via PHPUnit
      env:
        DB_CONNECTION: sqlite
        DB_DATABASE: database/database.sqlite
      run: vendor/bin/phpunit
```

#### イベントトリガーの指定

ワイルドカードが利用できるのでfeatureブランチも指定できます。

ワークフローをトリガーするイベント - GitHub Docs
https://docs.github.com/ja/actions/reference/events-that-trigger-workflows

GitHub Actionsでブランチ毎にワークフローを分ける - code-log
https://code-log.hatenablog.com/entry/2020/02/07/201830

```yaml
on:
  push:
    branches:
    - main
    - feature/**
  pull_request:
    branches:
    - main
```

#### パッケージのインストール

GitHub上ワークフロー実行する際にはキャッシュが効くので、下記を参考に`vendor`ディレクトリが存在するか否かで`composer install`が実行されるようにしました。

cache/examples.md at main · actions/cache 　
https://github.com/actions/cache/blob/main/examples.md#php---composer

```yaml
    - name: cache vendor
      id: cache
      uses: actions/cache@v1
      with:
        path: ./vendor
        key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
        restore-keys: |
          ${{ runner.os }}-composer-
    - name: composer install
      if: steps.cache.outputs.cache-hit != 'true'
      run: composer install -n --prefer-dist
```

#### データベースの準備

今回はSQLiteでもテスト実行できたので、データベースを準備します。

```yaml
    - name: Create Database
      run: |
        mkdir -p database
        touch database/database.sqlite
```

#### マイグレーションとテスト実行

マイグレーションとテスト実行時にSQLiteを利用するように環境変数を設定します。
`.env.ci`などのファイルをプロジェクトに含めておくのもありです。

```yaml
    - name: migrate
      run: php artisan migrate
      env:
        DB_CONNECTION: sqlite
        DB_DATABASE: database/database.sqlite
    - name: Execute tests (Unit and Feature tests) via PHPUnit
      env:
        DB_CONNECTION: sqlite
        DB_DATABASE: database/database.sqlite
      run: vendor/bin/phpunit
```

### ローカルで動作確認

actを利用してローカルでワークフローを実行します。

```console
# ワークフローの一覧
> act -l
ID             Stage  Name
laravel-tests  0      laravel-tests

# ワークフローの実行
> act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04
```

`-P`オプションで実行する環境のDockerイメージを指定します。actツール作成している方がイメージをいくつかしてくれていますが、Composerが利用できるのが指定したイメージとなります。

nektos/act: Run your GitHub Actions locally 🚀 https://github.com/nektos/act#runners

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/f0741da4-d343-d6d4-d441-aeba26fb1314.png)

初回はイメージの取得で時間がかなりかかりますが、2回目からはサクサク動作します。

### GitHubで動作確認

作成したワークフローをGitHubリポジトリにPushするついでにワークフローの動作確認をします。

```console
> git brunch feature/use-github-actions
> git checkout feature/use-github-actions
> git add .github/
> git commit -m 'Add: テスト用のGitHub Actions定義ファイルを追加しました。'
> git push --set-upstream origin feature/use-github-actions
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/d852df28-c605-d6bd-de3b-6924a6922db0.png)

GitHub上でもワークフローが動作することが確認できました。
やったぜ


## 参考

nektos/act: Run your GitHub Actions locally 🚀
https://github.com/nektos/act#installation

ワークフローをトリガーするイベント - GitHub Docs
https://docs.github.com/ja/actions/reference/events-that-trigger-workflows

GitHub Actionsでブランチ毎にワークフローを分ける - code-log
https://code-log.hatenablog.com/entry/2020/02/07/201830

cache/examples.md at main · actions/cache 　
https://github.com/actions/cache/blob/main/examples.md#php---composer

GitHub Actions で LaravelのCI/CD環境を構築する（MySQL, Deployer） - Qiita
https://qiita.com/wim/items/7eb8386672fd114c2576

GitHub ActionsでLaravelのCI環境を作ってみた｜TechRacho（テックラッチョ）〜エンジニアの「？」を「！」に〜｜BPS株式会社
https://techracho.bpsinc.jp/wingdoor/2020_07_03/93868