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

FIX Update getInstallerVersion #6

Merged
Merged
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
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
push:
pull_request:
workflow_dispatch:

jobs:
ci:
name: CI
runs-on: ubuntu-latest
steps:

- name: Checkout code
uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # v2.4.2

- name: Install PHP
uses: shivammathur/setup-php@3eda58347216592f618bb1dff277810b6698e4ca # v2.19.1
with:
php-version: 8.1
extensions: yaml

- name: Install PHPUnit
run: wget https://phar.phpunit.de/phpunit-9.5.phar

- name: PHPUnit
run: php phpunit-9.5.phar --verbose --colors=always
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.phpunit.result.cache
8 changes: 2 additions & 6 deletions action.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
include 'job_creator.php';

// Reads inputs.yml and creates a new json matrix
$inputs = yaml_parse(file_get_contents('__inputs.yml'));
if ($inputs === false) {
echo 'Unable to parse __inputs.yml';
exit(1);
}
$yml = file_get_contents('__inputs.yml');
$jobCreator = new JobCreator();
echo $jobCreator->createJson($inputs);
echo $jobCreator->createJson($yml);
59 changes: 43 additions & 16 deletions job_creator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,30 @@ public function getInstallerVersion(string $githubRepository, string $branch): s
if (in_array($repo, NO_INSTALLER_REPOS)) {
return '';
}
// e.g. ['4', '11']
$portions = explode('.', $branch);
if (count($portions) == 1) {
return '4.x-dev';
// e.g. pulls/4.10/some-bugfix or pulls/4/some-feature
// for push events to the creative-commoners account
if (preg_match('#^pulls/([0-9\.]+)/#', $branch, $matches)) {
$branch = $matches[1];
}
if (in_array($repo, LOCKSTEPED_REPOS)) {
return '4.' . $portions[1] . '.x-dev';
} else {
// use the latest minor version of installer
$installerVersions = array_keys(INSTALLER_TO_PHP_VERSIONS);
// remove '4' version
$installerVersions = array_diff($installerVersions, ['4']);
// get the minor portions of the verisons e.g. [9, 10, 11]
$minorPortions = array_map(fn($portions) => (int) explode('.', $portions)[1], $installerVersions);
sort($minorPortions);
return '4.' . $minorPortions[count($minorPortions) - 1] . '.x-dev';
// e.g. 4.10-release
$branch = preg_replace('#^([0-9\.]+)-release$#', '$1', $branch);
if (in_array($repo, LOCKSTEPED_REPOS) && is_numeric($branch)) {
// e.g. ['4', '11']
$portions = explode('.', $branch);
if (count($portions) == 1) {
return '4.x-dev';
} else {
return '4.' . $portions[1] . '.x-dev';
}
}
// use the latest minor version of installer
Copy link
Member

Choose a reason for hiding this comment

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

The only situation where this isn't ideal is prefer-lowest won't actually be testing the lowest version of framework according to the constraint in composer.json.... but we can probably live with that.

$installerVersions = array_keys(INSTALLER_TO_PHP_VERSIONS);
// remove '4' version
$installerVersions = array_diff($installerVersions, ['4']);
// get the minor portions of the verisons e.g. [9, 10, 11]
$minorPortions = array_map(fn($portions) => (int) explode('.', $portions)[1], $installerVersions);
sort($minorPortions);
return '4.' . $minorPortions[count($minorPortions) - 1] . '.x-dev';
}

public function createJob(int $phpIndex, array $opts): array
Expand Down Expand Up @@ -180,8 +187,28 @@ private function buildDynamicMatrix(
return $matrix;
}

public function createJson(array $inputs): string
public function getInputs(string $yml): array
{
$message = 'Failed to parse yml';
try {
$inputs = yaml_parse($yml);
} catch (Exception $e) {
throw new Exception($message);
}
if (!$inputs) {
throw new Exception($message);
}
if (array_key_exists('github_my_ref', $inputs)) {
if (!preg_match("#github_my_ref: *'#", $yml)) {
throw new Exception('github_my_ref needs to be surrounded by single-quotes');
}
}
return $inputs;
}

public function createJson(string $yml): string
{
$inputs = $this->getInputs($yml);
// $myRef will either be a branch for push (i.e cron) and pull-request (target branch), or a semver tag
$myRef = $inputs['github_my_ref'];
$isTag = preg_match('#^[0-9]+\.[0-9]+\.[0-9]+$#', $myRef, $m);
Expand Down
8 changes: 8 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="Default">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
149 changes: 149 additions & 0 deletions tests/JobCreatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<?php

use PHPUnit\Framework\TestCase;

class JobCreatorTest extends TestCase
{
/**
* @dataProvider provideGetInstallerVersion
*/
public function testGetInstallerVersion(
string $githubRepository,
string $branch,
string $expected
): void {
$creator = new JobCreator();
$actual = $creator->getInstallerVersion($githubRepository, $branch);
$this->assertSame($expected, $actual);
}

private function getLatestInstallerVersion(): string
{
$versions = array_keys(INSTALLER_TO_PHP_VERSIONS);
natsort($versions);
$versions = array_reverse($versions);
return $versions[0];
}

public function provideGetInstallerVersion(): array
{
$latest = $this->getLatestInstallerVersion() . '.x-dev';
return [
// no-installer repo
['myaccount/recipe-cms', '4', ''],
['myaccount/recipe-cms', '4.10', ''],
['myaccount/recipe-cms', 'burger', ''],
['myaccount/recipe-cms', 'pulls/4/myfeature', ''],
['myaccount/recipe-cms', 'pulls/4.10/myfeature', ''],
['myaccount/recipe-cms', 'pulls/burger/myfeature', ''],
['myaccount/recipe-cms', '4-release', ''],
['myaccount/recipe-cms', '4.10-release', ''],
// lockstepped repo with 4.* naming
['myaccount/silverstripe-framework', '4', '4.x-dev'],
['myaccount/silverstripe-framework', '4.10', '4.10.x-dev'],
['myaccount/silverstripe-framework', 'burger', $latest],
['myaccount/silverstripe-framework', 'pulls/4/mybugfix', '4.x-dev'],
['myaccount/silverstripe-framework', 'pulls/4.10/mybugfix', '4.10.x-dev'],
['myaccount/silverstripe-framework', 'pulls/burger/myfeature', $latest],
['myaccount/silverstripe-framework', '4-release', '4.x-dev'],
['myaccount/silverstripe-framework', '4.10-release', '4.10.x-dev'],
// lockstepped repo with 1.* naming
['myaccount/silverstripe-admin', '1', '4.x-dev'],
['myaccount/silverstripe-admin', '1.10', '4.10.x-dev'],
['myaccount/silverstripe-admin', 'burger', $latest],
['myaccount/silverstripe-admin', 'pulls/1/mybugfix', '4.x-dev'],
['myaccount/silverstripe-admin', 'pulls/1.10/mybugfix', '4.10.x-dev'],
['myaccount/silverstripe-admin', 'pulls/burger/myfeature', $latest],
['myaccount/silverstripe-admin', '1-release', '4.x-dev'],
['myaccount/silverstripe-admin', '1.10-release', '4.10.x-dev'],
// non-lockedstepped repo
['myaccount/silverstripe-tagfield', '2', $latest],
['myaccount/silverstripe-tagfield', '2.9', $latest],
['myaccount/silverstripe-tagfield', 'burger', $latest],
['myaccount/silverstripe-tagfield', 'pulls/2/mybugfix', $latest],
['myaccount/silverstripe-tagfield', 'pulls/2.9/mybugfix', $latest],
['myaccount/silverstripe-tagfield', 'pulls/burger/myfeature', $latest],
['myaccount/silverstripe-tagfield', '2-release', $latest],
['myaccount/silverstripe-tagfield', '2.9-release', $latest],
];
}

/**
* @dataProvider provideGetInputsValid
*/
public function testGetInputsValid(string $yml, array $expected)
{
if (!function_exists('yaml_parse')) {
$this->markTestSkipped('yaml extension is not installed');
}
$creator = new JobCreator();
$actual = $creator->getInputs($yml);
$this->assertSame($expected, $actual);
}

public function provideGetInputsValid(): array
{
return [
[
<<<EOT
endtoend: true
js: true
phpcoverage: false
phpcoverage_force_off: false
phplinting: true
phpunit: true
simple_matrix: false
github_repository: 'myaccount/silverstripe-versioned'
github_my_ref: 'pulls/1.10/module-standards'
EOT,
[
'endtoend' => true,
'js' => true,
'phpcoverage' => false,
'phpcoverage_force_off' => false,
'phplinting' => true,
'phpunit' => true,
'simple_matrix' => false,
'github_repository' => 'myaccount/silverstripe-versioned',
'github_my_ref'=> 'pulls/1.10/module-standards'
]
],
];
}

/**
* @dataProvider provideGetInputsInvalid
*/
public function testGetInputsInvalid(string $yml, string $expectedMessage)
{
if (!function_exists('yaml_parse')) {
$this->markTestSkipped('yaml extension is not installed');
}
$this->expectException(Exception::class);
$this->expectExceptionMessage($expectedMessage);
$creator = new JobCreator();
$creator->getInputs($yml);
}

public function provideGetInputsInvalid(): array
{
return [
// missing quotes around github_my_ref (would turn into an int, so 1.10 becomes 1.1)
[
<<<EOT
github_my_ref: 1.10
EOT,
'github_my_ref needs to be surrounded by single-quotes'
],
// invalid yml
[
<<<EOT
this: --
is: - total: ' nonsense
"
EOT,
'Failed to parse yml'
],
];
}
}
4 changes: 4 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
// working directory will be root
include 'consts.php';
include 'job_creator.php';