Testing PHP code against many PHP versions
As PHP grows, more versions show up with better stability & performance, obviously we test our code against production environment, but what if we could test it against new versions with little effort and ensure soft migration in future ?
Here we will use Docker & Gitlab to ensure that our PHP code runs on these versions: 5.5, 5.6 and 7.0.
We’ll use our own Docker images with configured additional extensions not provided by PHP official images, also with installed GIT and newest composer out of the box.
What is Gitlab
Gitlab is git projects hosting platform staying that it will be free forever. How does it differ from Github or Bitbucket ?
- no limits on public / private repos and users, more info here
- no PRs (pull requests), but MR (merge requests) - more details here
- Gitlab runners - tool to run builds on external machines, using host itself or docker - in this series we will speak only about docker runners. Runner can be either public (provided by Gitlab) or private - setup on external machine. In this example we will use Gitlab’s public runners.
Preparations
- Create an account on https://gitlab.com/
- Fork example repository https://gitlab.com/melkorm/php-testing
If you want to see how it works / looks like then make some change in source and build will be automatically ran against your changes.
.gitlab-ci.yml config
First we need a config for our Gitlab runner. It is a configuration file written in YAML format, for full specification see docs
Let’s go trough the config for details:
Variables, section where we specify env variables which will be available for all running scripts
COMPOSER_CACHE_DIR
- we want to cache composer libraries across builds, we don’t want to pull all the dependencies for each build,COMPOSER_DISABLE_XDEBUG_WARN
- disabling composer’s xdebug warn so it doesn’t mess with our tests output,COMPOSER_VENDOR_DIR
- here we setup custom directory for composer’s vendor dir,CI_PROJECT_ID
andCI_BUILD_REF_NAME
are provided by Gitlab, you can read more about available variables hereCI_PROJECT_ID
- this is ID of our project,CI_BUILD_REF_NAME
- The branch or tag name for which project is built.
Stages, section when we specify groups of tasks to be executed, you can think about it as a pipeline, for example: test, build, deploy.
We only specify test as this is our only stage in this scenario.
Jobs
- test55 - job name
- image - docker image pulled from Docker Hub
- stage - to which stage task belongs to
- script - list of commands to execute
mkdir -p /storage/vendor/${CI_PROJECT_ID}/${CI_BUILD_REF_NAME}
-
Here we prepare storage for composer’s dependencies
ln -s /storage/vendor/${CI_PROJECT_ID}/${CI_BUILD_REF_NAME} vendor
-
link the storage to vendor in our app directory
make
- run our make script to install dependencies and run tests.
PHP Testing
Makefile - quickly adds console for repetitive tasks done with our application from command line, like:
- installing dependencies
- testing
- building
- releasing
- and many more.
Example Makefile:
structure is:
if you run make without params it will run first command.
Now we can call $ make
and test
will execute after composer
, example output:
You can see example build & output here
Wrap up
As you can see it is easy to test your code against many PHP versions. All you need is Gitlab and Docker image supporting your stack. Of course you don’t need to use Gitlab, you can configure your Jenkins or any other build tool to test your code on different Docker images. We like Gitlab as this offers many features out of the box with little effort. So if you start a new project, or want to automate testing with current one - try Gitlab as it might be the right tool for you.