🙌

Laravel Sail + GithubActionsでCIを作成する

2022/09/02に公開2

環境

PC

機種 : MacBook Pro 2021(M1 Max)
OS : Monterey(12.2.1)

Laravel Sail

PHP version : 8.1.9
Laravel version : 9.25.1

ワークフローファイルを作成する

https://readouble.com/laravel/9.x/ja/sail.html

example-app/にLaravelプロジェクトがあります。mainブランチに対してPRを出すとCIが実行されるようにします。

.github/workflows/ci.yml
name: CI

on:
  pull_request:
    branches: [ "main" ]

jobs:
  laravel-tests:

    runs-on: ubuntu-latest
    # laravelプロジェクトのあるディレクトリに変更
    defaults:
      run:
        working-directory: ./example-app

    steps:
      - uses: actions/checkout@v3

      - name: cp env
        run: cp .env.example .env

      - name: composer install
        run: docker run --rm -u "$(id -u):$(id -g)" -v $(pwd):/var/www/html -w /var/www/html laravelsail/php81-composer:latest composer install --ignore-platform-reqs

      # 先に起動しておく
      - name: start mysql
        run: ./vendor/bin/sail up -d mysql

      - name: start
        run: ./vendor/bin/sail up -d

      - name: generate key
        run: ./vendor/bin/sail artisan key:generate

      - name: migrate
        run: ./vendor/bin/sail artisan migrate

      - name: test
        run: ./vendor/bin/sail test

DB接続のあるAPIエンドポイントのテストを書く

CIでDBに接続できなかったりする時があるので、テストを書いておきます。
簡単なレコード追加のコードを書いておきます。

example-app/routes/api.php
+Route::post('/user', \App\Http\Controllers\PostUserController::class);
example-app/app/Http/Controllers/PostUserController.php
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class PostUserController extends Controller
{
    public function __invoke(Request $request)
    {
        $user = User::create([
            'name' => 'lightkun',
            'email' => 'lightkun@example.com',
            'password' => Hash::make('password'),
        ]);

        return response()->json([
            'user_name' => $user->name
        ]);
    }
}
example-app/tests/Feature/PostUserTest.php
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PostUserTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic test example.
     *
     * @return void
     */
    public function test_the_application_returns_a_successful_response()
    {
        $response = $this->postJson('/api/user');

        $response->assertStatus(200)
            ->assertExactJson([
                    "user_name" => "lightkun"
        ]);

        $this->assertDatabaseHas('users', [
                'name' => 'lightkun',
                'email' => 'lightkun@example.com',
        ]);
    }
}

CI用に環境変数を変更しておきます。

example-app/.env.example
-DB_HOST=127.0.0.1
+DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=example_app
-DB_USERNAME=root
-DB_PASSWORD=
+DB_USERNAME=sail
+DB_PASSWORD=password

これでCIが通れば成功です。

株式会社ゆめみ

Discussion

mash180sxmash180sx

CIでDBに接続できなかったりする時があるとのことですが、どのぐらいの頻度で起こるのでしょうか。
私の手元ではCIで100%近く(初回は成功したんですが、その後一回も成功せず。。)migrateで失敗してしまいます。。もちろん、ローカルでは成功するので、無駄な時間が流れて困っています。。。

タカラボタカラボ

横からすみません。Sailは使ったことないのでわかりませんが、docker-compose.ymlではWebサーバーコンテナの設定を以下のようにして、データベースの立ち上げが完全に終わるまで待つようにします。Sailでも似たような設定が出来るかと思うので、それをすれば確実にmigrate可能です。

depends_on:
        db:
          condition: service_healthy