From 8725f2d222b1a228fdf42a98e54c28b30f2c2e16 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Sat, 19 Aug 2023 10:50:03 +1200 Subject: [PATCH 1/8] ENH Use gha-trigger-ci --- action.yml | 112 +++++++++++++++++++++++++++++++++++------ funcs.php | 5 ++ tests/BranchesTest.php | 50 +++++++++++++++++- 3 files changed, 150 insertions(+), 17 deletions(-) diff --git a/action.yml b/action.yml index 61a0205..34be01f 100644 --- a/action.yml +++ b/action.yml @@ -137,6 +137,7 @@ runs: fetch-depth: 0 - name: Git merge-up + id: git-merge-up shell: bash env: BRANCHES: ${{ steps.determine.outputs.branches }} @@ -149,6 +150,19 @@ runs: git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions" + # List of branches to trigger-ci for later + # Normally we'll only ever trigger 3 branches, though providing up to 6 for scenarios + # where there is are things like betas in the mix + # branches.php will throw an Exception early if there is more than 6 branches which will cause + # this job to fail without any merge-ups being performed + TRIGGER_CI_BRANCH_01="" + TRIGGER_CI_BRANCH_02="" + TRIGGER_CI_BRANCH_03="" + TRIGGER_CI_BRANCH_04="" + TRIGGER_CI_BRANCH_05="" + TRIGGER_CI_BRANCH_06="" + TRIGGER_CI_EXCEEDED="" + FROM_BRANCH="" INTO_BRANCH="" for BRANCH in $BRANCHES; do @@ -160,8 +174,13 @@ runs: echo "Attempting to merge-up $FROM_BRANCH into $INTO_BRANCH" # Checkout both branches to ensure branch info is up to date + # Also runs `git pull` which should not be necessary, though in practice GitHub actions sometimes + # rejects when pushing saying the tip of the branch is out of date. This possibly only happens + # when running a failed job though that's still a valid scenario git checkout $FROM_BRANCH + git pull git checkout $INTO_BRANCH + git pull # Determine if we will rebuild dist file during merge-up # This is based simply on if there are changes in the client/ directory @@ -317,22 +336,83 @@ runs: git push origin $INTO_BRANCH echo "Succesfully merged-up $FROM_BRANCH into $INTO_BRANCH" - # Trigger the CI workflow manually via GitHub API - # Do this because the ci.yml `push` event does not seem to be triggered by another workflow doing a push, - # instead it only seems to be triggered by a normal git user doing a push - # https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event - RESP_CODE=$(curl -w %{http_code} -s -L -o /dev/null \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ github.token }}"\ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/$GITHUB_REPOSITORY/actions/workflows/ci.yml/dispatches \ - -d "{\"ref\":\"$INTO_BRANCH\"}" - ) - if [[ $RESP_CODE != "204" ]]; then - echo "Failed to dispatch workflow - HTTP response code was $RESP_CODE" - exit 1 + if [[ $TRIGGER_CI_BRANCH_01 == "" ]]; then + TRIGGER_CI_BRANCH_01=$INTO_BRANCH + elif [[ $TRIGGER_CI_BRANCH_02 == "" ]]; then + TRIGGER_CI_BRANCH_02=$INTO_BRANCH + elif [[ $TRIGGER_CI_BRANCH_03 == "" ]]; then + TRIGGER_CI_BRANCH_03=$INTO_BRANCH + elif [[ $TRIGGER_CI_BRANCH_04 == "" ]]; then + TRIGGER_CI_BRANCH_04=$INTO_BRANCH + elif [[ $TRIGGER_CI_BRANCH_05 == "" ]]; then + TRIGGER_CI_BRANCH_05=$INTO_BRANCH + elif [[$TRIGGER_CI_BRANCH_06 == "" ]]; then + TRIGGER_CI_BRANCH_06=$INTO_BRANCH else - echo "Succesfully triggered CI workflow for $INTO_BRANCH" + if [[ $TRIGGER_CI_EXCEEDED == "" ]]; then + TRIGGER_CI_EXCEEDED=$INTO_BRANCH + else + TRIGGER_CI_EXCEEDED="$TRIGGER_CI_EXCEEDED,$INTO_BRANCH" + fi fi done + echo "TRIGGER_CI_BRANCH_01 is $TRIGGER_CI_BRANCH_01" + echo "TRIGGER_CI_BRANCH_02 is $TRIGGER_CI_BRANCH_02" + echo "TRIGGER_CI_BRANCH_03 is $TRIGGER_CI_BRANCH_03" + echo "TRIGGER_CI_BRANCH_04 is $TRIGGER_CI_BRANCH_04" + echo "TRIGGER_CI_BRANCH_05 is $TRIGGER_CI_BRANCH_05" + echo "TRIGGER_CI_BRANCH_06 is $TRIGGER_CI_BRANCH_06" + echo "TRIGGER_CI_EXCEEDED is $TRIGGER_CI_EXCEEDED" + echo "trigger_ci_branch_01=$TRIGGER_CI_BRANCH_01" >> $GITHUB_OUTPUT + echo "trigger_ci_branch_02=$TRIGGER_CI_BRANCH_02" >> $GITHUB_OUTPUT + echo "trigger_ci_branch_03=$TRIGGER_CI_BRANCH_03" >> $GITHUB_OUTPUT + echo "trigger_ci_branch_04=$TRIGGER_CI_BRANCH_04" >> $GITHUB_OUTPUT + echo "trigger_ci_branch_05=$TRIGGER_CI_BRANCH_05" >> $GITHUB_OUTPUT + echo "trigger_ci_branch_06=$TRIGGER_CI_BRANCH_06" >> $GITHUB_OUTPUT + echo "trigger_ci_exceeded=$TRIGGER_CI_EXCEEDED" >> $GITHUB_OUTPUT + + - name: Trigger CI 01 + if: ${{ steps.git-merge-up.outputs.trigger_ci_branch_01 != '' }} + uses: silverstripe/gha-trigger-ci@v1 + with: + branch: ${{ steps.git-merge-up.outputs.trigger_ci_branch_01 }} + + - name: Trigger CI 02 + if: ${{ steps.git-merge-up.outputs.trigger_ci_branch_02 != '' }} + uses: silverstripe/gha-trigger-ci@v1 + with: + branch: ${{ steps.git-merge-up.outputs.trigger_ci_branch_02 }} + + - name: Trigger CI 03 + if: ${{ steps.git-merge-up.outputs.trigger_ci_branch_03 != '' }} + uses: silverstripe/gha-trigger-ci@v1 + with: + branch: ${{ steps.git-merge-up.outputs.trigger_ci_branch_03 }} + + - name: Trigger CI 04 + if: ${{ steps.git-merge-up.outputs.trigger_ci_branch_04 != '' }} + uses: silverstripe/gha-trigger-ci@v1 + with: + branch: ${{ steps.git-merge-up.outputs.trigger_ci_branch_04 }} + + - name: Trigger CI 05 + if: ${{ steps.git-merge-up.outputs.trigger_ci_branch_05 != '' }} + uses: silverstripe/gha-trigger-ci@v1 + with: + branch: ${{ steps.git-merge-up.outputs.trigger_ci_branch_05 }} + + - name: Trigger CI 06 + if: ${{ steps.git-merge-up.outputs.trigger_ci_branch_06 != '' }} + uses: silverstripe/gha-trigger-ci@v1 + with: + branch: ${{ steps.git-merge-up.outputs.trigger_ci_branch_06 }} + + - name: Trigger CI Exceeded + if: ${{ steps.git-merge-up.outputs.trigger_ci_exceeded != '' }} + shell: bash + env: + TRIGGER_CI_EXCEEDED: ${{ steps.git-merge-up.outputs.trigger_ci_exceeded }} + run: | + echo "Exceeded the number of branches that can be have CI triggered" + echo "Branches where CI was not triggered is $TRIGGER_CI_EXCEEDED" + exit 1 diff --git a/funcs.php b/funcs.php index 52fa5dc..3d9654d 100644 --- a/funcs.php +++ b/funcs.php @@ -131,6 +131,11 @@ function branches( // reverse the array so that oldest is first $branches = array_reverse($branches); + + // max of 6 branches - also update action.yml if you need to increase this limit + if (count($branches) > 6) { + throw new Exception('More than 6 branches to merge up. Aborting.'); + } return $branches; } diff --git a/tests/BranchesTest.php b/tests/BranchesTest.php index 6aacd1e..92ccd11 100644 --- a/tests/BranchesTest.php +++ b/tests/BranchesTest.php @@ -16,6 +16,10 @@ public function testBranches( string $branchesJson = '', string $tagsJson = '' ) { + $expectException = $expected === ['__exception__']; + if ($expectException) { + $this->expectException(Exception::class); + } $actual = branches( $defaultBranch, $minimumCmsMajor, @@ -24,7 +28,9 @@ public function testBranches( $branchesJson, $tagsJson ); - $this->assertSame($expected, $actual); + if (!$expectException) { + $this->assertSame($expected, $actual); + } } public function provideBranches() @@ -295,6 +301,48 @@ public function provideBranches() EOT, 'tagsJson' => '[]', ], + 'More than 6 branches exception' => [ + 'expected' => ['__exception__'], + 'defaultBranch' => '5', + 'minimumCmsMajor' => '4', + 'githubRepository' => 'lorem/ipsum', + 'composerJson' => << << << Date: Tue, 22 Aug 2023 15:46:53 +1200 Subject: [PATCH 2/8] FIX Handle cwp-watea-theme --- funcs.php | 6 ++++++ tests/BranchesTest.php | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/funcs.php b/funcs.php index 3d9654d..bb50a70 100644 --- a/funcs.php +++ b/funcs.php @@ -46,6 +46,12 @@ function branches( $version = preg_replace('#[^0-9\.]#', '', $json->require->{'silverstripe/assets'} ?? ''); $matchedOnBranchThreeLess = true; } + if (!$version) { + $version = preg_replace('#[^0-9\.]#', '', $json->require->{'cwp/starter-theme'} ?? ''); + if ($version) { + $version += 1; + } + } if (preg_match('#^([0-9]+)+\.?[0-9]*$#', $version, $matches)) { $defaultCmsMajor = $matches[1]; if ($matchedOnBranchThreeLess) { diff --git a/tests/BranchesTest.php b/tests/BranchesTest.php index 92ccd11..505604b 100644 --- a/tests/BranchesTest.php +++ b/tests/BranchesTest.php @@ -343,6 +343,38 @@ public function provideBranches() ] EOT, ], + 'cwp-watea-theme' => [ + 'expected' => ['3.2', '3', '4.0', '4'], + 'defaultBranch' => '4', + 'minimumCmsMajor' => '4', + 'githubRepository' => 'lorem/ipsum', + 'composerJson' => << << << Date: Tue, 22 Aug 2023 16:16:57 +1200 Subject: [PATCH 3/8] FIX Handle repositories without a composer.json --- funcs.php | 18 +++++++++++++++++- tests/BranchesTest.php | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/funcs.php b/funcs.php index bb50a70..1411eef 100644 --- a/funcs.php +++ b/funcs.php @@ -1,5 +1,8 @@ [ + 'silverstripe/framework' => '^' . CURRENT_CMS_MAJOR, + ], + ], JSON_UNESCAPED_SLASHES); + } + $json = json_decode($contents); if (is_null($json)) { $lastError = json_last_error(); diff --git a/tests/BranchesTest.php b/tests/BranchesTest.php index 505604b..e633f5b 100644 --- a/tests/BranchesTest.php +++ b/tests/BranchesTest.php @@ -375,6 +375,32 @@ public function provideBranches() ] EOT, ], + 'gha-ci' => [ + 'expected' => ['1.4', '1'], + 'defaultBranch' => '1', + 'minimumCmsMajor' => '4', + 'githubRepository' => 'silverstripe/gha-ci', + 'composerJson' => '', + 'branchesJson' => << << Date: Tue, 22 Aug 2023 16:31:09 +1200 Subject: [PATCH 4/8] MNT Run module-standardiser --- .github/workflows/auto-tag.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml index 17712c8..32801df 100644 --- a/.github/workflows/auto-tag.yml +++ b/.github/workflows/auto-tag.yml @@ -3,6 +3,7 @@ on: push: tags: - '*.*.*' + workflow_dispatch: jobs: auto-tag: name: Auto-tag From 7fe73a4356ae551186de2cac467165676307631c Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Mon, 28 Aug 2023 16:02:02 +1200 Subject: [PATCH 5/8] MNT Delete old ci.yml --- .github/workflows/ci.yml | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index e635dfc..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: CI - -on: - push: - pull_request: - workflow_dispatch: - -jobs: - ci: - name: CI - runs-on: ubuntu-latest - steps: - - - name: Checkout code - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - - name: Install PHP - uses: shivammathur/setup-php@1a18b2267f80291a81ca1d33e7c851fe09e7dfc4 # v2.22.0 - with: - php-version: 8.1 - - - name: Install PHPUnit - run: wget https://phar.phpunit.de/phpunit-9.5.phar - - - name: PHPUnit - run: php phpunit-9.5.phar --verbose --colors=always From cb174df1762ce972117dfb9db9c34dc89640d062 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Mon, 28 Aug 2023 16:19:54 +1200 Subject: [PATCH 6/8] FIX Delete __composer.json if composer.json does not exist on repository --- action.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 34be01f..cdc3eb5 100644 --- a/action.yml +++ b/action.yml @@ -72,7 +72,10 @@ runs: fi # Download composer.json for use in branches.php - curl -s -o __composer.json https://raw.githubusercontent.com/$GITHUB_REPOSITORY/$DEFAULT_BRANCH/composer.json + RESP_CODE=$(curl -w %{http_code} -s -o __composer.json https://raw.githubusercontent.com/$GITHUB_REPOSITORY/$DEFAULT_BRANCH/composer.json) + if [[ $RESP_CODE != 200 ]]; then + rm __composer.json + fi BRANCHES=$(MINIMUM_CMS_MAJOR=$MINIMUM_CMS_MAJOR DEFAULT_BRANCH=$DEFAULT_BRANCH GITHUB_REPOSITORY=$GITHUB_REPOSITORY php ${{ github.action_path }}/branches.php) echo "BRANCHES is $BRANCHES" @@ -88,7 +91,9 @@ runs: echo "branches=$BRANCHES" >> $GITHUB_OUTPUT rm __tags.json rm __branches.json - rm __composer.json + if [[ -f __composer.json ]]; then + rm __composer.json + fi # Check to see if there is anything to merge-up using the GitHub API # Another approach is to see if we should merged using git, however that approach requires us to From 46e9d901e78f73f17a051dbca4f25e562c53919d Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Mon, 28 Aug 2023 18:44:31 +1200 Subject: [PATCH 7/8] FIX Add conditional before adding --- funcs.php | 4 +++- tests/BranchesTest.php | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/funcs.php b/funcs.php index 1411eef..428379b 100644 --- a/funcs.php +++ b/funcs.php @@ -60,7 +60,9 @@ function branches( } if (!$version) { $version = preg_replace('#[^0-9\.]#', '', $json->require->{'silverstripe/assets'} ?? ''); - $matchedOnBranchThreeLess = true; + if ($version) { + $matchedOnBranchThreeLess = true; + } } if (!$version) { $version = preg_replace('#[^0-9\.]#', '', $json->require->{'cwp/starter-theme'} ?? ''); diff --git a/tests/BranchesTest.php b/tests/BranchesTest.php index e633f5b..eb1a878 100644 --- a/tests/BranchesTest.php +++ b/tests/BranchesTest.php @@ -357,6 +357,10 @@ public function provideBranches() EOT, 'branchesJson' => << Date: Thu, 31 Aug 2023 09:51:27 +1200 Subject: [PATCH 8/8] ENH Allow require-dev changes in composer.json --- action.yml | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index cdc3eb5..8054b4f 100644 --- a/action.yml +++ b/action.yml @@ -124,14 +124,51 @@ runs: FILES=$(jq -r .files[].filename __compare.json) rm __compare.json - # Don't allow merge-ups when there are changes in dependency files - DEPENDENCY_FILES="composer.json package.json yarn.lock" + # Don't allow merge-ups when there are changes in javascript dependency files + DEPENDENCY_FILES="package.json yarn.lock" for DEPENDENCY_FILE in $DEPENDENCY_FILES; do if [[ $(echo "$FILES" | grep $DEPENDENCY_FILE) != "" ]]; then - echo "Unable to mergeup between $FROM_BRANCH and $INTO_BRANCH - there are changes in $DEPENDENCY_FILE" + echo "Unable to mergeup $FROM_BRANCH into $INTO_BRANCH - there are changes in $DEPENDENCY_FILE" exit 1 fi done + + # Don't allow merge-ups where the are changes composer.json, unless the only changes are in "require-dev" + if [[ $(echo "$FILES" | grep composer.json) != "" ]]; then + RESP_CODE=$(curl -w %{http_code} -s -o __composer_from.json https://raw.githubusercontent.com/$GITHUB_REPOSITORY/$FROM_BRANCH/composer.json) + if [[ $RESP_CODE != 200 ]]; then + echo "Unable to download composer.json for branch $FROM_BRANCH - HTTP response code was $RESP_CODE" + exit 1 + fi + RESP_CODE=$(curl -w %{http_code} -s -o __composer_into.json https://raw.githubusercontent.com/$GITHUB_REPOSITORY/$INTO_BRANCH/composer.json) + if [[ $RESP_CODE != 200 ]]; then + echo "Unable to download composer.json for branch $INTO_BRANCH - HTTP response code was $RESP_CODE" + exit 1 + fi + CAN_MERGE_UP_COMPOSER_JSON=$(php -r ' + $from = json_decode(file_get_contents("__composer_from.json"), true); + $into = json_decode(file_get_contents("__composer_into.json"), true); + if (!$from) { + throw new Exception("Could not parse __composer_from.json - " . json_last_error_msg()); + } + if (!$into) { + throw new Exception("Could not parse __composer_into.json - " . json_last_error_msg()); + } + if (array_key_exists("require-dev", $from)) { + unset($from["require-dev"]); + } + if (array_key_exists("require-dev", $into)) { + unset($into["require-dev"]); + } + echo json_encode($from) === json_encode($into) ? "1" : "0"; + ') + rm __composer_from.json + rm __composer_into.json + if [[ $CAN_MERGE_UP_COMPOSER_JSON == "0" ]]; then + echo "Unable to mergeup $FROM_BRANCH into $INTO_BRANCH - there are non require-dev changes in composer.json" + exit 1 + fi + fi done # actions/checkout with fetch-depth: 0 will fetch ALL git history for the repository