Skip to content

Instantly share code, notes, and snippets.

@mparramont
Created February 3, 2021 06:15
Show Gist options
  • Save mparramont/c4baa71789d380d42b6d67d17687a008 to your computer and use it in GitHub Desktop.
Save mparramont/c4baa71789d380d42b6d67d17687a008 to your computer and use it in GitHub Desktop.
How to Dual Boot a Composer app

How to Dual Boot a Composer app

In this article we will learn how to dual boot any composer app (like a Yii2 app) in a local environment and continuous integration (CI) service. This can be used to upgrade the version of Composer, PHP, or even maybe Yii, along the way with normal development, even if it's a process that spans many weeks or months.

This is inspired by Jordan Raine's talk about Clio's process to upgrade Rails over the years (You can watch it over here: Ten Years of Yii Upgrades), this post by Ernesto Tagwerker, and my own experiences about doing this on the Kantox B2B Forex Fintech platform.

Create a composer-next.json File

First, we need to initialize the composer-next.json file like this:

$ cd path/to/project
$ cp composer.json composer-next.json

Bump Yii (composer-next.json)

Now, in composer-next.json, we just need to change Yii to the new version:

  • In composer.json:
        "yiisoft/yii2": "2.0.22",
  • In composer-next.json:
        "yiisoft/yii2": "2.0.23",

Now I can install my current dependencies with composer install and my future dependencies with COMPOSER=composer-next.json composer install using the COMPOSER env var.

Run Tests

After running COMPOSER=composer-next.json composer update, I have a brand new composer-next.lock file. That means that my dependencies are ready to run my test suite. So I can run them like this:

$ COMPOSER=composer-next.json composer run-script test

There are many advantages to using dual booting in your composer application. In no particular order:

  • You can run your test suite with two different versions of Yii. Running composer run-script test still works thanks to having another composer.json file.
  • You can run your application in development with two different versions of Yii with composer run-script [command-to-run-server].
  • You can even run your application in staging using the next version of Yii. Simply make sure that you set this environment variable: COMPOSER and use composer run-script.
  • You can quickly debug issues between your current version of Yii and the next one.

Fix the errors on the new version

Now, the last step is to fix the issues that the update might have uncovered. The way to do it to build up compatibilty with the new version of Yii is:

  1. Identify an error (through a test or the UI)

  2. Fix the source of the incompatibility on the new version of Yii

  3. Fix the error

  4. If the fix solves the error in both the old and the new version of Yii, you're done!

  5. Otherwise, split the fix in two parts as follows:

    if(getenv('COMPOSER') === 'composer-next.json'){
        // fix for the new version
    } else {
        // existing code that works in the old version
    }

    Once compatibility with the new version is fully accomplished, the cleanup is just searching in all the project for if(getenv('COMPOSER') === 'composer-next.json') and deleting all the old code ✨

Setup Continuous Integration

The next step would be to setup 2 different builds in CI:

  • One that users composer.json
  • One that users composer-next.json: this one will only run the tests that run the code that has been fixed. As more code is fixed, more tests are run in this build, until all the tests run.

This is done so that no developer breaks the new version of the code, even if they only develop using the old version.

The setup depends on the specific CI service, but it shouldn't be too hard: it's basically C&Ping the configuration to a new build and replacing composer run-script x with COMPOSER=composer-next.json composer run-script x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment