RSS
 

Posts Tagged ‘Travis CI’

CakePHP 3.6 is coming

14 Mar

The first betas have landed already. Make your plugins and apps 3.6-ready now.
It is actually rather easy – better to be proactive now and have a small migration path than a big fallout and some surprises in a few weeks or months.

Prepare your Application

First read the 3.6 migration guide to get a grasp of the upcoming changes.
Deprecations ignored (easy ones, more later), there are not too many changes – especially no heavy ones. All in all this should be a very smooth upgrade from previous 3.x versions.

Now for the actual upgrade we have a few important issues to talk about:

Regressions

3.6 might introduce accidental regressions or issues that your app can not deal with. Those should be either fixed or outlined in the documentation and migration guide.
You can spend a few minutes here to find out early on how compatible your app is to a new minor version. Execute

composer require cakephp/cakephp:"dev-3.next as 3.5.14"

if you want to check the latest 3.6 version faked as 3.5 (due to the constraints). You can of course try 3.6 here as aliases, as well (as long as no constraints locks it down to ~3.5.x).

Note: For some plugins there might be already a 3.next branch (or even tags), as well.

Report or PR any issues you find and help to make the 3.6 release as smooth and BC as possible.

Migration path

Always keep up with minors in the framework. So at this point I expect everyone to be already running on CakePHP 3.5 for a while.

You can already have fully removed any deprecation of 3.4 or 3.5, which will further make the migration path smaller and easier to review.
Since 3.6 will trigger actual deprecation notices, this is really advised to do early on.
Once you actually switch to 3.6 you can actually silence the deprecations for the first run to verify functional compatibility by setting the error level in your app.php configs:

    'errorLevel' => E_ALL & ~E_USER_DEPRECATED,

Read the 3.6 migration guide for any functional upgrade that might be necessary, those should be applied first.

Once you established functional BC, you can start replacing all deprecations and afterwards again all tests should pass.

Tip: Try not use the above silence as a production default if possible. Instead try to remove those asap. But if not all plugins are updated yet, or do you don’t have the time to fix all of them right now, it is acceptable to just keep the deprecations silenced for the time being.

Migration tooling

Until now there was the CakePHP Upgrade tool which really helped a lot for the migration.
And it still does for a small subset, e.g. upgrade skeleton syncs the skeleton files from the latest cakephp/app repo into your app.
So it might not be completely dead just yet. If you are even below 3.5, definitely check it out.

But regex can only do so much. For more complex issues and especially all the deprecations there are now more modern and less error prone solutions available.
There is a very useful PHP tool that can help with deprecation replacement called rector.
It introspects the code and can very reliably identify and replace code pieces.

I tried it and using

composer require --dev bamarni/composer-bin-plugin
composer bin rector require --dev rector/rector
// lets dry-run for src/ directory
vendor/bin/rector process src/ --level cakephp36 --dry-run

it will show you what it would change as diff. Without --dry-run it will then actually run the upgrade. Make sure you committed all files or made a backup.

Tip: If it takes too long, just run it on each subfolder, e.g. src/Model, …

You can take a look at its CakePHP config. If there is anything missing, you can PR (pull request) your additions.

Plugins/Ecosystem

If you encounter issues with plugins or alike, open a ticket or better yet a pull request to get these things fixed ASAP.
This should ideally also be done pro-actively before you actually start upgrading your code-base, so that there is no time-bottleneck.

In case there really is something stuck, you can make a fork and use a tmp branch of master on your side for the upgrade.
Your composer.json would then point to dev-master of your repository fork and contain a repositories link so that composer knows to look there:

  "repositories": [
    {
      "type": "git",
      "url": "git@github.com:your-name/plugin-name.git"
    }
  ],

Once there is a tag with the fixed code in that original repository, you can remove and use the tagged release again.

Prepare your Plugins

This actually brings us the next point – if you are maintainer of a plugin yourself.

Having so many deprecations throughout 3.x it becomes more and more difficult to keep track of when methods were added and since what version you can use them, or not use others anymore.
With 3.6 this is more important than ever since this now adds deprecation warnings emitted for deprecated usage.
So make sure that if you start supporting 3.6 for your plugins, that your composer.json constraint towards cakephp/cakephp reads ^3.6. Users need to know if they can pull your version without the application breaking.

First of all: Make sure you support 7.2 in your Travis test matrix. There are quite some changes hidden in count() usage that can easily break your code or at least emit warnings.

Secondly, make sure you got also older PHP and CakePHP versions properly regression tested.
I started to actually add the following trick into my plugins:

matrix:
  include:
    ...
    - php: 5.6
      env: PREFER_LOWEST=1

Then exchange the first before_script line composer install with

before_script:
  - if [[ $PREFER_LOWEST != 1 ]]; then composer install --prefer-source --no-interaction ; fi
  - if [[ $PREFER_LOWEST == 1 ]]; then composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable ; fi

This will make sure, composer uses the lowest possible versions everywhere.
You will now spot any wrong usage of methods right in your tests in Travis – if those are covered by tests, that it.
That’s why I think it is more valuable that the tests execute the code than having good asserts. Sure, the latter is also needed in some cases. But the mere fact that the code executes fine means already a lot, from syntax issues (based on the PHP changes even in minor versions) and interface issues to other more runtime issues.

A full working version can be seen e.g. in TinyAuth .travis.yml.

Try to support 3.5 and 3.6

It is usually best to not always jump right to the latest minor as minimum requirement. This makes it harder for folks on the previous minor to get patches and bugfixes.
Thus, with the new deprecation warnings, you might have to do the following if you use any deprecated functionality because of this:

Add <ini name="error_reporting" value="16383"/> into your phpunit.xml.dist file (see here for example).

Similar things can be required for tooling like PHPStan. The linked IdeHelper plugins also shows a solution for this using a shim.php file that contains

error_reporting(E_ALL & ~E_USER_DEPRECATED);

Icing on the cake

You want to go even a step further and get alerted early on if your plugin or app breaks with new minors or patches?

Most of the time I encountered CI fails and BC issues months after when I applied a new change to a plugin and suddenly tests that should have passed didn’t pass anymore.
In this case you can see that the core way of building a query has been changed and now has less () brackets in 3.5+. Notified about this I can just make the tests conditional on the CakePHP version and all is good again.

It is rather easy to enable a cronjob in CI (e.g. Travis) that runs nightly or weekly and alerts you of any failures of new releases.
This is an example of how to enable for Open Source plugins in Travis:

 
1 Comment

Posted in CakePHP

 

Continuous integration with Travis and CakePHP

03 Apr

I must admit that I only recently started to take testing more serious.
In the past I just created tests if too much time was available.

But the larger projects get, the more just minor changes will most likely break other pieces in them, as well.
Most of the time you don’t even realize it until it is too late, and people report it broken after deployment.
To avoid this, it is wise to have a good test coverage of your project.
Also, it helps to have some software that tests your projects continuously and automatically. This is where Jenkins or Travis come into play.

In the following tutorial I want to focus on how use the free Travis CI to automatically test your github repositories automatically after every commit.
Jenkins you would have to manually set up on your server. Travis is already available with only some minor configuration (for free repos anyway).

Note: For Jenkins there is some documentation in the cookbook.

Travis Setup

You need to get a Travis account first. The easierst way would be to sign in with your github account as this automatically sets everything up. Then you just need to enable the github repositories you want to be tested.

Github Setup

On github you also need to enable the corresponding "Travis hook" for your repositories. It will also need the token you can get from the travis settings page.

Then we need to make our ".travis.yml" configuration file. The documentation is pretty good, but I will still outline the major pitfalls.
A basic version to test your "YourPluginRepository" plugin code for PHP5.3 and PHP5.4 would be sth. like this:

language: php
 
php:
  - 5.3
  - 5.4
before_script:
  - git clone --depth 1 git://github.com/cakephp/cakephp ../cakephp && cd ../cakephp
  - mv ../YourPluginRepository plugins/YourPlugin
  - sh -c "mysql -e 'CREATE DATABASE cakephp_test;'"
  - chmod -R 777 ../cakephp/app/tmp
  - echo "<?php
    class DATABASE_CONFIG {
    public \$test = array(
      'datasource' => 'Database/Mysql',
      'database' => 'cakephp_test',
      'host' => '0.0.0.0',
      'login' => 'travis',
      'persistent' => false,
    );
    }" > ../cakephp/app/Config/database.php
 
script:
  - ./lib/Cake/Console/cake test PluginName AllTests --stderr
  
notifications:
  email: false

Save this file to your repository root.
After the commit and push Travis should be notified via hook and your first test build should already be in the queue there.
You can find it at

https://travis-ci.org/[YOUR_GITHUB_USERNAME]/[YOUR_PROJECT_NAME]/

If you want to take a look at some more complex travis setups, take a look at my tools plugin or the cakephp repository. Both also use different CakePHP versions or database types.

Hooks

If you take a look at the Build-Lifecycle you can see that you have the possibility to install additional software/packages and configure your build to your liking prior to executing the tests.

Status image for your readme or website:

https://travis-ci.org/[YOUR_GITHUB_USERNAME]/[YOUR_PROJECT_NAME].png

Current status for my tools plugin

That was actually the main reason I started to try out Travis. The plugin got larger and more and more apps started to use it. I had to start thinking about how to make it more stable and reliable, especially after modifying parts of it. Regression tests really help here a lot!

Just as an example image:
Build Status

I noticed, however, that this image does not change very often. So if your build does not pass anymore, don’t rely on this image. Better use the notification hooks to get alerted 🙂

Sugar: Coverage via Coveralls

You can include coveralls.io coverage results and also get a detailed report for each class.
It is easiest to use the travis plugin then, as the coveralls setup is quite complicated otherwise.
See my Tools plugin on how to get it working.

You can show a neat little batch in your readme as well:

Note

It seems I wasn’t the only one writing something about this. Independently, Mark Story wrote an alternative article about the the same topic.