diff --git a/funcs_scripts.php b/funcs_scripts.php index 979d8fe..1fe20a6 100644 --- a/funcs_scripts.php +++ b/funcs_scripts.php @@ -150,6 +150,10 @@ function is_module() return false; } + if (is_gha_repository()) { + return false; + } + $contents = read_file('composer.json'); $json = json_decode($contents); if (is_null($json)) { @@ -158,7 +162,7 @@ function is_module() } // config isn't technically a Silverstripe CMS module, but we treat it like one. - if ($json->name === 'silverstripe/config') { + if (($json->name ?? '') === 'silverstripe/config') { return true; } @@ -238,6 +242,7 @@ function is_docs() /** * Determine if the module being processed is a gha-* repository e.g. gha-ci + * aka "WORKFLOW" * * Example usage: * is_gha_repository() @@ -254,6 +259,56 @@ function is_gha_repository() ); } +/** + * Determine if the module being processed is "TOOLING" + * + * Example usage: + * is_gha_repository() + */ +function is_tooling() +{ + global $GITHUB_REF; + return in_array( + $GITHUB_REF, + array_column( + MetaData::getAllRepositoryMetaData()[MetaData::CATEGORY_TOOLING], + 'github' + ) + ); +} + +/** + * Determine if the module being processed is "MISC" + * + * Example usage: + * is_gha_repository() + */ +function is_misc() +{ + global $GITHUB_REF; + return in_array( + $GITHUB_REF, + array_column( + MetaData::getAllRepositoryMetaData()[MetaData::CATEGORY_MISC], + 'github' + ) + ); +} + +/** + * Determine if the module being processed has a wildcard major version mapping + * in silverstripe/supported-modules repositories.json + * + * Example usage: + * has_wildcard_major_version_mapping() + */ +function has_wildcard_major_version_mapping() +{ + global $GITHUB_REF; + $repoData = MetaData::getMetaDataForRepository($GITHUB_REF); + return array_key_exists('*', $repoData['majorVersionMapping']); +} + /** * Return the module name without the account e.g. silverstripe/silverstripe-admin with return silverstripe-admin * @@ -350,21 +405,25 @@ function human_cron(string $cron): string * between 1 and 28 * Note that this will return the exact same value every time it is called for a given filename in a given module */ -function predictable_random_int($max, $offset = 0): int +function predictable_random_int($scriptName, $max, $offset = 0): int +{ + $chars = str_split(module_name() . $scriptName); + $codes = array_map(fn($c) => ord($c), $chars); + $sum = array_sum($codes); + $remainder = $sum % ($max + 1); + return $remainder + $offset; +} + +/** + * Determine if the current branch is either 1 or 1.2 numeric style + * Can also be pulls//... style + */ +function current_branch_name_is_numeric_style() { global $MODULE_DIR; - $callingFile = debug_backtrace()[0]['file']; - // remove absolute path e.g. /home/myuser/... - $moduleStandardiserDir = basename(__DIR__); - $dirQuoted = preg_quote($moduleStandardiserDir); - // double $dirQuoted is for github actions CI where there which will have a directory strcture - // with /module-standardiser/module-standardiser/... - if (!preg_match("#/$dirQuoted/$dirQuoted/(.+)$#", $callingFile, $matches)) { - preg_match("#/$dirQuoted/(.+)$#", $callingFile, $matches); + $currentBranch = cmd('git rev-parse --abbrev-ref HEAD', $MODULE_DIR); + if (preg_match('#^(pulls/)?([0-9]+)(\.[0-9]+)?(/|$)#', $currentBranch)) { + return true; } - $relativePath = $matches[1]; - $chars = str_split("$MODULE_DIR-$relativePath"); - $codes = array_map(fn($c) => ord($c), $chars); - mt_srand(array_sum($codes)); - return mt_rand(0, $max) + $offset; + return false; } diff --git a/funcs_utils.php b/funcs_utils.php index 5a92e13..1208e25 100644 --- a/funcs_utils.php +++ b/funcs_utils.php @@ -287,13 +287,14 @@ function current_branch_cms_major( return MetaData::HIGHEST_STABLE_CMS_MAJOR; } + $contents = ''; if ($composerJson) { $contents = $composerJson; } elseif (check_file_exists('composer.json')) { $contents = read_file('composer.json'); } $composerJson = json_decode($contents); - if (is_null($composerJson)) { + if (is_null($composerJson) && check_file_exists('composer.json')) { $lastError = json_last_error(); error("Could not parse from composer.json - last error was $lastError"); } diff --git a/scripts/cms-any/dispatch-ci.php b/scripts/cms-any/dispatch-ci.php index 41e2450..a9afb3a 100644 --- a/scripts/cms-any/dispatch-ci.php +++ b/scripts/cms-any/dispatch-ci.php @@ -1,13 +1,13 @@ assertSame(0, predictable_random_int(15)); - $this->assertSame(25, predictable_random_int(30)); - $this->assertSame(45, predictable_random_int(30, 20)); - $MODULE_DIR = 'donuts'; - $this->assertSame(13, predictable_random_int(15)); - // use eval to simulate calling from a different file - // it will suffix "(19) : eval()'d code" to the calling file in debug_backtrace() - $ret = null; - eval('$ret = predictable_random_int(15);'); - $this->assertSame(2, $ret); + global $GITHUB_REF; + // set $GITHUB_REF because by module_name() which is used by predictable_random_int() + $GITHUB_REF = 'myaccount/lorem'; + $this->assertSame(1, predictable_random_int('test-script', 15)); + // Setting a higher max does more than just add to the result, it's somewhat random + $this->assertSame(23, predictable_random_int('test-script', 30)); + // Setting an offset simply adds to the result of the same max as above + $this->assertSame(43, predictable_random_int('test-script', 30, 20)); + // Changing $GITHUB_REF will change the result + $GITHUB_REF = 'myaccount/donuts'; + $this->assertSame(15, predictable_random_int('test-script', 15)); + // Changing the script name will change the result + $this->assertSame(6, predictable_random_int('different-script', 15)); } } diff --git a/update_command.php b/update_command.php index da64500..f50b518 100644 --- a/update_command.php +++ b/update_command.php @@ -47,6 +47,7 @@ $cloneUrl = $module['cloneUrl']; $MODULE_DIR = MODULES_DIR . "/$repo"; $GITHUB_REF = "$account/$repo"; + // clone repo // always clone the actual remote even when doing update-prs even though this is slower // reason is because we read origin in .git/config to workout the actual $account in @@ -65,6 +66,8 @@ } cmd("git remote add pr-remote $prOrigin", $MODULE_DIR); + $useDefaultBranch = has_wildcard_major_version_mapping(); + if ($input->getOption('update-prs')) { // checkout latest existing pr branch cmd('git fetch pr-remote', $MODULE_DIR); @@ -72,7 +75,7 @@ // example branch name: pulls/5/module-standardiser-1691550112 $allBranches = array_map('trim', $allBranches); $allBranches = array_filter($allBranches, function($branch) { - return preg_match('#^pr\-remote/pulls/[0-9\.]+/module\-standardiser\-[0-9]{10}$#', $branch); + return preg_match('#^pr\-remote/pulls/.+?/module\-standardiser\-[0-9]{10}$#', $branch); }); if (empty($allBranches)) { warning("Could not find an existing PR branch for $repo - skipping"); @@ -107,11 +110,12 @@ $defaultBranch = cmd($cmd, $MODULE_DIR); cmd("git checkout $defaultBranch", $MODULE_DIR); - if (is_meta_repo()) { - $branchToCheckout = $allBranches[0]; + $currentBranch = cmd('git rev-parse --abbrev-ref HEAD', $MODULE_DIR); + + // checkout the branch to run scripts over + if ($useDefaultBranch) { + $branchToCheckout = $currentBranch; } else { - // checkout the branch to run scripts over - $currentBranch = cmd('git rev-parse --abbrev-ref HEAD', $MODULE_DIR); // ensure that we're on a standard next-minor style branch if (!ctype_digit($currentBranch)) { $tmp = array_filter($allBranches, fn($branch) => ctype_digit($branch)); @@ -138,7 +142,7 @@ cmd("git checkout $branchToCheckout", $MODULE_DIR); // ensure that this branch actually supports the cmsMajor we're targetting - if ($branchOption !== 'github-default' && current_branch_cms_major() !== $cmsMajor) { + if (!$useDefaultBranch && $branchOption !== 'github-default' && current_branch_cms_major() !== $cmsMajor) { error("Branch $branchToCheckout does not support CMS major version $cmsMajor"); }