Skip to content

Commit

Permalink
ENH Update reference to supported modules data
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed May 8, 2024
1 parent 3029172 commit f7d6f2d
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 169 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,3 @@ MS_GITHUB_TOKEN=abc123 php run.php labels --dry-run --only=silverstripe-config,s
| --exclude=[modules] | Exclude the specified modules (without account prefix) separated by commas e.g. `silverstripe-mfa,silverstripe-totp` |
| --dry-run | Do not update labels in GitHub, output to terminal only |
| --no-delete | Do not delete `_data` directory before running |

## Updating the tool when a new major version of CMS is updated

Update the `CURRENT_CMS_MAJOR` constant in `run.php`
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"require": {
"php": ">=8.1",
"silverstripe/supported-modules": "dev-main",
"symfony/console": "^6.3",
"symfony/process": "^6.3",
"panlatent/cron-expression-descriptor": "^1"
Expand Down
44 changes: 33 additions & 11 deletions funcs_scripts.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Panlatent\CronExpressionDescriptor\ExpressionDescriptor;
use SilverStripe\SupportedModules\MetaData;

// These functions in scripts can be used in scripts

Expand Down Expand Up @@ -123,6 +124,12 @@ function rename_file_if_exists($oldFilename, $newFilename)
*/
function module_is_recipe()
{
global $GITHUB_REF;
$repoData = MetaData::getMetaDataForRepository($GITHUB_REF);
if (isset($repoData['type'])) {
return $repoData['type'] === 'recipe';
}

if (!check_file_exists('composer.json')) {
return false;
}
Expand All @@ -145,6 +152,12 @@ function module_is_recipe()
*/
function is_module()
{
global $GITHUB_REF;
$repoData = MetaData::getMetaDataForRepository($GITHUB_REF);
if (isset($repoData['type'])) {
return $repoData['type'] !== 'other';
}

if (!check_file_exists('composer.json')) {
return false;
}
Expand Down Expand Up @@ -200,6 +213,12 @@ function is_composer_plugin()
*/
function is_theme()
{
global $GITHUB_REF;
$repoData = MetaData::getMetaDataForRepository($GITHUB_REF);
if (isset($repoData['type'])) {
return $repoData['type'] === 'theme';
}

if (!check_file_exists('composer.json')) {
return false;
}
Expand Down Expand Up @@ -243,8 +262,14 @@ function is_docs()
*/
function is_gha_repository()
{
global $MODULE_DIR;
return !is_module() && strpos($MODULE_DIR, '/gha-') !== false;
global $GITHUB_REF;
return in_array(
$GITHUB_REF,
array_column(
MetaData::getAllRepositoryMetaData()[MetaData::CATEGORY_WORKFLOW],
'github'
)
);
}

/**
Expand All @@ -257,8 +282,8 @@ function is_gha_repository()
*/
function module_name()
{
global $MODULE_DIR;
$parts = explode('/', $MODULE_DIR);
global $GITHUB_REF;
$parts = explode('/', $GITHUB_REF);
return end($parts);
}

Expand All @@ -270,15 +295,15 @@ function module_name()
*/
function module_is_one_of($repos)
{
global $MODULE_DIR;
global $GITHUB_REF;
if (!is_array($repos)) {
error('repos is not an array');
}
foreach ($repos as $repo) {
if (!is_string($repo)) {
error('repo is not a string');
}
if (strpos($MODULE_DIR, "/$repo") !== false) {
if (strpos($GITHUB_REF, "/$repo") !== false) {
return true;
}
}
Expand All @@ -293,11 +318,8 @@ function module_is_one_of($repos)
*/
function module_account()
{
$s = read_file('.git/config');
if (!preg_match('#github.com:([^/]+)/#', $s, $matches)) {
error('Could not determine github account');
}
return $matches[1];
global $GITHUB_REF;
return explode('/', $GITHUB_REF)[0];
}

/**
Expand Down
195 changes: 49 additions & 146 deletions funcs_utils.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use SilverStripe\SupportedModules\BranchLogic;
use SilverStripe\SupportedModules\MetaData;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Style\SymfonyStyle;
Expand Down Expand Up @@ -46,85 +48,6 @@ function write_file($path, $contents)
info("Wrote to $path");
}

/**
* Returns all the supported modules for a particular cms major version
* Will download the list if it doesn't exist
*/
function supported_modules($cmsMajor)
{
$filename = "_data/modules-cms$cmsMajor.json";
if (!file_exists($filename)) {
$url = "https://raw.githubusercontent.com/silverstripe/supported-modules/$cmsMajor/modules.json";
info("Downloading $url to $filename");
$contents = file_get_contents($url);
file_put_contents($filename, $contents);
}
$json = json_decode(file_get_contents($filename), true);
if (is_null($json)) {
$lastError = json_last_error();
error("Could not parse from $filename - last error was $lastError");
}
$modules = [];
foreach ($json as $module) {
$ghrepo = $module['github'];
$modules[] = [
'ghrepo' => $ghrepo,
'account' => explode('/', $ghrepo)[0],
'repo' => explode('/', $ghrepo)[1],
'cloneUrl' => "git@github.com:$ghrepo.git",
];
}
return $modules;
}

/**
* Hardcoded list of non-supported, additional repositories to standardise (e.g. silverstripe/gha-*)
*
* Repositories in this list should only have a single supported major version
* This will only be included if the $cmsMajor is the CURRENT_CMS_MAJOR
*/
function extra_repositories()
{
$importantRepos = [
'silverstripe/markdown-php-codesniffer',
'silverstripe/silverstripe-standards',
'silverstripe/documentation-lint',
'silverstripe/.github',
];
$modules = [];
// iterating to page 10 will be enough to get all the repos well into the future
for ($i = 0; $i < 10; $i++) {
$path = "_data/extra_repositories-$i.json";
if (file_exists($path)) {
info("Reading local data from $path");
$json = json_decode(file_get_contents($path), true);
} else {
$json = github_api("https://api.github.com/orgs/silverstripe/repos?per_page=100&page=$i");
file_put_contents($path, json_encode($json, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
if (empty($json)) {
break;
}
foreach ($json as $repo) {
if ($repo['archived']) {
continue;
}
$ghrepo = $repo['full_name'];
// Only include repos we care about
if (!in_array($ghrepo, $importantRepos) && strpos($ghrepo, '/gha-') === false) {
continue;
}
$modules[] = [
'ghrepo' => $ghrepo,
'account' => explode('/', $ghrepo)[0],
'repo' => explode('/', $ghrepo)[1],
'cloneUrl' => "git@github.com:$ghrepo.git",
];
}
}
return $modules;
}

/**
* Returns a list of all scripts files to run against a particular cms major version
*/
Expand Down Expand Up @@ -349,85 +272,45 @@ function branch_to_checkout($branches, $defaultBranch, $currentBranch, $currentB
}

/**
* Uses composer.json to workout the current branch cms major version
*
* If composer.json does not exist then it's assumed to be CURRENT_CMS_MAJOR
* Works out the current branch cms major version
*/
function current_branch_cms_major(
// this param is only used for unit testing
string $composerJson = ''
) {
global $MODULE_DIR;
global $MODULE_DIR, $GITHUB_REF;

// Some repositories don't have a valid matching CMS major
$ignoreCMSMajor = [
'/silverstripe-simple',
'/markdown-php-codesniffer',
];
foreach ($ignoreCMSMajor as $ignore) {
if (strpos($MODULE_DIR, $ignore) !== false) {
return CURRENT_CMS_MAJOR;
}
// This repo matches every major and matches start at the lowest - but we only want the highest stable.
if ($GITHUB_REF === 'silverstripe/silverstripe-simple') {
return MetaData::HIGHEST_STABLE_CMS_MAJOR;
}

if ($composerJson) {
$contents = $composerJson;
} elseif (check_file_exists('composer.json')) {
$contents = read_file('composer.json');
} else {
return CURRENT_CMS_MAJOR;
}

// special logic for developer-docs
if (strpos($MODULE_DIR, '/developer-docs') !== false) {
$currentBranch = cmd('git rev-parse --abbrev-ref HEAD', $MODULE_DIR);
if (!preg_match('#^(pulls/)?([0-9]+)(\.[0-9]+)?(/|$)#', $currentBranch, $matches)) {
error("Could not work out current major for developer-docs from branch $currentBranch");
}
return $matches[2];
}

$json = json_decode($contents);
if (is_null($json)) {
$composerJson = json_decode($contents);
if (is_null($composerJson)) {
$lastError = json_last_error();
error("Could not parse from composer.json - last error was $lastError");
}
$matchedOnBranchThreeLess = false;
$version = preg_replace('#[^0-9\.]#', '', $json->require->{'silverstripe/framework'} ?? '');
if (!$version) {
$version = preg_replace('#[^0-9\.]#', '', $json->require->{'silverstripe/cms'} ?? '');
}
if (!$version) {
$version = preg_replace('#[^0-9\.]#', '', $json->require->{'silverstripe/mfa'} ?? '');
}
if (!$version) {
$version = preg_replace('#[^0-9\.]#', '', $json->require->{'silverstripe/assets'} ?? '');
if ($version) {
$matchedOnBranchThreeLess = true;
}
}
if (!$version) {
$version = preg_replace('#[^0-9\.]#', '', $json->require->{'cwp/starter-theme'} ?? '');
if ($version) {
$version += 1;
}
}
$cmsMajor = '';
if (preg_match('#^([0-9]+)+\.?[0-9]*$#', $version, $matches)) {
$cmsMajor = $matches[1];
if ($matchedOnBranchThreeLess) {
$cmsMajor += 3;
}
} else {
$phpVersion = $json->require->{'php'} ?? '';
if (substr($phpVersion,0, 4) === '^7.4') {
$cmsMajor = 4;
} elseif (substr($phpVersion,0, 4) === '^8.1') {
$cmsMajor = 5;

$repoData = MetaData::getMetaDataForRepository($GITHUB_REF);
$branchMajor = '';
// If we're running unit tests, $MODULE_DIR will be some fake value with causes errors here
if (!running_unit_tests()) {
$currentBranch = cmd('git rev-parse --abbrev-ref HEAD', $MODULE_DIR);
if (preg_match('#^(pulls/)?([0-9]+)(\.[0-9]+)?(/|$)#', $currentBranch, $matches)) {
$branchMajor = $matches[2];
}
}
$cmsMajor = BranchLogic::getCmsMajor($repoData, $branchMajor, $composerJson, true);

if ($cmsMajor === '') {
error('Could not work out what the current CMS major version is');
// The supported modules metadata has a bunch of repos with no specific major version mapping.
// Just assume they're on the highest major in that case.
return MetaData::HIGHEST_STABLE_CMS_MAJOR;
}
return (string) $cmsMajor;
}
Expand All @@ -445,13 +328,18 @@ function setup_directories($input, $dirs = [DATA_DIR, MODULES_DIR]) {
}
}

function filtered_modules($cmsMajor, $input) {
$modules = supported_modules($cmsMajor);
if ($cmsMajor === CURRENT_CMS_MAJOR) {
// only include extra_repositories() when using the current CMS major version because the extra rexpositories
// don't have multi majors branches supported e.g. gha-generate-matrix
$modules = array_merge($modules, extra_repositories());
}
function filtered_modules($cmsMajor, $input)
{
$repos = MetaData::removeReposNotInCmsMajor(
MetaData::getAllRepositoryMetaData(false),
$cmsMajor,
// This ensures that we only have one scenario that includes repositories which don't have
// multi major branches supported e.g. gha-generate-matrix
$cmsMajor === MetaData::HIGHEST_STABLE_CMS_MAJOR
);

$modules = reformat_repos_data($repos);

if ($input->getOption('only')) {
$only = explode(',', $input->getOption('only'));
$modules = array_filter($modules, function ($module) use ($only) {
Expand All @@ -466,3 +354,18 @@ function filtered_modules($cmsMajor, $input) {
}
return $modules;
}

function reformat_repos_data(array $repos)
{
$newFormatRepos = [];
foreach ($repos as $repo) {
$ghrepo = $repo['github'];
$newFormatRepos[] = [
'ghrepo' => $ghrepo,
'account' => explode('/', $ghrepo)[0],
'repo' => explode('/', $ghrepo)[1],
'cloneUrl' => "git@github.com:$ghrepo.git",
];
}
return $newFormatRepos;
}
5 changes: 3 additions & 2 deletions labels_command.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use SilverStripe\SupportedModules\MetaData;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
Expand Down Expand Up @@ -73,8 +74,8 @@
// modules
$modules = [];
$repos = [];
$modulesCurrentMajor = filtered_modules(CURRENT_CMS_MAJOR, $input);
$modulesPreviousMajor = filtered_modules(CURRENT_CMS_MAJOR - 1, $input);
$modulesCurrentMajor = filtered_modules(MetaData::HIGHEST_STABLE_CMS_MAJOR, $input);
$modulesPreviousMajor = filtered_modules(MetaData::HIGHEST_STABLE_CMS_MAJOR - 1, $input);
foreach ([$modulesCurrentMajor, $modulesPreviousMajor] as $modulesList) {
foreach ($modulesList as $module) {
$repo = $module['repo'];
Expand Down
Loading

0 comments on commit f7d6f2d

Please sign in to comment.