Laravel Pintの実行をGitHub Actionsで自動化

# はじめに
個人開発アプリ作成において、Laravel Pintの実行をGitHub Actionsで自動化してみたので、そのソースコードや躓いた内容を記載します。Laravelのソースコードの整形を自動化したい方には参考になるかもしれません。

# Laravel Pintとは
Laravelのコードスタイルの自動整形ツールです。
Readoubleでは、下記のように記載されています。

> Laravel Pint（ピント：PHP+lint）は、ミニマリストのための主張を持ったPHPコードスタイルフィクサです。PintはPHP-CS-Fixer上に構築されており、あなたのコードスタイルがクリーンで一貫したものになるよう、シンプルにします。
> Pintは、すべての新しいLaravelアプリケーションに自動的にインストールされますので、すぐに使い始めることができます。デフォルトで、Pintは設定を必要とせず、Laravelの主張を取り入れたコーディングスタイルに従い、コードスタイルの問題を修正します。

https://readouble.com/laravel/11.x/ja/pint.html

下記のコマンドを実行すると、コードスタイルの修正が行われます。
```
./vendor/bin/pint
```

始めてPintを実行する場合、大量にコードが修正されることがあるため、`--test`オプションを付けることを推奨します。

```
./vendor/bin/pint --test
```

# GitHub Actionsとは
あらかじめ定義した処理と条件の組合せ（＝ワークフロー/Workflow）を自動化するGitHub公式の機能です。
GitHub Actionsではリポジトリに対するプッシュなどの処理をトリガーとして、専用のWorkflowに定義しておいた処理を自動で実行します。

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

https://docs.github.com/ja/actions/about-github-actions/understanding-github-actions

用語（ワークフロー、ジョブ、ステップなど）の説明は省きます。
下記の記事がわかりやすかったです。

https://qiita.com/shun198/items/14cdba2d8e58ab96cf95

# ソースコード

実際に私が記載したソースコードを共有します。

https://github.com/yuuhei-koutoku/laravel-ecsite/blob/main/.github/workflows/pint.yml

```yml:.github/workflows/pint.yml
name: Run Laravel Pint

on: [pull_request]

jobs:
  pint:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.ref }}

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          extensions: bcmath, ctype, curl, dom, fileinfo, gd, intl, json, mbstring, openssl, pdo_mysql, pdo_pgsql, tokenizer, xml
          tools: composer:v2.5.4

      - name: Install Composer dependencies
        run: composer install --prefer-dist --no-progress --no-suggest --ansi

      - name: Run Laravel Pint
        run: vendor/bin/pint

      - name: Commit and Push changes
        run: |
          git config --global user.name "GitHub Actions[bot]"
          git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add -A
          git commit -m "Automated code format" || exit 0
          git push
```

- `name: Run Laravel Pint`
このワークフローに「Run Laravel Pint」という名前を付けています。
- `on: [pull_request]`
プルリクエストが作成された際にワークフローが実行されます。
- `jobs:`
「pint」というジョブが定義されています。
    - `runs-on: ubuntu-latest`
ジョブは`ubuntu-latest`という最新のUbuntu環境で実行されます。
    - `steps:`
ジョブ内で実行される各ステップが定義されています。
        - `- name: Checkout`
GitHub Actionsがリポジトリのコードをチェックアウトします。`actions/checkout@v4`アクションを使用してリポジトリの内容を取得します。
`ref: ${{ github.event.pull_request.head.ref }}`により、プルリクエストのブランチを取得し、そのブランチをチェックアウトします。
        - `- name: Setup PHP`
PHPのセットアップを行います。`shivammathur/setup-php@v2`アクションを使用して`PHP 8.2`をインストールします。
`extensions`では拡張機能をインストールします。
`tools`ではComposerのバージョンを指定し、ここでは`composer:v2.5.4`をインストールします。
        - `- name: Install Composer dependencies`
依存パッケージをインストールします。`composer install --prefer-dist --no-progress --no-suggest --ansi`コマンドを使用して、Composerの依存関係をインストールします。
`--prefer-dist`は、ソースコードではなく、事前にパッケージ化されたファイルを優先的に使用するオプションです。
`--no-progress`, `--no-suggest`は、ログ出力を軽減するためのオプションです。
        - `- name: Run Laravel Pint`
実際にLaravel Pintを実行します。`vendor/bin/pint`コマンドを実行し、コードのフォーマットチェックや自動整形を行います。
        - `- name: Commit and Push changes`
フォーマットされた変更を自動的にコミットし、リモートリポジトリにプッシュします。
`git config --global`で、GitHub Actionsのbotユーザーとしての名前とメールアドレスを設定します。
`git add -A`で全ての変更をステージングし、`git commit -m "Automated code format"`でコミットします。`|| exit 0`は、コミットが失敗してもジョブを終了させないための保険として使用されています（フォーマットの変更がない場合、`git commit`は何もせずにエラーを返すため）。
最後に`git push`でリモートリポジトリに変更をプッシュします。

# 躓いたエラー・不具合

### インデントを間違えていた

`yml`ファイルは、インデントの位置によりデータ構造が決まります。インデントを間違えると、当然エラーになります。

<details><summary>エラー詳細</summary>

![スクリーンショット 2024-10-02 15.05.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/b5c6cb67-3fda-eec1-84ef-1f66bc344481.png)
```
Invalid workflow file
No steps defined in `steps` and no workflow called in `uses` for the following jobs: pint
```

![スクリーンショット 2024-10-02 15.06.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/8912a19f-0038-4546-69e6-0812c99817d2.png)
```
Invalid workflow file
You have an error in your yaml syntax on line 10
```
</details>

<details><summary>エラー解消</summary>

`No steps defined in 'steps' and no workflow called in 'uses' for the following jobs: pint`を解消
![スクリーンショット 2024-10-02 15.52.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/d905c9b6-dada-88a5-6c93-e34cca347f4d.png)

`You have an error in your yaml syntax on line 10`を解消
![スクリーンショット 2024-10-02 15.53.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/3dd76132-d36c-755b-29e8-e974eeaa7411.png)
</details>

### phpのバージョンを間違えていた
PHPのセットアップのステップでPHPのバージョンが正しく設定されていないとエラーになります。

<details><summary>エラー詳細</summary>

![スクリーンショット 2024-10-02 15.15.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/ba0803a6-f040-ac94-8520-32daa754efe0.png)

```
Run composer install --prefer-dist --no-progress --no-suggest --ansi
You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3.
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Your lock file does not contain a compatible set of packages. Please run composer update.

  Problem 1
    - carbonphp/carbon-doctrine-types is locked to version 3.2.0 and an update of this package was not requested.
    - carbonphp/carbon-doctrine-types 3.2.0 requires php ^8.1 -> your php version (8.0.30) does not satisfy that requirement.
Error: Your lock file does not contain a compatible set of packages. Please run composer update.
```
</details>

<details><summary>エラー解消</summary>

リポジトリで使用されているPHPのバージョンと、`pint.yml`のPHPのバージョンを一致させれば解消できます。`php -v`コマンドでPHPのバージョンを確認し、ソースコードを修正しましょう。
![スクリーンショット 2024-10-02 15.59.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/896dabd0-759c-6b21-8b4c-5ae6390b7e17.png)
</details>

### Laravel Pint実行時、`--test`オプションを付けるとエラーになる場合がある
ワークフロー自体が正常に実行されている（Laravel Pintによるチェックは正常に実行されている）場合でも、`vendor/bin/pint`コマンドに`--test`オプションを付けるとエラーになる場合があります。
コードスタイルに問題があると、ワークフローは「失敗（エラー）」として記録されます。（コードスタイルに問題ない場合は「成功」となります。）

<details><summary>エラー詳細</summary>

![スクリーンショット 2024-10-02 16.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/a1be49dd-55e6-fd6c-2bc1-362bd6d1dcd5.png)

```
Run vendor/bin/pint --test

  .........................⨯...⨯..⨯⨯⨯⨯..⨯..........⨯⨯⨯.⨯................⨯.....
  ⨯...................⨯..⨯..⨯⨯...⨯..⨯..⨯⨯⨯.⨯...⨯..⨯..⨯⨯⨯..................⨯.⨯⨯
  ⨯

  ──────────────────────────────────────────────────────────────────── Laravel  
    FAIL   ........................................ 153 files, 32 style issues  
  ⨯ app/Http/Controllers/Admin/Auth/NewPasswordController.php method_chaining…  
  ⨯ app/Http/Controllers/Admin/Auth/PasswordResetLinkController.php method_ch…  
  ⨯ app/Http/Controllers/Admin/InquiryController.php method_chaining_indentat…  
  ⨯ app/Http/Controllers/Admin/OwnersController.php method_chaining_indentati…  
  ⨯ app/Http/Controllers/Owner/Auth/NewPasswordController.php method_chaining…  
  ⨯ app/Http/Controllers/Owner/Auth/PasswordResetLinkController.php method_ch…  
  ⨯ app/Http/Controllers/Owner/ImageController.php method_chaining_indentatio…  
  ⨯ app/Http/Controllers/Owner/ProductController.php method_chaining_indentat…  
  ⨯ app/Http/Controllers/Owner/ShopController.php method_chaining_indentation…  
  ⨯ app/Http/Controllers/ProfileController.php     method_chaining_indentation  
  ⨯ app/Http/Controllers/User/Auth/NewPasswordController.php method_chaining_…  
  ⨯ app/Http/Controllers/User/Auth/PasswordResetLinkController.php method_cha…  
  ⨯ app/Http/Controllers/User/CartController.php method_chaining_indentation,…  
  ⨯ app/Http/Controllers/User/InquiryController.php method_chaining_indentati…  
  ⨯ app/Http/Controllers/User/ItemController.php method_chaining_indentation,…  
  ⨯ app/Jobs/SendOrderedMail.php                   method_chaining_indentation  
  ⨯ app/Jobs/SendThanksMail.php                    method_chaining_indentation  
  ⨯ app/Models/Product.php method_chaining_indentation, unary_operator_spaces…  
  ⨯ app/Models/User.php                            method_chaining_indentation  
  ⨯ app/Services/CartService.php                   method_chaining_indentation  
  ⨯ app/Services/ImageService.php                                 concat_space  
  ⨯ database/migrations/2023_05_05_074226_create_shops_table.php class_defini…  
  ⨯ database/migrations/2023_05_11_102827_create_images_table.php class_defin…  
  ⨯ database/migrations/2023_05_12_085706_create_categories_table.php class_d…  
  ⨯ database/migrations/2023_05_12_101634_create_products_table.php class_def…  
  ⨯ database/migrations/2023_05_14_095122_create_stocks_table.php class_defin…  
  ⨯ database/migrations/2023_05_22_110715_create_carts_table.php class_defini…  
  ⨯ database/migrations/2023_06_06_115055_create_inquiries_table.php class_de…  
  ⨯ routes/admin.php        method_chaining_indentation, statement_indentation  
  ⨯ routes/auth.php                                method_chaining_indentation  
  ⨯ routes/owner.php        method_chaining_indentation, statement_indentation  
  ⨯ routes/web.php                                       statement_indentation  

Error: Process completed with exit code 1.
```
</details>

<details><summary>エラー解消</summary>

実行コマンドの`--test`オプションを削除した上で、GitHubの設定を追加すれば解消できます。

:::note warn
大量のソースコードが修正される場合があるので、要注意。
:::
![スクリーンショット 2024-10-02 16.16.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/bbfd1809-0b12-d34b-7949-d1ca136f2e49.png)
</details>

### 権限不足によるエラー
権限が不足しているとエラーになるので、設定変更を行いましょう。

<details><summary>エラー詳細</summary>

```
Run git config --global user.name "GitHub Actions[bot]"
[automating_laravel_pint 79fbcac] Automated code format
 32 files changed, 202 insertions(+), 203 deletions(-)
remote: Permission to yuuhei-koutoku/laravel-ecsite.git denied to github-actions[bot].
fatal: unable to access 'https://github.com/yuuhei-koutoku/laravel-ecsite/': The requested URL returned error: 403
Error: Process completed with exit code 128.
```
</details>

<details><summary>エラー解消</summary>

1. リポジトリのSettingsを押下
1. Actionsのgeneralを押下
1. Workflow permissionsのRead and write permissionsを選択し、Saveを押下

![スクリーンショット 2024-10-02 16.26.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/ad22e139-2f5d-edc6-5a75-ef710178da3c.png)
</details>

https://zenn.dev/osawa_koki/articles/a63b96a2707a8f

# 成功時

### Pull requests
プルリクエスト作成直後、ワークフローが実行されます。
![スクリーンショット 2024-10-04 14.21.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/cb21a213-5699-70c0-a54c-686b462fe093.png)

しばらく時間が経ち、`All checks have passed`が表示されればOKです。
![スクリーンショット 2024-10-04 14.21.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/06fb02ba-6c03-1a09-70f8-0c08cc699e4f.png)

実際にコードスタイルの修正が行われた場合は、自動的にコミットされます。
![スクリーンショット 2024-10-04 14.31.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/4a40f7fa-7397-dd2d-fc7f-223730ba5a59.png)
![スクリーンショット 2024-10-04 14.32.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/85c9f574-d315-b1a2-2a1f-991e92da8f9b.png)

### Actions
ワークフローが成功すると、緑色のチェックマークが表示されます。👏
![スクリーンショット 2024-10-02 16.46.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935364/fe1dc8f7-137d-13de-d5db-3966afcae8bc.png)

# さいごに
今まではプッシュを行う前に`./vendor/bin/pint`コマンドを実行していたのですが、それをGitHub Actionsを用いて自動化することで、かなり楽になりました。
費用対効果は高いので、取り組んでみて良かったと感じています。
GitHub Actionsは始めて使ってみました。
間違った説明やソースコードの改善点などあれば、ご指摘いただけると幸いです。
最後まで読んでいただき、ありがとうございました！

# 参考文献

https://zenn.dev/tatsuyaaa/articles/bd5b73ef1f1882

https://qiita.com/shun198/items/14cdba2d8e58ab96cf95

https://www.kagoya.jp/howto/it-glossary/develop/githubactions/