Updating CI pipelines to allow PHP8
Tags: gitlab, ci, php
Published: 2021-01-18 08:56:25

---
title: Updating CI pipelines to allow PHP8
published: true
description: How you can update your pipelines to support PHP8
tags: gitlab, ci, php
canonical_url: https://www.garybell.co.uk/upgrading-ci-cd-pipelines-to-php-8/
cover_image: https://static.garybell.co.uk/images/upgrade-pipelines-to-php8/cover-image.jpeg
---
With the release of PHP8, there's going to be a scramble from people to get their PHP applications up-to-date. Yes, PHP 7.4 is supported until [28th November 2021](https://www.php.net/supported-versions.php), but there could still be a lot of work to do. Especially if your application uses external libraries. This puts you at the mercy of the maintainers. 

I maintain one of those packages on which you may rely, an [entropy based password validator](https://packagist.org/packages/garybell/password-validator). Knowing that PHP 8 was going to be released made me want to get ahead of the curve on migrating to be able to use it. To do that, and have some level of proof that it would be ok, I needed to update the CI pipeline to also run the unit tests under PHP 8. This will be the starting point for a lot of teams with good code coverage, I imagine. Here's how I found the experience (with the issues I ran into). First, it was a case or copying and renaming the existing PHP Unit test suite, which resulted in:

```yml
PHP 8.0 Tests:
  image: ubuntu:focal
  stage: unitTest
  # Install composer dependencies
  before_script:
    - DEBIAN_FRONTEND=noninteractive apt-get update
    - DEBIAN_FRONTEND=noninteractive apt-get -y install curl php php-xdebug php-curl php-dom php-json php-mbstring php-pdo zip unzip php-zip
    - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
  script:
    - composer install
    - ./vendor/bin/phpunit --coverage-text --colors=never --configuration phpunit.xml --log-junit phpunit_results.xml
```

That's not much use, as it still runs things on PHP 7.4 (the default with Ubuntu 20.04). It needs PHP to be updated, so I added the PPA to allow this. This needed the following line added to the start of the `before_script` section:

```yml
- DEBIAN_FRONTEND=noninteractive apt-get update
- DEBIAN_FRONTEND=noninteractive apt install -y software-properties-common
- DEBIAN_FRONTEND=noninteractive add-apt-repository ppa:ondrej/php
```

The I changed the php elements to be php8.0, again in the before script:

```yml
- DEBIAN_FRONTEND=noninteractive apt-get -y install curl php8.0 php8.0-xdebug php8.0-curl php8.0-dom php8.0-json php8.0-mbstring php8.0-pdo zip unzip php8.0-zip
```

Done - queue excitement for the run...FAIL. The pipeline console showed the following error:

``` bash
E: Package 'php8.0-json' has no installation candidate
```

What the...?
It turns out that JSON is [included within PHP 8 by default](https://php.watch/versions/8.0#ext-json), which saves issues on forgetting to install it. With it not being needed, I removed the php8.0-json part, so the unit test full job was:

```yaml
PHP 8.0 Tests:
  image: ubuntu:focal
  stage: unitTest
  before_script:
    - DEBIAN_FRONTEND=noninteractive apt-get update
    - DEBIAN_FRONTEND=noninteractive apt install -y software-properties-common
    - DEBIAN_FRONTEND=noninteractive add-apt-repository ppa:ondrej/php
    - DEBIAN_FRONTEND=noninteractive apt-get update
    - DEBIAN_FRONTEND=noninteractive apt-get -y install curl php8.0 php8.0-xdebug php8.0-curl php8.0-dom php8.0-mbstring php8.0-pdo zip unzip php8.0-zip
    - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
  script:
    - composer install
    - ./vendor/bin/phpunit --coverage-text --colors=never --configuration phpunit.xml --log-junit phpunit_results.xml
```

All done, all good to run...Fail.

```bash
Your requirements could not be resolved to an installable set of packages.
  Problem 1
    - Root composer.json requires php ^7.4 but your php version (8.0.0RC3) does not satisfy that requirement.
```

Yes, I forgot to update the required PHP version in `composer.json`. It was then changed from

```json
"require": {
  "php": "^7.4"
}
```

to

```json
"require": {
  "php": "^7.4|^8.0"
}
```

Re-run the pipeline. Success!

## Conclusion
For a small component like my password validator, this was a trivial exercise. It's a handful of files, and doesn't have much in the way of complexity. The issues I had were due to me rushing for a success (forgetting to update the PHP requirement) or simply not knowing that JSON was included by default now. The actual updating of the pipeline was pretty straight forward. It's an exercise certianly worth undertaking on a development branch (even if it goes nowhere for a while) to see if there's any impending compatibility issues for your application. If there are, you can be aware of them early, and start working to mitigte or resolve them to keep on a supported version of PHP.