Bitbucket Pipelines + Laravel + PHPUnit
Tags: bitbucket, laravel, php, testing
Published: 2020-02-27 21:01:55

I recently decided to enable pipelines in a relatively simple repository to see if I could automate my PHPUnit tests. There's [lots of other articles](https://www.google.com/search?q=bitbucket+pipeline+laravel) online about getting this to work for laravel, but my application had a few unique requirements beyond the standard Laravel packages:

- LDAP for authentication with Active Directory
- GD Image manipulation library for use with [intervention\image](http://image.intervention.io/)
- I wanted to use SQLite in-memory database for my tests
- I did not want to commit a "pipeline" environment file, instead using the phpunit.xml file included with Laravel

# Setting up Bitbucket Pipelines

The first step is enabling pipelines for your repository. Bitbucket cloud comes with 50 minutes per month for free, so almost everyone can utilize this service without having to pay for an account.

Within your repo, you need to click on "Settings" then scroll down to *Pipelines* -> *Settings*

You'll be greeted with a slider to enable pipelines for your repository.

![Enable Pipelines for your repository](https://dev-to-uploads.s3.amazonaws.com/i/ceq5unnm4gs1ds7mthpc.png)

## Choosing a Base Image

Once you've done that, you will need to create a `bitbucket-pipelines.yml` file. Bitbucket helpfully provides a default PHP configuration, but we need to modify it to work for us. Bitbucket uses [Docker](https://docker.io) to load pre-configured images and you can customize them using this file. Dockerhub is a great repository to find the perfect base image for your pipeline!

![Dockerhub is a great repository to find the perfect base image for your pipeline](https://dev-to-uploads.s3.amazonaws.com/i/zusac1y7fiex6mxz33y3.png)

Bitbucket will automatically handle downloading your repo and linking it into the Docker image, but you will need to include any additional requirements for your specific project. Many tutorials suggest starting with a PHP base image. This is a great starting point and allows you to customize all your requirements from the bottom up.

For example, you could choose to start with one of the official php Docker images, in my case I wanted at least PHP 7.2.

```yml
# Start your bitbucket-pipelines.yml file with your base image
image: php:7.2-fpm
```
The major *downside* to this approach, is that you have to install and enable all your dependencies from scratch. This also means your pipeline will take longer to complete each time it runs. For the free bitbucket plan, this means you'd be using up more of your free minutes! For my use case, I wanted to pre-load as many dependencies if possible, so finding a Laravel-specific base image was imperative.

After reading several tutorials, I stumbled across [this git-lab specific tutorial for Laravel](https://lorisleiva.com/using-gitlabs-pipeline-with-laravel/) by Loris Leiva, which included their [customized laravel Docker image](https://hub.docker.com/r/lorisleiva/laravel-docker). This whittled down the additional packages that I would need to install to just a few, rather than all the Laravel-specific dependencies.

# Writing the `bitbucket-pipelines.yml` file

Loris's image is based on alpine linux, so we can easily install the few dependencies needed for our specific Laravel app within the `bitbucket-pipelines.yml` file as follows:

```yml
# Load the Laravel image for PHP 7.2
image: lorisleiva/laravel-docker:7.2

pipelines:
  default:
    - step:
        # Name your step, in my case I'm running tests
        name: Test
        
        # Cache composer dependencies to speed building between runs
        caches:
          - composer

        # This is the heavy lifting portion where we install our dependencies
        script:
          # I need to install sqlite for in-memory testing, ldap, and libpng for gd compatability
          - apk --no-cache add php7-ldap php7-sqlite3 sqlite sqlite-dev
              libpng libpng-dev libldap openldap-dev

          # Enable the PHP extensions for the previously installed dependencies
          - docker-php-ext-install ldap pdo pdo_sqlite gd

          # Install composer dependencies
          - composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts

          # Run our tests!
          - phpunit --coverage-text --colors=never --verbose        
```

If there's a dependency for Alpine linux you need, and you're not sure how to find it, the [Alpine Linux packages](https://pkgs.alpinelinux.org/packages) reference is a great way to find what you need! Of course, don't be surprised if you have to update your build file a few times to figure out everything exactly.

![Failure, then success!](https://dev-to-uploads.s3.amazonaws.com/i/oj9z6efzyne2l14o6uab.png)

# Viewing your results

Once you have committed your `bitbucket-pipelines.yml` file, you can view the results of your builds by clicking on *Pipelines* in the sidebar of the Bitbucket repo interface.

![View Pipeline results](https://dev-to-uploads.s3.amazonaws.com/i/etgej42cira09n29rng4.png)

If you click on one of the *success* or *failed* lines, you can deep dive into the console to figure out what went wrong.

![This build failed because I did not install the right package for ldap to install correctly.](https://dev-to-uploads.s3.amazonaws.com/i/6c6w0k3d7i8rmehgj3ce.png)

In my case, I had to add `libldap` to the `apk add` command for the php extension to be enabled successfully.

# Further reading
There's a lot more that you can do with Bitbucket Pipelines, and I would encourage you to read the Bitbucket wiki and documentation regarding all the different options.

* [Getting started with Bitbucket Pipelines](https://confluence.atlassian.com/bitbucket/get-started-with-bitbucket-pipelines-792298921.html)
* [Laravel and Pipelines](https://confluence.atlassian.com/bitbucket/laravel-with-bitbucket-pipelines-913473967.html)
* [Caching](https://confluence.atlassian.com/bitbucket/caching-dependencies-895552876.html)
* [Artifacts](https://confluence.atlassian.com/bitbucket/using-artifacts-in-steps-935389074.html)