CI for Laravel

The Build Specification

Chipper CI prefers (but does't require) that you include a .chipperci.yml file in the root of your repository. That file will control the build environment the project uses.

  1. It can set the environment - the PHP and Node versions
  2. It can set the services - extra software used, such as databases, caches, and Docker
  3. It can set the pipeline - the commands that are run to build, test, and deploy your application
  4. It allows you to have branches with difference code environments
    • For example, if you have a branch to test out a newer version of PHP
  5. It lets you easily copy build definitions across multiple projects

If you don't have a .chipperci.yml file in your repository, you can define the build environment, services, and pipeline within the project settings at

Here's every option you can currently use in the .chipperci.yml file:

# Assume version 1
version: 1

# Choose between PHP and NodeJS majar versions
  php: 8.3                          # 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3
  node: 18                          # 6, 8, 10, 12, 14, 16, 18, 20

  # Choose only one of these databases
  - mysql: 5.7                      # 5.6, 5.7, 8
  - mariadb: 10.3
  - postgres: 13                    # 10, 11, 12, 13, 14, 15, 16
  - postgis/postgis: 13-3.0         # 10-3.0, 11-3.0, 12-3.0, 13-3.0, 14-3.0, 14-3.4, 15-3.3, 15-3.4, 16-3.4

  # Add redis, just like this, with the trailing colon
  # This always equates to the "redis:latest" Docker image
  - redis:

  # Paid accounts can add in Docker support,
  #  useful for running Vapor deployments.
  # Ensure you have the trailing colon.
  - docker:

  # Include the Chrome browser for use 
  #  in Dusk browser tests
  - dusk:

# Decide what events trigger a build
  # "push" is a regular, old commit.
  # This will build on push to any branch
  # Note that `.*` is a regex!
    branches: .*

  # This will build on PR open, re-open, and update
  # (Updates are when commits are pushed to a PR)
  # Here we say to only build when a PR is opened/reopened/updated 
  # and the branch being pushed to
  # is feature/.* or bug/.*
      - feature/.*
      - bug/.*

  # This will build on the (re)creation of any
  # tag that starts with `v`
    - v.*

# The pipeline commands can be just about anything.
# Note the use of the pipe character to allow you to
#  have multi-line commands
  - name: Setup
    cmd: |
      cp -v .env.example .env
      composer install --no-interaction --prefer-dist --optimize-autoloader
      php artisan key:generate

  - name: Compile Dev Assets
    cmd: |
      npm ci --no-audit
      npm run build

  - name: Run Tests
    cmd: phpunit

Best Practices

Use the pipeline to call scripts you commit to your repository. If I forget to write more here, yell at me at

Notes on Triggers (on:)

There's a few points to clarify on the events that trigger a build.

  1. For backwards-compatibility, omitting the on: section will build every build (rather than no builds at all)
  2. If you don't use a .chipperci.yml file (what are you even doing?!), then build decisions are configured in project settings under Build Restrictions
  3. Don't use * for wildcards, but instead the Regular Expression .* (more info below)

Branches (and tags) can be defined as a single value or a list of branches/tags:

# These are valid:
    branches: .*

    branches: feature/.*

  tags: .*

# And these are valid:
      - main
      - develop
      - feature/.*

      - feature/.*
      - bug/.*

    - .*

Combine push, pull_request, and tags any way you'd like.

Regular Expressions

Branches and tags are treated as regular expressions, and are run through preg_match_all() in format /^your-regex$/.

Use phpliveregex to test your expressions.

As a quick example, branch feature/.* would be tested with:

$regex = '/^feature\/.*$/'; // Regex generated from `feature/.*`
$actualBranchName = 'feature/my-new-feature';

if (preg_match_all($regex, $actualBranchname) > 0) {
    // Perform build

Useful Links