diff --git a/funcs_utils.php b/funcs_utils.php index 1208e25..edccfa6 100644 --- a/funcs_utils.php +++ b/funcs_utils.php @@ -152,7 +152,8 @@ function github_api($url, $data = [], $httpMethod = '') { // silverstripe-themes has a kind of weird redirect only for api requests $url = str_replace('/silverstripe-themes/silverstripe-simple', '/silverstripe/silverstripe-simple', $url); - info("Making curl request to $url"); + $method = $httpMethod ? strtoupper($httpMethod) : 'GET'; + info("Making $method curl request to $url"); $token = github_token(); $jsonStr = empty($data) ? '' : json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $ch = curl_init($url); @@ -244,6 +245,44 @@ function output_repos_with_labels_updated() $io->writeln(''); } +/** + * Outputs a list of repos that that had rulesets updated + * If there was an error with a run (probably a secondary rate limit), this can be + * copy pasted into the --exclude option for the next run to continue from where you left off + */ +function output_repos_with_rulesets_created_or_updated() +{ + if (running_unit_tests()) { + return; + } + global $REPOS_WITH_RULESETS_UPDATED; + $io = io(); + $io->writeln(''); + $io->writeln('Repos with rulesets created/updated (add to --exclude if you need to re-run):'); + $io->writeln(implode(',', $REPOS_WITH_RULESETS_UPDATED)); + $io->writeln(''); +} + +function create_ruleset($type, $additionalBranchConditions = []) +{ + $ruleset = file_get_contents("rulesets/$type-ruleset.json"); + if (!$ruleset) { + error("Could not read ruleset for $type"); + } + $json = json_decode($ruleset, true); + if ($type == 'branch') { + $json['name'] = BRANCH_RULESET_NAME; + } elseif ($type === 'tag') { + $json['name'] = TAG_RULESET_NAME; + } else { + error("Invalid ruleset type: $type"); + } + foreach ($additionalBranchConditions as $value) { + $json['conditions']['ref_name']['include'][] = $value; + } + return $json; +} + /** * Works out which branch in a module to checkout before running scripts on it * diff --git a/rulesets/branch-ruleset.json b/rulesets/branch-ruleset.json new file mode 100644 index 0000000..44e87a6 --- /dev/null +++ b/rulesets/branch-ruleset.json @@ -0,0 +1,44 @@ +{ + "name": "", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [ + "refs/heads/[0-9]*" + ] + } + }, + "rules": [ + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + }, + { + "type": "creation" + }, + { + "type": "update" + }, + { + "type": "pull_request", + "parameters": { + "required_approving_review_count": 2, + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": false, + "require_last_push_approval": true, + "required_review_thread_resolution": false + } + } + ], + "bypass_actors": [ + { + "actor_id": 5, + "actor_type": "RepositoryRole", + "bypass_mode": "always" + } + ] +} diff --git a/rulesets/tag-ruleset.json b/rulesets/tag-ruleset.json new file mode 100644 index 0000000..e6740f2 --- /dev/null +++ b/rulesets/tag-ruleset.json @@ -0,0 +1,34 @@ +{ + "name": "", + "target": "tag", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [ + "~ALL" + ] + } + }, + "rules": [ + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + }, + { + "type": "creation" + }, + { + "type": "update" + } + ], + "bypass_actors": [ + { + "actor_id": 5, + "actor_type": "RepositoryRole", + "bypass_mode": "always" + } + ] +} diff --git a/rulesets_command.php b/rulesets_command.php new file mode 100644 index 0000000..6dcb512 --- /dev/null +++ b/rulesets_command.php @@ -0,0 +1,110 @@ +getOption('dry-run')) { + info('Not updating rulesets on GitHub because --dry-run option is set'); + } else { + foreach ($apiCalls as $apiCall) { + github_api($apiCall[0], $apiCall[1], $apiCall[2]); + } + } + + $REPOS_WITH_RULESETS_UPDATED[] = $repo; + } + + output_repos_with_rulesets_created_or_updated(); + return Command::SUCCESS; +}; diff --git a/run.php b/run.php index 643909d..7bc22fa 100644 --- a/run.php +++ b/run.php @@ -5,6 +5,7 @@ include 'funcs_utils.php'; include 'update_command.php'; include 'labels_command.php'; +include 'rulesets_command.php'; use SilverStripe\SupportedModules\MetaData; use Symfony\Component\Console\Application; @@ -19,6 +20,8 @@ const TOOL_URL = 'https://github.com/silverstripe/module-standardiser'; const PR_TITLE = 'MNT Run module-standardiser'; const PR_DESCRIPTION = 'This pull-request was created automatically by [module-standardiser](' . TOOL_URL . ')'; +const BRANCH_RULESET_NAME = 'Silverstripe branch ruleset'; +const TAG_RULESET_NAME = 'Silverstripe tag ruleset'; // global variables $MODULE_DIR = ''; @@ -26,6 +29,7 @@ $PRS_CREATED = []; $REPOS_WITH_PRS_CREATED = []; $REPOS_WITH_LABELS_UPDATED = []; +$REPOS_WITH_RULESETS_UPDATED = []; $OUT = null; // options @@ -102,6 +106,13 @@ ->addOption(...$optionNoDelete) ->setCode($labelsCommand); +$app->register('rulesets') + ->setDescription('Script to set rulesets on all repos only on the silverstripe account') + ->addOption(...$optionOnly) + ->addOption(...$optionExclude) + ->addOption(...$optionDryRun) + ->setCode($rulesetsCommand); + try { $app->run(); } catch (Error|Exception $e) {