laracel sail + breeze, Github Actions, vercelでCI/CDを構築

# laracel sail + breeze, Github Actions, vercelでCI/CDを行う   
Continuous Integration/Continuous Deliveryの略。   
ソフトウェアの変更を常にテストし、自動で本番環境に適用できる状態へしておく開発手法です。   

laracel sail + breeze, Github Actions, vercelで勉強できないか試してみました。

## CI/CDのメリット
- エラーの早期発見や迅速な修正が可能になる   
- 開発速度と品質の向上が実現する   
- ユーザーと顧客の満足度の向上   
- アフターケアの手間の削減   
- 安定して納期を守る   
- デベロッパーの作業時間を削減する   

## CI/CDの仕組み
- CI（継続的インテグレーション）：開発者がコードを作成しているときに実行される一連のプラクティス  ﻿
- CD（継続的デリバリー）：CIで統合されたソフトウェアを本番に対応できる環境へ届ける手法﻿   
- CI/CDを導入する際には、ビルドスクリプトやテストコードなどの自動化のための準備作業が必要になります。また、一度作成したら終了ではなく、メンテナンスも必要です   

# CI/CDについて学ぶ

| No | 項目 | 概要 |
|:---|:---|:---|
| 1 | [テストプロジェクト](#laravel-sail-project) | laravelのテストプロジェクトを用意します |
| 2 | [CI](#ci) | github actionsにてCIを行います |
| 3 | [CD](#cd) | 無料サーバーへCDをします |

## laravel sail project

1. laravle sailのプロジェクトを用意

```
curl -s "https://laravel.build/vercel-laravel-test-app" | bash
```

```
cd vercel-laravel-test-app
```

```
sail up
```

```
sail composer require laravel/breeze --dev
```

```
sail artisan breeze:install
```

- Blade with Alpine   
- No   
- PHPUnit   

と選択します。
DBの準備をしましょう   

```cmd
sail artisan migrate:fresh --seed
```

- ローカルでテストコードの実行

```cmd
sail test
```

- `sail artisan optimize`実行後にbreezeのテストコードでエラーが出る   
この解決策を記載しているブログが少なくて苦労しました。   
下記のコマンドを全て実行しましょう。   

```
sail artisan cache:clear
sail artisan config:clear
sail artisan route:clear
sail artisan view:clear
```

これでローカル環境のテストが確認できました。

2. Githubのアカウントを作成
3. Githubでリポジトリを作成
4. Githubへプロジェクトをプッシュする

```
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:RubyLrving/vercel-laravel-test-app.git
git push -u origin main
```

## CI
[github actions](https://docs.github.com/ja/actions)

GitHub Actions は、ビルド、テスト、デプロイのパイプラインを自動化できる継続的インテグレーションと継続的デリバリー (CI/CD) のプラットフォームです。 リポジトリに対するすべての pull request をビルドしてテストしたり、マージされた pull request を運用環境にデプロイしたりするワークフローを作成できます。

- ビルドファイルの作成
phpunit.ymlを下記のパスのフォルダ内に作成します。

```
root/.github/workflows
```

- phpunit.ymlを編集します

```yml
name: Laravel

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  DB_USERNAME: sail
  DB_PASSWORD: password
  MAIL_FROM_ADDRESS: info@example.com

jobs:
  laravel-tests:

    runs-on: ubuntu-latest

    services:
      mysql.test:
        image: 'mysql/mysql-server:8.0'
        ports:
          - 3306:3306
        env:
          MYSQL_DATABASE: 'laravel'
          MYSQL_USER: '${{ env.DB_USERNAME }}'
          MYSQL_PASSWORD: '${{ env.DB_PASSWORD}}'
          MYSQL_ALLOW_EMPTY_PASSWORD: 1
        options: >- 
          --health-cmd "mysqladmin ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
    - uses: actions/checkout@v2
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.4'
        tools: composer:v2
    - name: Copy .env
      run: cp .env.example .env.testing
    - name: Install Dependencies
      if: steps.cache.outputs.cache-hit != 'true'
      run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
    - name: Install Node.js dependencies
      run: npm ci
      working-directory: ./ 
    - name: Build assets with Vite
      run: npm run build
      working-directory: ./ 
    - name: Generate key
      run: php artisan key:generate --env testing
    - name: Directory Permissions
      run: chmod -R 777 storage bootstrap/cache
    - name: Set hostname
      run: sudo echo "127.0.0.1 mysql.test" | sudo tee -a /etc/hosts
    - name: Execute tests (Unit and Feature tests) via PHPUnit
      run: vendor/bin/phpunit
```

laravel 10.x、breezeのテストコードを実行させる際に、
Vite のマニフェストファイル（manifest.json）を作成する必要があります。
下記のコマンドで作成します。

```yml
    - name: Install Node.js dependencies
      run: npm ci
      working-directory: ./ 
    - name: Build assets with Vite
      run: npm run build
      working-directory: ./ 
```

- 実行結果

![スクリーンショット 2025-01-03 21.26.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/b8934e82-7e05-6116-191d-33c7955fbb73.png)

プッシュする度に、phpunit.ymlが実行されビルド、テストコードの実行が行われています。

![スクリーンショット 2025-01-03 21.26.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/53d8794e-2bb6-7baa-b102-9b26bd9e188c.png)

45sでテストが完了してプッシュ時にテストコードの実行が成功しています。

## CD
[vercel](https://vercel.com)を使用します。
デプロイには、

- laravelとlaravel sail
- DBとpostgreの知識
- composer
- ファイルの書き込み権限
- session, cacheの知識
- 環境変数の知識

が必要になります。
順番にやっていきましょう。

### vercelのアカウントを作成、Githubと連携

[VercelでLaravel10をデプロイしてVercel Strage(DB)を繋ぐ](https://qiita.com/ogwayk/items/60fbc1d9b1387ce10632)

これを参考にvercelとneonのDB, envファイルを用意してください。 

### vercel webサーバー

- output directory
publicを入力します。

![スクリーンショット 2025-01-10 0.16.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/2432e259-cac8-5e69-587c-678a5629ef88.png)

- node.js
18.xを指定します。

![スクリーンショット 2025-01-10 0.16.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/ab0a1865-c383-8538-44e4-9cb7e0ef0678.png)

### neon postgre sql

- singapore
リージョンはシンガポールを設定しています。
後の設定はデフォルトです。

![スクリーンショット 2025-01-10 0.18.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/41a7fed8-a0fe-61a4-4732-4cf7b1e5ae95.png)

### laravel sail

- vercelのモジュールをインストール
```
sail composer require revolution/laravel-vercel-installer --dev
```

```
sail artisan vercel:install
```   
  
- .env.productionの作成
本番環境用の.envを作成します。


```tex:.env
APP_NAME=Laravel
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_TIMEZONE=UTC
APP_URL=
ASSET_URL=

DB_CONNECTION=
DB_HOST=
DB_PORT=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
DATABASE_URL=

LOG_CHANNEL=stderr
CACHE_DIRECTORY=/tmp/laravel/cache
SESSION_DRIVER=cookie
APP_STORAGE=/tmp
```

1. APP_URL
laravelで設定されるURLに影響します。   

2. ASSET_URL
viteが生成するリソースのURLに影響します。   

3. CACHE_DIRECTORY, SESSION_DRIVER
laravel sailだとradiesのキャッシュサーバーなどを使っているので、vercelのwebサーバー用に設定しましょう。   


- .env.production
vercelのdashboard, setting, Environment Variablesからenv importの機能でenvファイルを読み込みできます。  
毎回手動で入力するのは大変なので、この機能を使いましょう。   

- composer.jsonの編集
scriptsの項目に以下を追加しましょう。

```tex:composer.json
        "vercel-build": [
            "composer install --no-dev --optimize-autoloader",
            "chmod -R 777 bootstrap/cache",
            "php artisan config:cache",
            "php artisan route:cache",
            "php artisan view:cache"
        ]
```

- vercel.json

下記の設定です。

```json:vercel.json
{
    "regions": [
        "hnd1"
    ],
    "functions": {
        "api/index.php": {
            "runtime": "vercel-php@0.6.2"
        }
    },
    "routes": [
        {
            "src": "/build/(.*)",
            "dest": "/public/build/"
        },
        {
            "src": "/(.*)",
            "dest": "/api/index.php"
        }
    ],
    "env": {
        "APP_NAME": "Laravel Vercel",
        "APP_DEBUG": "false",
        "APP_CONFIG_CACHE": "/tmp/config.php",
        "APP_EVENTS_CACHE": "/tmp/events.php",
        "APP_PACKAGES_CACHE": "/tmp/packages.php",
        "APP_ROUTES_CACHE": "/tmp/routes.php",
        "APP_SERVICES_CACHE": "/tmp/services.php",
        "CACHE_DRIVER": "array",
        "CACHE_STORE": "array",
        "LOG_CHANNEL": "stderr",
        "SESSION_DRIVER": "cookie",
        "VIEW_COMPILED_PATH": "/tmp"
    }
}
```

![スクリーンショット 2025-01-10 0.25.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/81122f41-c6ab-1d8f-bfbe-1a400693ad2b.png)

![スクリーンショット 2025-01-10 0.25.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626801/cdd9c57a-a2b9-dda8-37dc-cf20f89fdb70.png)

フロントエンドのvite、DBへの接続もできています。
breezeのアカウントの作成もできています。

# 最後に

laravel sailのプロジェクトの設定、環境変数を理解しました。
またGithub Actionsでのテストコードのチェック、ビルドファイルへの理解が深まりました。
vercelというサーバーレスアーキテクチャに触れ、本番サーバーとローカルサーバーの差分を理解しました。
この勉強はよかったと思います。