How to setup Github Workflow for Laravel Pint and PHP Pest testing

Categories - Laravel PHP Framework Tags - PHP Laravel   Maniruzzaman Akash   1 year ago   1255   6 minutes   0

What is Github Workflow

GitHub Workflow is a powerful tool that allows developers to automate various tasks and processes related to software development, such as building, testing, and deploying applications.

GitHub Workflows are defined using YAML (Yet Another Markup Language) syntax and are stored in a file called .github/workflows/main.yml within the repository. This file contains the configuration details for the workflow, including the events that trigger it, the jobs to be executed, and the steps to be performed within each job.

Laravel Pint

Laravel Pint is an opinionated PHP code style fixer for minimalists. Pint is built on top of PHP-CS-Fixer and makes it simple to ensure that your code style stays clean and consistent.

This Laravel Pint is now built in code fixer for Laravel application (Laravel 10.x).

Now fixing code style in Laravel is lot simpler. Just run the command of Pint -

./vendor/bin/pint

And it will fix all of the normal coding styling issue, formatting issue, which is super useful.

PHP Pest

PHP Pest is a testing framework for PHP applications. It is inspired by Jest, a popular testing framework for JavaScript. Pest provides a clean and expressive syntax for writing tests and comes with a wide range of features to simplify the testing process.

We can say PHP Pest is a total alternative for PHPUnit. Pest is more simple and has more features than PHPUnit. Laravel has lots of support for this library.

Let’s see a short example of writing test-case in PHP Pest -

$value = 3;

expect($value)
    ->toBeInt()
    ->toBe(3)
    ->not->toBeString() // Not to be string...
    ->not->toBe(4); // Not to be 4...

**Run Pest unit tests - **

./vendor/bin/pest

Setup Instruction for Github Workflow

So, let’s make our Github repository has some built in setup for Laravel Pint and PHP Pest.

  1. Laravel Pint will fix all of the code style
  2. PHP Pest will do the Unit test works
  3. If founds any error, it will show before creating any Pull Request or Push

How to start

Create a file in your repository under .github/workflows/php-tests.yml

Where in the .github folder, we’ve to create another folder workflows, then create a file php-test.yml. This file name could be anything. Let’s write the below codes in php-test.yml.

name: Laravel Tests
on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

jobs:
  laravel-tests:
    runs-on: ubuntu-latest
    # Service container Mysql mysql
    services:
      # Label used to access the service container
      mysql:
        # Docker Hub image (also with version)
        image: mysql:5.7
        env:
          MYSQL_ROOT_PASSWORD: secret
          MYSQL_DATABASE:  testing
        ## map the "external" 33306 port with the "internal" 3306
        ports:
          - 33306:3306
        # Set health checks to wait until mysql database has started (it takes some seconds to start)
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3

    strategy:
      matrix:
        operating-system: [ubuntu-latest]
        php-versions: [ '8.1' ]
        dependency-stability: [ prefer-stable ]

    name: P${{ matrix.php-versions }} - L${{ matrix.laravel }} - ${{ matrix.dependency-stability }} - ${{ matrix.operating-system}}

    steps:
      - uses: actions/checkout@v2
      - name: Install PHP versions
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
      - name: Get Composer Cache Directory 2
        id: composer-cache
        run: |
          echo "::set-output name=dir::$(composer config cache-files-dir)"
      - uses: actions/cache@v2
        id: actions-cache
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-composer-
      - name: Cache PHP dependencies
        uses: actions/cache@v2
        id: vendor-cache
        with:
          path: vendor
          key: ${{ runner.OS }}-build-${{ hashFiles('**/composer.lock') }}
      - name: Copy .env
        run: php -r "file_exists('.env') || copy('.env.example', '.env');"
      - name: Install Dependencies
        run: composer install --no-interaction --prefer-dist --optimize-autoloader

      - name: Create storage folders
        run: mkdir -p storage/framework/{sessions,views,cache}
      - name: Directory Permissions
        run: chmod -R 777 storage bootstrap/cache

      - name: Show dir
        run: pwd
      - name: PHP Version
        run: php --version

      # Code quality
      - name: Execute tests (Unit and Feature tests) via PestPHP
        # Set environment
        env:
          DB_CONNECTION: mysql
          DB_DATABASE: testing
          DB_PORT: 33306
          DB_USER: root
          DB_PASSWORD: secret
        run: |
          php artisan key:generate
          vendor/bin/pest

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

This is a complete setup for Laravel Pint and PHP PEST.

Demonstrate the Workflow line by line

Let’s demonstrate the code line by line. Here’s a breakdown of the file and its structure:

Step 1:

name: Laravel Tests
on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

The workflow is triggered when a pull request is opened or pushed to the main branch.

Step 2:

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

The workflow has a single job named “laravel-tests” that runs on the latest version of Ubuntu.

Step 3:

services:
      mysql:
        image: mysql:5.7
        env:
          MYSQL_ROOT_PASSWORD: secret
          MYSQL_DATABASE: testing
        ports:
          - 33306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3

This section defines a MySQL service container. It pulls the mysql:5.7 Docker image, sets environment variables for the MySQL root password and database name, maps port 33306 on the host to port 3306 in the container, and sets health checks to ensure the MySQL database is running.

Step 4:

strategy:
      matrix:
        operating-system: [ubuntu-latest]
        php-versions: [ '8.1' ]
        dependency-stability: [ prefer-stable ]

The strategy section defines a matrix of variables to specify different combinations of operating systems, PHP versions, and dependency stability.

Step 5:

steps:
      - uses: actions/checkout@v2

This step checks out the repository code.

Step 6:

- name: Install PHP versions
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}

This step uses a community action shivammathur/setup-php to install the specified PHP version.

Step 7:

- name: Get Composer Cache Directory 2
        id: composer-cache
        run: |
          echo "::set-output name=dir::$(composer config cache-files-dir)"

This step retrieves the Composer cache directory.

Step 8:

- uses: actions/cache@v2
        id: actions-cache
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-composer-

This step caches the Composer dependencies based on the composer.lock file

Step 9:

- name: Cache PHP dependencies
        uses: actions/cache@v2
        id: vendor-cache
        with:
          path: vendor
          key: ${{ runner.OS }}-build-${{ hashFiles('**/composer.lock') }}

This step caches the PHP dependencies located in the vendor directory.

Step 10:

- name: Copy .env
        run: php -r "file_exists('.env') || copy('.env.example', '.env');"

This step copies the .env.example file to .env if the latter doesn’t exist.

Step 11:

- name: Install Dependencies
        run: composer install --no-interaction --prefer-dist --optimize-autoloader

This step installs the project dependencies using Composer.

Step 12:

- name: Create storage folders
        run: mkdir -p storage/framework/{sessions,views,cache}

This creates the frameworks necessary stuffs like creating folder in storage/framework/sessions, storage/framework/views, storage/framework/cache etc.

Step 13:

- name: Directory Permissions
        run: chmod -R 777 storage bootstrap/cache
```	
This step sets the directory permissions for the storage and `bootstrap/cache` directories.

#### Step 14:
```yml
- name: Show dir
        run: pwd
```	
This step prints the current working directory.

#### Step 15:
```yml
- name: PHP Version
        run: php --version

This step displays the PHP version in use.

Step 16: PEST Testing Part

- name: Execute tests (Unit and Feature tests) via PestPHP
        env:
          DB_CONNECTION: mysql
          DB_DATABASE: testing
          DB_PORT: 33306
          DB_USER: root
          DB_PASSWORD: secret
        run: |
          php artisan key:generate
          vendor/bin/pest

This step sets environment variables for the MySQL database connection and runs tests using PestPHP, a testing framework for PHP. It generates an application key using php artisan key:generate and then runs the tests using vendor/bin/pest.

Step 17:

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

This step runs the Pint tool, which is not explained in the given workflow snippet but might be a custom tool for additional testing or analysis.

That concludes the explanation of the provided GitHub Actions workflow file. It sets up the environment, installs dependencies, prepares the database, and executes tests for a Laravel application. It demonstrates how to use various actions and steps to automate the testing process in a CI/CD pipeline.

Demo Output at Github for next Pull Request or commit to main branch

If you still have any confusion about how to setup github workflow in laravel Pint, PHP PEST, please comment below.

Previous
PHP If-else-elseif and Switch-case
Next
PHP String Functions - All necessary String functions in PHP to manage strings better.