Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW Start with lowest installer version for --prefer-lowest #97

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions consts.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,37 @@
'recipe-blog',
];

// list of modules that are required in either:
// - silverstripe/installer
// - silverstripe/recipe-cms
// - silverstripe/recipe-core
const INSTALLER_MODULES = [
// installer
'recipe-plugin',
'vendor-plugin',
'recipe-cms',
'silverstripe-simple',
'silverstripe-login-forms',
// recipe-cms
'recipe-core',
'silverstripe-admin',
'silverstripe-asset-admin',
'silverstripe-campaign-admin',
'silverstripe-versioned-admin',
'silverstripe-cms',
'silverstripe-errorpage',
'silverstripe-reports',
'silverstripe-siteconfig',
'silverstripe-versioned',
'silverstripe-graphql',
'silverstripe-session-manager',
// recipe-core
'silverstripe-assets',
'silverstripe-config',
'silverstripe-framework',
'silverstripe-mimevalidator',
];
Comment on lines +26 to +55
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be all of the modules which have isCore = true in repositories.json - no need to have a duplicate list here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list isn't quite the same:

repositories.json - isCore:

developer-docs
admin
asset-admin
assets
campaign-admin
cms
config
errorpage
framework
graphql
installer
session-manager
recipe-cms
recipe-core
recipe-plugin
reports
siteconfig
vendor-plugin
versioned
versioned-admin
simple

Things in repositories.json not in INSTALLER_MODULES (this doesn't really matter):

developer-docs
installer

Things in INSTALLER_MODULES not in repositories.json (this matters):

login-forms
mime-validator


// use hardcoded.php to bulk update update this after creating a .cow.pat.json
// for multiple versions, use an array e.g. silverstripe-mymodule => ['2.3', '2.4']
const INSTALLER_TO_REPO_MINOR_VERSIONS = [
Expand Down
16 changes: 15 additions & 1 deletion job_creator.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,24 @@ public function getInstallerVersion(

public function createJob(int $phpIndex, array $opts): array
{
$isInstallerModule = in_array($this->repoName, INSTALLER_MODULES);
$isPreferLoweset = strpos($opts['composer_args'] ?? '', '--prefer-lowest') !== false;
$installerVersion = $this->installerVersion;
$cmsMajor = BranchLogic::getCmsMajor($this->repoData, $this->branch, $this->getComposerJsonContent());
if ($cmsMajor >= 5 && !$isInstallerModule && $isPreferLoweset && $installerVersion) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ($cmsMajor >= 5 && !$isInstallerModule && $isPreferLoweset && $installerVersion) {
if (!$isInstallerModule && $isPreferLoweset && $installerVersion) {

There's no reason to exclude CMS 4 here - those should all have compatible dependencies already (and if they don't, that's a problem)

Copy link
Member Author

@emteknetnz emteknetnz Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason it's excluded is because in the corresponding gha-ci PR each major will have the following minor releases:
x.0, x.1, x.2, x.3, x.4

The way this solution works it needs to start at x.0. CMS 4 goes all the was up to 4.13. I don't really want it to waste lots of time incrementing all the way up to x.13 if something just isn't going to install.

If CMS 4 does suffer from a --prefer-lowest incompatibility, it's not worth fixing at this point in its lifecycle. There's a simple work around of simply upgrade something else to get things to install.

// --prefer-lowest jobs should use the lowest installer version for non-installer modules
// gha-ci will increment the installer version higher if composer is unable to install
// and try installing again
Comment on lines +141 to +142
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For prefer-lowest it probably shouldn't increment the installer version - that goes against the entire point of using prefer-lowest.

Copy link
Member Author

@emteknetnz emteknetnz Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incrementing installer is the entire point of this solution

It always starts off trying to using installer 5.0. If that fails to installs, then it attempts installer 5.1

This would have caught out the original issue that started all of this. That version of elemental has a framework dep of ^5, instead of ^5.1. What happened before is the --prefer-lowest builds were installing using a recent version of installer that included a version of framework that DID have the eagerLoad API (added in 5.1).

With this new solution it would have instead installed with installer 5.0, and this would have lead to the CI build going red because of the missing API called in the unit test and we'd see the issue.

With this solution, which the framework dep correctly being ^5.1 instead, it will fail to install with installer 5.0, then it will successfully install with installer 5.1. Which is what we want to test --prefer-lowest with because that's what the specified minimum version of framework/installer is.

//
// Was going to use something like 5.2.x-dev, install 5.0.x-dev instead
$installerVersion = preg_replace('#^([0-9])\.[0-9]\.x-dev$#', '$1.0.x-dev', $installerVersion);
// Was going to use something like 5.x-dev, install 5.0.x-dev instaed
$installerVersion = preg_replace('#^([0-9])\.x-dev$#', '$1.0.x-dev', $installerVersion);
Comment on lines +144 to +147
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should detect the lowest supported version based on the composer dependencies! That's what this is all about.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The detection is done gha-ci rather than gha-generate-matrix

Makes far more sense to use composer to work out what's installable and what's not rather than trying to work out what's installable and what's not by looking at composer.json files in gha-generate-matrix

}
$default = [
# ensure there's a default value for all possible return keys
# this allows us to use `if [[ "${{ matrix.key }}" == "true" ]]; then` in gha-ci/ci.yml
'installer_version' => $this->installerVersion,
'installer_version' => $installerVersion,
'php' => $this->getPhpVersion($phpIndex),
'parent_branch' => $this->parentBranch,
'db' => DB_MYSQL_57,
Expand Down
45 changes: 44 additions & 1 deletion tests/JobCreatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,49 @@

class JobCreatorTest extends TestCase
{
public function provideCreateJobPreferLowest(): array
{
return [
'installer-module cms 4' => [
'branch' => '4',
'ghrepo' => 'silverstripe/silverstripe-framework',
'expected' => '4.x-dev',
],
'non-installer-module cms 4' => [
'branch' => '4',
'ghrepo' => 'dnadesign/silverstripe-elemental',
'expected' => '4.x-dev',
],
'installer-module cms 5' => [
'branch' => '5',
'ghrepo' => 'silverstripe/silverstripe-framework',
'expected' => '5.x-dev',
],
'non-installer-module cms 5' => [
'branch' => '5',
'ghrepo' => 'dnadesign/silverstripe-elemental',
'expected' => '5.0.x-dev',
],
];
}

/**
* @dataProvider provideCreateJobPreferLowest
*/
public function testCreateJobPreferLowest(string $branch, string $ghrepo, string $expected): void
{
$installerVersionProperty = new ReflectionProperty(JobCreator::class, 'installerVersion');
$installerVersionProperty->setAccessible(true);
$creator = new JobCreator();
$installerVersionProperty->setValue($creator, "$branch.x-dev");
$creator->githubRepository = $ghrepo;
$creator->repoName = explode('/', $ghrepo)[1];
$creator->branch = $branch;
$creator->parseRepositoryMetadata();
$actual = $creator->createJob(0, ['composer_args' => '--prefer-lowest'])['installer_version'];
$this->assertSame($expected, $actual);
}

/**
* @dataProvider provideCreateJob
*/
Expand Down Expand Up @@ -962,7 +1005,7 @@ public function testGetInstallerVersionFromComposer(
$creator = new JobCreator();
$creator->composerJsonPath = '__composer.json';
$json = json_decode($creator->createJson($yml));
$this->assertSame($expected, $json->include[0]->installer_version);
$this->assertSame($expected, $json->include[1]->installer_version);
} finally {
unlink('__composer.json');
unlink('__installer_branches.json');
Expand Down
6 changes: 6 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<?php
$autoloadPath = __DIR__ . '/../vendor/autoload.php';
if (!file_exists($autoloadPath)) {
throw new RuntimeException('Run composer install first');
}
require_once $autoloadPath;

// working directory will be root
include 'consts.php';
include 'job_creator.php';
Loading