This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 15k traffic Daily!!!

A GitHub Workflow to Check the Compatibility of Your PHP Package with a Range of Dependency Versions


A standard side of a PHP developer’s job is to cope with Composer dependencies. We use the work of others as Lego bricks to construct our personal tasks, benefiting from the attractive factor that’s the open-source motion.

As typical end-users of those group efforts, we keep an inventory of dependencies whose variations are pinned by way of the composer.lock file. We do not want to consider supporting different variations of those dependencies, simply as we do not want to consider accommodating a spread of PHP variations – we work throughout the constraints of our software’s goal environments, that are identified and anticipated to be secure over time.

Issues are completely different for open-source software program maintainers. They’re largely agnostic to the constraints of their customers’ environments, so the most effective they will do is ensure their libraries are suitable with as many PHP and dependency variations as potential.

That is the place compatibility testing is essential. Open-source maintainers want to make sure that any change made to the code will work with all of the variations listed in composer.json. Doing so manually is unpractical, in order that they resort to check protection and automatic scripts.

This publish explores one such method of automating compatibility testing, utilizing a mixture of take a look at protection and a GitHub Actions workflow.



On this publish

  • Full workflow
  • Breakdown
  • Closing ideas
  • Assets



Full workflow

Right here is the ultimate model of the workflow. In case you’re simply right here for the code, be at liberty to repeat and reuse the beneath as a lot as you please. In any other case hold studying for a progressive breakdown of the file, supported by an instance venture.

You may also try this text’s repository for reference.



Breakdown

The next is a full breakdown of the workflow. We are going to construct it up incrementally, utilizing an instance venture that we’ll replace as we increase the vary of supported dependency variations.



Preliminary setup

This step is elective, however for those who’re a “study by way of observe” form of particular person, chances are you’ll need to construct this instance venture in your machine and replace it as we go. In case you do not, chances are you’ll need to learn this part anyway, because it accommodates some related data.

In case you do, go forward and create a brand new empty GitHub repository now. Name it php-compatibility-demo (or anything for those who really feel impressed) and ensure it is public so you may benefit from the free GitHub Actions allowance (until you’ve got obtained a paid account, wherein case be at liberty to maintain the repository personal).

The beneath assumes that your growth setup helps PHP 8.0+ and that you’ve entry to a terminal with Composer and Git.

Clone the repository in your growth machine and initialise a brand new Composer venture:

$ git clone php-compatibility-demo
$ cd php-compatibility-demo
$ composer init
Enter fullscreen mode

Exit fullscreen mode

The final command will ask you a sequence of questions and generate a composer.json file on the finish. Most questions do not matter within the context of this text, however ensure to pick library for the kind of venture, stable for the minimal stability, and to depart the default values for the PSR-4 autoload bit.

As soon as that is carried out, add /vendor/ and composer.lock to the .gitignore file:

/vendor/
composer.lock
Enter fullscreen mode

Exit fullscreen mode

That is the primary main distinction from common firm tasks, the place builders will often commit the composer.lock file so the appliance is constant throughout environments. Right here we embrace inconsistency as a substitute, and let Composer work out what dependency variations to make use of primarily based on the constraints of consumer environments.

On this context, the GitHub workflow is one more consumer atmosphere, and we do not need it to choose up a composer.lock file that may drive the set up of particular variations whereas our aim is to check a complete vary of them.



Library and take a look at protection

With that in place, let’s speak about our take a look at venture for a minute. We’re going to construct a small library on prime of Money, a well-liked PHP package deal facilitating the manipulation of financial values and currencies.

Our library will include a single helper class – CurrencyHelper.php – that may simplify working with currencies. It is going to expose two strategies – one to be sure that a bunch of Cash objects have the identical forex, and one other one returning the numeric ISO 4217 code of a Cash object.

You’ll quickly realise that this library is fairly pointless, nevertheless it makes up an excellent instance to assist this text, so I belief you’ll flip a blind eye.

This is the file construction it is best to get on the finish of this part (keep in mind that you could additionally check with this text’s repository at any time for comparability):

php-compatibility-demo/
├── src/
│   └── CurrencyHelper.php
├── checks/
│   └── CurrencyHelperTest.php
├── vendor/
├── .gitignore
├── composer.json
└── composer.lock
Enter fullscreen mode

Exit fullscreen mode

Let’s instal the Cash library:

$ composer require moneyphp/cash:^4.0
Enter fullscreen mode

Exit fullscreen mode

Word that we deliberately import v4 right here, despite the fact that it might not be the newest model whenever you’re studying this.

Let’s additionally instal PHPUnit as a growth dependency:

$ composer require --dev phpunit/phpunit
Enter fullscreen mode

Exit fullscreen mode

In case you’re additionally constructing this instance library in your machine, remember to replace the seller identify within the namespace on the prime.

The isSame technique takes any variety of Cash objects and returns a boolean indicating whether or not they share the identical forex. The best way it really works is that it removes the primary component from the array (utilizing array_shift) after which compares this component’s forex with that of the opposite ones, utilizing the isSameCurrency technique from the Cash class.

The second technique – numericCode – takes a Cash object as its solely parameter and returns its forex’s numeric ISO code, utilizing the numericCodeFor technique from the ISOCurrencies helper class (which is a part of the Cash library).

And right here is the content material for checks/CurrencyHelperTest.php, the category testing the behaviour of our “library”:

These checks will enable us to verify whether or not our library works with numerous PHP and dependency variations afterward. Once more, remember to replace the seller’s identify on the prime.

Let’s test that the checks are passing:

$ ./vendor/bin/phpunit checks
Enter fullscreen mode

Exit fullscreen mode

In the event that they do, we will transfer on to the workflow.



Primary workflow

Let’s begin with a easy GitHub Actions workflow whose solely job might be to run the take a look at suite. Principally what we simply did, however in an automatic method.

We have to create a brand new .github folder on the root of the venture, itself containing a workflows folder wherein we add a file named ci.yml. These directories are GitHub conventions – that is the place the platform expects to seek out our workflows, ci.yml being certainly one of them.

That is the up to date file construction:

php-compatibility-demo/
├── .github/
│   └── workflows/
│       └── ci.yml
├── src/
│   └── CurrencyHelper.php
├── checks/
│   └── CurrencyHelperTest.php
├── vendor/
├── .gitignore
├── composer.json
└── composer.lock
Enter fullscreen mode

Exit fullscreen mode

And here is the content material of ci.yml:

Let’s break it down shortly – we first give the workflow a reputation (“CI” stands for “Steady Integration”), after which outline the situations on which it ought to set off (right here, any modifications pushed to the foremost department, or any pull request opened in direction of it).

We then listing the roles to be executed. There’s just one in our case – working the take a look at suite. We name this job “PHPUnit” and specify that it’ll run on the newest Ubuntu model.

Then we outline the steps making up the job – testing the code, organising PHP, putting in the Composer dependencies and, lastly, working the take a look at suite. The primary three steps are utilizing standard GitHub Actions (see the makes use of keys):

We do not want a GitHub Motion for the final step as it’s a easy command.

Save the file, commit and push. After just a few seconds, it is best to see a display much like this below the Actions tab of your GitHub repository:

Successful basic workflow

You’ll be able to click on on the workflow run to see the logs.

And that is it for the primary model of our workflow. It is a first rate first step already, because the workflow will set off any time some new code is pushed to/a pull request is opened in direction of foremost, robotically reporting any breaking modifications.

However to date we’re solely testing a single set of dependency variations – no matter Composer decides is finest when the workflow reaches the Set up composer dependencies step.

Let’s go one step additional.



Dependency ranges

Say we need to assist each PHP 7.4+ and PHP 8.0+. As a substitute of letting Composer do its finest primarily based on what software program model is obtainable on the consumer atmosphere, we’re going to tip it off by explicitly itemizing the PHP variations our library is suitable with.

Open composer.json and replace the require part as follows:

"require": ^8.0",
    "moneyphp/cash": "^4.0"
,
Enter fullscreen mode

Exit fullscreen mode

We’re now supporting each PHP 7.4+ and PHP 8.0+. However wait, that is not going to work – the Cash library requires PHP 8.0+ for its v4, so if we need to add assist for PHP 7.4+, we additionally want to incorporate an older model of Cash.

Let’s replace composer.json once more:

"require": ^8.0",
    "moneyphp/cash": "^3.0,
Enter fullscreen mode

Exit fullscreen mode

We’re now additionally supporting each Cash v3 and v4. As Cash v3 needs PHP 5.6+, we must be suitable with PHP 7.4 as effectively.

As we have up to date composer.json, let’s ensure our native composer.lock is updated with the next command:

$ composer replace --lock
Enter fullscreen mode

Exit fullscreen mode

We now must replace our workflow to make sure the take a look at suite will run for each variations of PHP:

The principle change right here is the addition of the technique part. A strategy permits us to outline a matrix for our jobs – a option to run the steps utilizing completely different configurations.

However let’s have a fast have a look at fail-fast first – by setting this property to false, we ensure the steps will run for all configurations and will not be interrupted even when certainly one of them fails. We would like complete suggestions for all PHP variations right here, so we will repair any situation that comes up.

Then comes the matrix part, composed of a single php-version key, which is an array of values. What that does is that for every successive run of the steps, the php-version key might be assigned a brand new worth from the array, till we attain the tip of the array.

Word that we have additionally listed PHP 8.1 in there, as there are some notable differences with PHP 8.0.

We are able to see the php-version key being referenced additional down, within the Setup PHP step. We added a brand new php-version key below the with part – that is the place we assign the worth of the present run (${{ matrix.php-version }}), utilizing a configuration option from the Setup PHP GitHub Motion.

Let’s do that out – commit and push the modifications and head over to the repository’s Actions tab once more. Give it just a few seconds – it is best to see that this time, the run has failed:

Failed intermediate workflow

Click on on the workflow run – there was a difficulty with the PHP 7.4 job:

Failed intermediate workflow – PHP 7.4

Click on on it and increase the Run PHPUnit logs:

Failed intermediate workflow – PHP 7.4 logs

Attention-grabbing. Certainly one of our take a look at assertions is failing on line 23:

$this->assertFalse($checker->isSame($amount1, $amount2, $amount4));
Enter fullscreen mode

Exit fullscreen mode

Trying on the Cash library’s changelog, the explanation seems to be as a result of the Cash@isSameCurrency technique solely added assist for a number of arguments from v4. We all know that this model can solely be used with PHP 8.0+, which explains why Composer instals Cash v3 when it detects PHP 7.4.

To repair the problem, we have to change the best way the isSame technique works in CurrencyHelper.php:

public operate isSame(Cash ...$quantities): bool
{
    if (depend($quantities) === 1) {
        return true;
    }

    $first = array_shift($quantities);

    foreach ($quantities as $quantity) {
        if (! $first->isSameCurrency($quantity)) {
            return false;
        }
    }

    return true;
}
Enter fullscreen mode

Exit fullscreen mode

As a substitute of passing all of the remaining components of the $quantities array to isSameCurrency directly, we now loop by way of them and evaluate their forex to that of the primary component, one after the other.

Let’s ensure we’ve not damaged our library earlier than pushing our modifications:

$ ./vendor/bin/phpunit checks
Enter fullscreen mode

Exit fullscreen mode

Commit and push and test the Actions tab once more:

Successful intermediate workflow

The error is gone!

So it seems our library is now suitable with each PHP 7.4+ and PHP 8.0+.

Or is it?



Testing decrease dependency variations

Let’s check out the logs once more. Click on on the newest profitable workflow run and enter the PHPUnit (7.4) job from the left-hand facet. Develop the Set up composer dependencies logs and search for the road referencing the Cash library.

It appears to be like like Composer is choosing the newest minor model by default (v3.3.1 on the time of writing):

Composer picks the latest version

The difficulty is we wish our library to be suitable with earlier variations as effectively – how can we drive Composer to instal the bottom model – v3.0.0?

We have to replace ci.yml once more:

Word that we have added a brand new key to our matrix – dependency-versions. It’s also an array, with two values – lowest and highest.

This time we’re making the most of a configuration option from the Composer Set up GitHub Motion, permitting us to drive Composer to both use the bottom or highest variations of the dependencies.

We are able to see the dependency-versions key getting used additional down, within the Set up composer dependencies step. We added a brand new with part to it, with a single dependency-versions key to which we assign the present worth from the matrix (${{ matrix.dependency-versions }}).

When that worth is lowest, the Composer Set up GitHub Motion will run this command behind the scenes:

$ composer replace --prefer-lowest --prefer-stable
Enter fullscreen mode

Exit fullscreen mode

What is the consequence of including a brand new array of values to our matrix? The reply is that it’ll set off as many step runs as there are combos from each arrays.

Let’s have a look at it in motion – commit and push the brand new workflow, and test the Actions tab once more:

Failed advanced workflow

Appears like there was a difficulty with the brand new run. If we click on on it, we’ll see that the take a look at suite was run for every PHP and dependency model, in addition to for every worth from the dependency-versions array.

However all of the runs utilizing the lowest worth have failed:

Failed advanced workflow – lowest dependencies

Let’s discover out why. Click on on the PHPUnit (7.4, lowest) job and increase the Run PHPUnit logs:

Failed advanced workflow – lowest dependencies logs

The error is the next:

Name to undefined technique MoneyCurrenciesISOCurrencies::numericCodeFor()
Enter fullscreen mode

Exit fullscreen mode

If we check out the Cash library’s changelog once more, we will see that this technique was added with v3.0.5.

We now have two methods to repair this – both we replace the CurrencyHelper@numericCode technique and manually implement the change, or we bump the minimal supported model to three.0.5.

Since this model is a small patch, it feels affordable to do the latter.

Let’s replace composer.json one final time:

"require": ^4.0"
,
Enter fullscreen mode

Exit fullscreen mode

Commit and push, and anticipate the workflow run to complete:

Successful advanced workflow

No extra errors!

For good measure, let’s ensure our native composer.lock is in sync with composer.json once more:

$ composer replace --lock
Enter fullscreen mode

Exit fullscreen mode



Closing ideas

Compatibility testing highlights as soon as once more the significance of getting good take a look at protection for our purposes. Even when we needn’t assist a spread of dependency variations, each time we discover ourselves in must replace certainly one of them, having a robust take a look at suite provides us the arrogance that it will not break some elements of our code. That additionally goes for upgrading to a more recent PHP model.

However then once more, most PHP builders do not have to consider this an excessive amount of. I personally began to look into compatibility testing extra severely after I created my first open-source library and, afterward, after I began exploring building for the console with PHP.

But chances are you’ll finally end up in a state of affairs the place you should construct and supply a PHP package deal with restricted information of goal environments. Be it within the context of a personal firm or as a option to contribute again to the group, when that day comes it could be helpful to have this sort of information useful.



Assets

The Article was Inspired from tech community site.
Contact us if this is inspired from your article and we will give you credit for it for serving the community.

This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 10k Tech related traffic daily !!!

Leave a Reply

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?