Skip to content
Latchkey

CI/CD for a Laravel + Pest App with GitHub Actions

Run Pest against MySQL, build assets, and deploy your Laravel app.

Pest is an expressive PHP test framework that runs on top of PHPUnit. This recipe sets up PHP and Node, runs Laravel migrations against a MySQL service, runs Pest, and builds front-end assets.

What the pipeline does

  • set up PHP with extensions and Composer cache
  • install Composer and npm deps
  • run migrations against a MySQL service
  • run the Pest suite
  • build assets with Vite

The workflow

shivammathur/setup-php provides PHP and extensions. A MySQL service backs the suite; php artisan migrate prepares the schema before Pest runs.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: app
        ports: ["3306:3306"]
        options: >-
          --health-cmd "mysqladmin ping" --health-interval 10s
          --health-timeout 5s --health-retries 5
    env:
      DB_CONNECTION: mysql
      DB_HOST: 127.0.0.1
      DB_DATABASE: app
      DB_USERNAME: root
      DB_PASSWORD: root
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: "8.3"
          extensions: mbstring, pdo_mysql
          tools: composer
      - run: composer install --no-interaction --prefer-dist
      - run: cp .env.example .env && php artisan key:generate
      - run: php artisan migrate --force
      - run: ./vendor/bin/pest
      - run: npm ci && npm run build

Caching and speed

Cache the Composer and npm caches with actions/cache keyed on composer.lock and package-lock.json. The MySQL-backed Pest run is the slow part, so cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) keep cost low, and auto-retry covers a flaky MySQL start.

Deploying

Deploy with your tool of choice (Laravel Forge, Envoyer, a container, or rsync over SSH). Run php artisan migrate --force on the server during deploy, and php artisan config:cache plus route:cache to warm caches.

Key takeaways

  • setup-php pins the PHP version and required extensions.
  • Run php artisan migrate against a MySQL service before Pest.
  • Cache both Composer and npm to cut install time.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →