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

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, October 03, 2019

Follow me on Twitter as @mattiasgeniar

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 <m@ttias.be>"

# 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.



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.