ci/backward-compatibility-check - #634
Conversation
1.5.0 introduced backward-incompatible changes in a minor release (google#628). This restores src/ and tests/ to the 1.4.2 tag verbatim, so the library is behaviourally identical to 1.4.2 for every consumer. Verification: `git diff 1.4.2 -- src` is empty. There are no source changes to review, and no version constant is touched here, since choosing and tagging the release is the maintainers' call. Restored by reverting rather than by re-implementing: - untyped public signatures with phpdoc, no native param or return types - no return type on the RequestMethod::submit() interface - non-readonly Response and RequestParameters - the Curl and Socket wrapper classes and their ?Curl / ?Socket dependency-injection constructors, so the documented pattern for testing a custom RequestMethod works again 1.4.2 predates the phpstan level max and php-cs-fixer setup this repo now runs in CI, and reports 191 pre-existing errors, 62 of them in src/. Many of those, such as offset access on mixed and resource parameters, cannot be resolved with annotations alone. Changing code in a revert would defeat the purpose of the revert, so they are recorded in phpstan-baseline.neon instead. The follow-up hardening removes entries from it as it adds the guards that fix them. php-cs-fixer needed no changes to the 1.4.2 sources. phpunit 52 passing, phpstan clean against the baseline, php-cs-fixer clean.
1.5.0 shipped several BC breaks in a minor release without anyone noticing until after the tag (google#628). This adds Roave/BackwardCompatibilityCheck as a CI job so that class of mistake fails the build instead of reaching a release. The check runs as its own job and compares against the most recent release tag, so the checkout needs the full history rather than a shallow clone. It is added as a container action rather than a dev dependency, to keep it out of the project's own dependency resolution. One ordering note: this is only useful once the restored API has been tagged, since until then the most recent tag is 1.5.0 and the check would correctly flag the deliberate revert as a break.
| fetch-depth: 0 | ||
|
|
||
| - name: Check for BC breaks since the last release | ||
| uses: docker://nyholm/roave-bc-check-ga |
There was a problem hiding this comment.
Unfortunately the nyholm/roave-bc-check-ga docker image isn't maintained by roave/backward-compatibility-check and is more than 3 years out of date (there's an open issue for this) - it contains a number of dependency versions with security vulnerabilities.
You could explore getting the docker image updated, alternatively in Behat we deal with this by just composer install roave-backward-compatibility-check in a temporary subdirectory, which ensures we're always using the latest versions. https://github.com/Behat/Behat/blob/b077d2c8ddc6c78506e4372150e0b6d9db3e0781/.github/workflows/build.yml#L154-L178
There was a problem hiding this comment.
Good catch, thank you — I hadn't realised the Docker image was that stale. I've switched to the same approach Behat uses: composer-installing roave/backward-compatibility-check into its own directory at runtime, so it always picks up current releases and stays out of the project's dependency resolution. Pushed as a follow-up commit.
Review on the PR pointed out that the nyholm/roave-bc-check-ga docker image is not maintained by the Roave project, is several years out of date, and carries dependency versions with known vulnerabilities. Following the approach Behat uses: install roave/backward-compatibility-check with composer into its own directory at run time, so the check always runs with current releases while its dependencies stay out of this library's own dependency resolution, then invoke the binary directly with the github-actions output format.
The repository's workflow security check requires every action reference to be pinned to a full commit hash rather than a mutable tag, and it flags all five uses in this file, including the three that predate this branch. Each is pinned to the commit behind the latest release within the major version the workflow was already using, with the version kept as a comment: - actions/checkout v4.4.0 - shivammathur/setup-php 2.37.2 - actions/cache v4.3.0 No behaviour change beyond moving to the newest release of each major.
1.5.0 shipped several BC breaks in a minor release without anyone noticing until after the tag (#628). This addsRoave/BackwardCompatibilityCheck as a CI job so that this class of mistake fails the build instead of reaching a release. As suggested in review, this is more robust than adding unit tests for specific bits of BC.
It runs as its own job and compares against the most recent release tag, so the checkout needs the full history rather than a shallow clone. It is added as a container action rather than a dev dependency, to keep it out of the project's own dependency resolution.
One ordering note: this is only useful once the restored API has been tagged. Until then, the most recent tag is 1.5.0, and the check would correctly flag the deliberate revert in the previous PR as a break.
Props to @acoulton