WPBrowser and Travis CI 01

Setting up Travis for WPBrowser.

What’s Continuous Integration?

Skipping over Wikipedia definition of Continuous Integration I will go straight into what it means to me.
I’ve had mixed feelings about Continuous Integration (CI) in the past: on one side I knew how good it would have been to have it in place while on the other the additional work required directed me away.
Aside from all the general benefits CI offers two things convinced me:

  • making sure my code can safely run on other people machines and my very own machine artefacts and gimmicks are not what makes a test pass or fail
  • running the tests every time me or someone else updates the code without requiring the ability to run those tests locally

Plus the set up process required to test the wp-browser library is not dissimilar from what could be required to test a WordPress plugin or theme relying on it for its tests and all of the experience I will recycle in future projects.

Why Travis?

The Travis CI service is free for open-source projects, it’s widely used, documented and the amount of know-how available online is immense. This wealth of information coupled with some basic understanding of what’s going on in a “build” makes working with it easy.
The wp-browser library is open source and so I could experiment and tinker to my heart content with the Travis configuration file to make it work as intended.

Quick and dirty guide to the Travis machine instance

There are many processes going on under the Travis hood but understanding and knowing them all is not my objective.
In my brief experience what I’ve come to grasp is that, when used to “build” a PHP project, Travis will provide a Ubuntu 12.04.5 installation with some default tools and packages installed.
Those tools include Composer, phpenv to switch between the available PHP language versions, PhpUnit and so on.
When tied to a GitHub repository a “build” will be attempted any time a code push or a pull request is made to it.
In as short a list of steps as possible this is what Travis will do:

  • spin up an Ubuntu-based virtual machine and set it up with some defaults
  • git clone the just pushed version or pull request branch in a work folder (accessible in the TRAVIS_BUILD_DIR environment variable)
  • run a shell command compiled from the .travis.yml configuration file
  • run some testing script at the end

If not specified in PHP projects Travis will launch the phpunit command by default from the root of the cloned repository folder.
What should happen after the Ubuntu installation is ready to run is specified in a configuration file that takes the form of a .travis.yml file in the repository root folder.

Setting up WPBrowser for CI

Shown here after an endless list of experiments is WPBrowser Travis configuration file.
Since WPBrowser is a collection of modules for Codeception I’m using Codeception itself to test it and wanted to be able to run all the tests in the suite; this requires some components to be put in place:

  • a database to power the WordPress installation
  • a second database dedicated to the tests for the WPLoader module
  • a fully working Apache web server able to handle requests

Below the .travis.yml file from the repository with inline comments.

# this first instruction tells Travis I will need to use the `sudo` command
# this means the [container based build](!g travis container infrastructure) is off-limits for the time being.
sudo: required

# the project is a PHP based one
# Travis will instance a Ubuntu machine ready to run and packed with most commonly used PH packages
language: php

# avoid sending me email notifications about the builds
notifications:
  email: false

# test the project using PHP versions 5.6 and 7.0
php:
  - '5.6'
  - '7.0'

# the build will need to use MYSQL databases
# Travis will take care of setting mysql up and making the `mysql` command available for the build scrip to use
services:
  - mysql

# cache some commonly used files and avoid re-downloading them
cache:
  directories:
    - vendor
    - $HOME/.composer/cache

# set up some shell variables;
# this is the same as writing `export wpDbName=test && export wpLoaderDbName=wploader` and so on
env:
  - wpDbName=test wpLoaderDbName=wploader wpDbPrefix=wp_ wpUrl=wordpress.dev wpAdminUsername=admin wpAdminPassword=admin wpSubdomain1=test1 wpSubdomain1Title="Test Subdomain 1" wpSubdomain2=test2 wpSubdomain2Title="Test Subdomain 2"

# create the two databases the test script will need using the shell variables above;
# shell parameter expansion will yield a first line like `mysql -e "create database IF NOT EXISTS test;" -uroot`
before_install:
  - mysql -e "create database IF NOT EXISTS $wpDbName;" -uroot
  - mysql -e "create database IF NOT EXISTS $wpLoaderDbName;" -uroot

# at this point the wp-browser repository has been cloned in the work folder
# now install its dependencies using Composer
install:
  - composer update --prefer-dist

# the "script" is the place where the "build" (testing) happens
# before that I need more stuff to be set up
before_script:
  # set up the folders I will use to install WordPress and wp-cli
  - mkdir -p $HOME/tools /tmp/wordpress

  # download wp-cli in the `/tmp/tools` folder
  - wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -P /tmp/tools/
  # alias wp-cli to wp and make it executable
  - chmod +x /tmp/tools/wp-cli.phar && mv /tmp/tools/wp-cli.phar /tmp/tools/wp
  # add the `/tmp/tools` and the `vendor/bin` folders to the path
  # the `vendor/bin` is a relative path that and the one where the `codecept` executable is stored
  # in the build folder
  - export PATH=$PATH:/tmp/tools:vendor/bin

  # download wordpress
  - cd /tmp/wordpress && wp core download

  # create a WordPress configuration file
  - wp core config --dbname=$wpDbName --dbuser=root --dbpass='' --dbhost=localhost --dbprefix=$wpDbPrefix --skip-salts
  # install a WordPress multisite subdomain-based instance using wp-cli
  - wp core multisite-install --url=$wpUrl --base=/ --title=Test --admin_user=$wpAdminUsername --admin_password=$wpAdminPassword --admin_email=admin@$wpUrl --subdomains --skip-email
  # add two subdomain sites to the installation
  - wp site create --slug=$wpSubdomain1 --title="$wpSubdomain1Title"
  - wp site create --slug=$wpSubdomain2 --title="$wpSubdomain2Title"
  # empty the installation of any default post or page
  - wp site empty --yes 
  # keep just twentysixteen theme
  - wp theme activate twentysixteen && wp theme delete $(wp theme list --field=name --status=inactive) 
  # delete any default plugin
  - wp plugin delete $(wp plugin list --field=name)
  - wp core version

  # export a dump of the just installed clean database to the _data folder
  # this dump will be used by acceptance and functional tests as a starting point
  - wp db export $TRAVIS_BUILD_DIR/tests/_data/dump.sql

  # update and install apache2 packages
  - sudo apt-get update
  - sudo apt-get install -y --force-yes apache2 libapache2-mod-fastcgi make
  - sudo apt-get install -y --force-yes php5-dev php-pear php5-mysql php5-curl php5-gd php5-json php5-sqlite php5-pgsql
  - sudo a2enmod headers

  # Enable php-fpm in Apache
  # credit: https://www.marcus-povey.co.uk/2016/02/16/travisci-with-php-7-on-apache-php-fpm/
  - if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.0" ]]; then sudo cp $TRAVIS_BUILD_DIR/build/www.conf ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/; fi
  - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
  - sudo a2enmod rewrite actions fastcgi alias
  - sudo echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
  - ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm

  # Configure apache virtual hosts
  # the repository contains a `/build` dir that contains a ready to use Apache virtual host configuration
  # replace the default virtual host configuration
  - sudo cp -f $TRAVIS_BUILD_DIR/build/travis-ci-apache /etc/apache2/sites-available/default
  # replace the folder and url placeholders with the real ones
  - sudo sed -e "s?%WP_DIR%?/tmp/wordpress?g" --in-place /etc/apache2/sites-available/default
  - sudo sed -e "s?%WP_URL%?$wpUrl?g" --in-place /etc/apache2/sites-available/default
  # the `wordpress.dev` address should be resolved to `localhost`
  - echo '127.0.0.1 wordpress.dev' | sudo tee --append /etc/hosts > /dev/null

  # Restart services
  - sudo service apache2 restart

  # Get back to Travis build dir
  - cd $TRAVIS_BUILD_DIR

script:
  # finally run Codeception...
  - codecept run

Next

I will delve into the project suites configuration and then configure the I’d like this plugin to run on Travis.