A github CI workflow tailored to modern PHP applications (Laravel, Symfony, …)

Last year we wrote a blogpost about our setup we use for Oh Dear! with Gitlab, and how we use their pipelines for running our CI tests . Since then, we’ve moved back to Github since they introduced their free private repositories.

In this post I’ll describe how we re-configured our CI environment using Github Actions.

If you have a Laravel application or package, you should find copy/paste-able examples here to get it up and running for yourself. This will only require small adaptations for Symfony, Zend, …

It’s all PHP, after all.

A custom Docker container with PHP 7.3 and extensions#

I built a custom Docker container with PHP 7.3 and my necessary extensions. You’re free to use it yourself, too: mattiasgeniar/php73 .

I’m still pretty new to Docker, so if you spot any obvious errors, I’d love to improve the container. Here’s the Dockerfile as is. It’s up on Github too , so you’re free to fork/modify as you see fit to create your own containers.

FROM php:7.3-cli

LABEL maintainer="Mattias Geniar <[email protected]>"

## Install package dependencies
RUN apt update && apt install -y libmagickwand-dev git libzip-dev unzip

## Enable default PHP extensions
RUN docker-php-ext-install mysqli pdo_mysql pcntl bcmath zip soap intl gd exif

## Add imagick from pecl
RUN pecl install imagick && echo 'extension=imagick.so' >> /usr/local/etc/php/php.ini

## Install nodejs & yarn
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \
    && DEBIAN_FRONTEND=noninteractive apt-get install nodejs -yqq \
    && npm i -g npm \
    && curl -o- -L https://yarnpkg.com/install.sh | bash \
    && npm cache clean --force

## Install composer
ENV COMPOSER_HOME=/composer
ENV PATH=./vendor/bin:/composer/vendor/bin:/root/.yarn/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV COMPOSER_ALLOW_SUPERUSER=1
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

WORKDIR /var/www

In short: this takes the official base image of PHP 7.3 and adds some custom extensions, the node & yarn binaries, together with composer .

It’s a rather large container in total, because of the dependency of ImageMagick. By needing the source-files, it pulls in more than 100MB of dependencies. Oh well …

Using this container in your Github Action#

You can now use Github Actions to automatically run a set of commands, every time you push code. You can do so by creating a file called .github/workflows/ci.yml . In that file, you’ll determine what actions need to run in a container.

Here’s our current CI config for Oh Dear .

on: push
name: Run phpunit testsuite
jobs:
  phpunit:
    runs-on: ubuntu-latest
    container:
      image: mattiasgeniar/php73

    steps:
    - uses: actions/checkout@v1
      with:
        fetch-depth: 1

    - name: Install composer dependencies
      run: |
        composer install --prefer-dist --no-scripts -q -o;
    - name: Prepare Laravel Application
      run: |
        cp .env.example .env
        php artisan key:generate
    - name: Compile assets
      run: |
        yarn install --pure-lockfile
        yarn run production --progress false
    - name: Set custom php.ini settings
      run: echo 'short_open_tag=off' >> /usr/local/etc/php/php.ini
    - name: Run Testsuite
      run: vendor/bin/phpunit tests/

You can find a simplified example in my Docker example repo . The one above also takes care of the javascript & CSS compilation using yarn/webpack. We need this in our unit tests, but you might be able to remove those run lines.

Setting this up in your own repository#

Here’s what was needed to get this up-and-running.

  1. Sign up for the “beta” program of Github Actions . You’ll get immediate access, but it’s opt-in for now.
  2. Create a file called .github/workflows/ci.yml in your repository, take the content from the example above
  3. git push upstream to Github, the action should kick in after a few seconds

You can find an example Action here: mattiasgeniar/docker-examples/actions .

After that, you should see the Actions tab pick up your jobs.