⚙️

laravelで開発を行う際にミスを防ぐCI設定

2023/01/13に公開

はじめに

自動でテストや静的解析をcommit時に実行したり、
pushの際にGithubActionsでテストや静的解析を行うようにしたり
masterに直pushしないように設定したり...
自分が忘れたときのために書いておきます。もし詰まっている人の助けになれば嬉しいです。

必要なツールのインストール

静的解析にlarastan
linterにpint
を使うのでインストール

 composer require laravel/pint --dev
 composer require nunomaduro/larastan --dev

ルートフォルダにphpstan.neonを下記の内容で作成

includes:
    - ./vendor/nunomaduro/larastan/extension.neon

parameters:

    paths:
        - app
        - tests

    # The level 9 is the highest level
    level: 9

    # ignoreErrors:
    #    - '#Unsafe usage of new static#'

    excludePaths:
        - ./*/*/FileToBeExcluded.php

    checkMissingIterableValueType: false

local編

localではcommitするときにテストや静的解析を走らせ、またmasterやdevelopなど直にcommitしたくないブランチを保護します。

pre-commit

gitのpre-commitHookをつかってcommit時の挙動を設定。
.git/hooksの中のpre-commitに例がありますが、git管理されないので.githooks/pre-commitを作りそこに設定を書きます。

#!/bin/bash

echo "Running Tests..."

cmd="php artisan test"

$cmd

if [[ $? -ne 0 ]]; then
  echo "error"
  exit 1
fi

echo "Running LaraStan..."

cmd="./vendor/bin/phpstan analyse"

$cmd

if [[ $? -ne 0 ]]; then
  echo "error"
  exit 1
fi

echo "Running Pint..."

cmd="./vendor/bin/pint"

$cmd

if [[ $? -ne 0 ]]; then
  echo "error"
  exit 1
fi

Running Tests...から始まるブロックではtestを実行、
Running LaraStan...ではlarastanを、
Running Pint...ではpintを動かしています。

if [[ $? -ne 0 ]] の部分は $?でコマンドのステータスを取得して、
0以外はエラーなのでexitしてcommitされないようにしています。

以上でコミット時に.githooks/pre-commitで設定したコマンドが実行され、testや静的解析が走るようになり、失敗時にはコミットを防げます。

参考
https://www.youtube.com/watch?v=ooF6t2ITu58&ab_channel=AmitavRoy

特定のブランチでのコミットを防ぐ

vscodeを使っているのでvscodeでの設定。
vscode以外は参考元のリンクを参照してください。

1.Ctrl+Shift+Pでコマンドパレットを開き、OpenSettings(UI)を開きます。
2.検索欄でgit.branchprotectionと入力し、branchProtectionのAddボタンから保護したいブランチを入力します。
これでvscode上の左下のブランチ名に鍵マークがついて保護完了です。

注意点
git commit ~のコマンドを直に叩くと保護できません。あくまでvscode上の保護なので...
なので、commitする際はvscodeのSourceControlからコミットするようにしましょう。

あとはマージも防げません。masterを保護しているとして、master <- feature/someFeature...
みたいなマージも通るのでそこも注意しましょう。

参考
https://tech-blog.cloud-config.jp/2022-07-13-protect-git-local-branch/

Remote編

master,featureブランチがあるとして、下記の動作を達成するように設定します。

1.masterへのpush,PullRequest時にgithubActionsで設定した動作(testや静的解析)が動くようにする
2.masterへの直プッシュを防ぐ

GithubActionsの設定から。

レポジトリ上のActionsをクリック

laravelで検索しconfigureをクリック

templateが表示されるので後はこのtemplateを修正

修正後

name: Laravel

on:
  push:
    branches: ["master"]
  pull_request:
    branches: ["master"]

jobs:
  laravel-tests:
    runs-on: ubuntu-latest

    steps:
      - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e
        with:
          php-version: "8.0"
      - uses: actions/checkout@v3
      - 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
      - name: Generate key
        run: php artisan key:generate
      - name: Directory Permissions
        run: chmod -R 777 storage bootstrap/cache
      - name: Create Database
        run: |
          mkdir -p database
          touch 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
	
      # 下記の二つを加える
      - name: Execute LaraStan
        run: ./vendor/bin/phpstan analyse
      - name: Execute Pint
        run: ./vendor/bin/pint


修正といってもphpstanとpintが動くように4行追加しただけです。
もしmasterブランチ以外でpush,PullRequest時にActionsが走るようにしたい場合は下記を修正します。

on:
  push:
    branches: ["master","develop"]
  pull_request:
    branches: ["master","develop"]

上記でmasterへのpush,PullRequest時にtestや静的解析,linterが走るようになります。

1だけではmasterへの直プッシュが可能なので制限します。

settings -> サイドバーのbranchをクリック -> Add Rule

設定画面

--Branch name pattern
保護したいブランチ名を検索し指定。

--Protect matching branches
Require a pull request before mergingにチェックすると、マージ前にPullRequestが必須になります。
必要に応じてPullRequestに承認を必要とするRequire approvalsなどにもチェック。

--Require status checks to pass before mergeing
検索欄からGithubActionsで作ったActionを選ぶとそのActionが成功しなければマージ不可となります。
なのでmaster <- featureのPR時にActionが走り、Action内のテスト等が失敗したらマージボタンが押せなくなります。

--Do not allow bypassing the above settings
この設定をするとレポジトリの作成者も上記の制限を受けるようになります。
裏を返せばここにチェックをしないとレポジトリ作成者はmasterに直プッシュできてしまうので注意。

注意点
include administratorが2023/1/13時点では無くなっていて、Do not allow bypassing the above settingsがinclude administrator相当の設定になっているみたいです。
include administratorを探しても見つからなかったのでどこの設定をいじればよいかわかりませんでした...(一敗)

参考
https://techracho.bpsinc.jp/wingdoor/2020_07_03/93868

Discussion