]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
.github: New PR Submit workflows
authorGeorge Joseph <gjoseph@sangoma.com>
Tue, 17 Oct 2023 12:59:43 +0000 (06:59 -0600)
committerGeorge Joseph <gjoseph@sangoma.com>
Tue, 17 Oct 2023 18:33:17 +0000 (12:33 -0600)
The workflows that get triggered when PRs are submitted or updated
have been replaced with ones that are more secure and have
a higher level of parallelism.

.github/workflows/PROpenedOrUpdated.yml [deleted file]
.github/workflows/PRSubmitActions.yml [new file with mode: 0644]
.github/workflows/PRSubmitTests.yml [new file with mode: 0644]

diff --git a/.github/workflows/PROpenedOrUpdated.yml b/.github/workflows/PROpenedOrUpdated.yml
deleted file mode 100644 (file)
index 84e2300..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-name: PROpenedOrUpdated
-run-name: "PR ${{github.event.number}} ${{github.event.action}} by ${{ github.actor }}"
-on:
-#  workflow_dispatch:
-  pull_request_target:
-#    types: [opened, reopened, synchronize]
-    types: [labeled]
-
-env:
-  ASTERISK_REPO:     ${{github.repository}}
-  PR_NUMBER:         ${{github.event.number}}
-  PR_COMMIT:         ${{github.event.pull_request.head.sha}}
-  BRANCH:            ${{github.event.pull_request.base.ref}}
-  GITHUB_TOKEN:      ${{secrets.GITHUB_TOKEN}}
-  MODULES_BLACKLIST: ${{vars.GATETEST_MODULES_BLACKLIST}} ${{vars.UNITTEST_MODULES_BLACKLIST}}
-
-jobs:
-
-  PRTestSetup:
-    if: ${{ github.event.label.name == vars.PR_ACCEPTANCE_TEST_LABEL }}
-    runs-on: ubuntu-latest
-    steps:
-      - name: Job Start Delay
-        env:
-          JOB_START_DELAY_SEC:       ${{vars.PR_JOB_START_DELAY_SEC}}
-        run: |
-          # Give the user a chance to add their "cherry-pick-to" comments
-          sleep ${JOB_START_DELAY_SEC:-60}
-
-      - name: Get Token needed to add reviewers
-        if: github.event.action == 'opened'
-        id: get_workflow_token
-        uses: peter-murray/workflow-application-token-action@v2
-        with:
-          application_id: ${{secrets.ASTERISK_ORG_ACCESS_APP_ID}}
-          application_private_key: ${{secrets.ASTERISK_ORG_ACCESS_APP_PRIV_KEY}}
-          organization: asterisk
-
-      - name: Get cherry-pick branches
-        uses: asterisk/asterisk-ci-actions/GetCherryPickBranchesFromPR@main
-        id: getbranches
-        with:
-          repo:                    ${{github.repository}}
-          pr_number:               ${{env.PR_NUMBER}}
-          cherry_pick_regex:       ${{vars.CHERRY_PICK_REGEX}}
-          github_token:            ${{secrets.GITHUB_TOKEN}}
-
-      - name: Add cherry-pick reminder
-        env:
-          GITHUB_TOKEN: ${{steps.get_workflow_token.outputs.token}}
-          GH_TOKEN: ${{steps.get_workflow_token.outputs.token}}
-          CHERRY_PICK_REMINDER: ${{vars.CHERRY_PICK_REMINDER}}
-          BRANCHES_OUTPUT: ${{toJSON(steps.getbranches.outputs)}}
-          BRANCH_COUNT: ${{steps.getbranches.outputs.branch_count}}
-          FORCED_NONE:  ${{steps.getbranches.outputs.forced_none}}
-        run: |
-          # If the user already added "cherry-pick-to" comments
-          # we don't need to remind them.
-          ( $FORCED_NONE || [ $BRANCH_COUNT -gt 0 ] ) && { echo "No reminder needed." ; exit 0 ; }
-          IFS=$'; \n'
-          # If there's already a reminder comment, don't add another one.
-          ADD_COMMENT=true
-          # This query will FAIL if it finds the comment.
-          gh pr view --repo ${{github.repository}} --json comments \
-            --jq '.comments[].body | select(. | startswith("<!--CPR-->")) | halt_error(1)' \
-            ${{env.PR_NUMBER}} >/dev/null 2>&1 || ADD_COMMENT=false
-          if $ADD_COMMENT ; then
-            echo "Adding CPR comment"
-            gh pr comment --repo ${{github.repository}} \
-              -b "${CHERRY_PICK_REMINDER}" ${{env.PR_NUMBER}}
-          else
-            echo "CPR comment already present"
-          fi
-
-      - name: Add reviewers
-        if: github.event.action == 'opened'
-        env:
-          GH_TOKEN: ${{steps.get_workflow_token.outputs.token}}
-          REVIEWERS: ${{vars.PR_REVIEWERS}}
-        run: |
-          IFS=$'; \n'
-          for r in $REVIEWERS ; do
-            echo "Adding reviewer $r"
-            gh pr edit --repo ${{github.repository}} ${PR_NUMBER} --add-reviewer $r || :
-          done
-
-      - name: Set Labels
-        env:
-          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          gh pr edit --repo ${{github.repository}} \
-            --remove-label ${{vars.TEST_CHECKS_PASSED_LABEL}} \
-            --remove-label ${{vars.TEST_CHECKS_FAILED_LABEL}} \
-            --remove-label ${{vars.TEST_GATES_PASSED_LABEL}} \
-            --remove-label ${{vars.TEST_GATES_FAILED_LABEL}} \
-            --remove-label ${{vars.CHERRY_PICK_CHECKS_PASSED_LABEL}} \
-            --remove-label ${{vars.CHERRY_PICK_CHECKS_FAILED_LABEL}} \
-            --remove-label ${{vars.CHERRY_PICK_GATES_PASSED_LABEL}} \
-            --remove-label ${{vars.CHERRY_PICK_GATES_FAILED_LABEL}} \
-            --remove-label ${{vars.PR_ACCEPTANCE_TEST_LABEL}} \
-            --add-label ${{vars.TESTING_IN_PROGRESS}} \
-            ${{env.PR_NUMBER}} || :
-
-  PRUnitTest:
-    needs: PRTestSetup
-    runs-on: ubuntu-latest
-    steps:
-      - name: Run Unit Tests
-        id: run_unit_tests
-        uses: asterisk/asterisk-ci-actions/AsteriskUnitComposite@main
-        with:
-          asterisk_repo:     ${{env.ASTERISK_REPO}}
-          pr_number:         ${{env.PR_NUMBER}}
-          base_branch:       ${{env.BRANCH}}
-          modules_blacklist: ${{env.MODULES_BLACKLIST}}
-          github_token:      ${{secrets.GITHUB_TOKEN}}
-          unittest_command:  ${{vars.UNITTEST_COMMAND}}
-        continue-on-error: true
-
-      - name: Post Unit Test
-        env:
-          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          CONCLUSION: ${{ steps.run_unit_tests.conclusion }}
-          OUTCOME:    ${{ steps.run_unit_tests.outcome }}
-        run: |
-          if [ "$OUTCOME" == "success" ] ; then
-            gh pr edit --repo ${{github.repository}} \
-              --add-label ${{vars.TEST_CHECKS_PASSED_LABEL}} \
-              ${{env.PR_NUMBER}} || :
-            exit 0
-          fi
-          gh pr edit --repo ${{github.repository}} \
-            --remove-label ${{vars.TESTING_IN_PROGRESS}} \
-            --add-label ${{vars.TEST_CHECKS_FAILED_LABEL}} \
-            ${{env.PR_NUMBER}} || :
-          exit 1
-
-  PRGateTestMatrix:
-    needs: PRUnitTest
-    continue-on-error: false
-    strategy:
-      fail-fast: false
-      matrix:
-        group: ${{ fromJSON(vars.GATETEST_LIST) }}
-    runs-on: ubuntu-latest
-    steps:
-      - id: runtest
-        name: Run Gate Tests for ${{ matrix.group }}
-        uses: asterisk/asterisk-ci-actions/AsteriskGateComposite@main
-        with:
-          test_type:         Gate
-          asterisk_repo:     ${{env.ASTERISK_REPO}}
-          pr_number:         ${{env.PR_NUMBER}}
-          base_branch:       ${{env.BRANCH}}
-          modules_blacklist: ${{env.MODULES_BLACKLIST}}
-          github_token:      ${{secrets.GITHUB_TOKEN}}
-          testsuite_repo:    ${{vars.TESTSUITE_REPO}}
-          gatetest_group:    ${{matrix.group}}
-          gatetest_commands: ${{vars.GATETEST_COMMANDS}}
-
-  PRPRGateTests:
-    if: ${{ always() && github.event.label.name == vars.PR_ACCEPTANCE_TEST_LABEL }}
-    runs-on: ubuntu-latest
-    needs: PRGateTestMatrix
-    steps:
-      - name: Check gate test matrix status
-        env:
-          RESULT: ${{ needs.PRGateTestMatrix.result }}
-          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          echo "all results: ${{ toJSON(needs.*.result) }}"
-          echo "composite result: $RESULT"
-
-          gh pr edit --repo ${{github.repository}} \
-            --remove-label ${{vars.TESTING_IN_PROGRESS}} \
-            ${{env.PR_NUMBER}} || :
-
-          case $RESULT in
-            success)
-              gh pr edit --repo ${{github.repository}} \
-                --add-label ${{vars.TEST_GATES_PASSED_LABEL}} \
-                ${{env.PR_NUMBER}} || :
-              echo "::notice::All Testsuite tests passed"
-              exit 0
-              ;;
-            skipped)
-              gh pr edit --repo ${{github.repository}} \
-                --add-label ${{vars.TEST_CHECKS_FAILED_LABEL}} \
-                ${{env.PR_NUMBER}} || :
-              echo "::error::Testsuite tests were skipped because of an earlier failure"
-              exit 1
-              ;;
-            *)
-              gh pr edit --repo ${{github.repository}} \
-                --add-label ${{vars.TEST_GATES_FAILED_LABEL}} \
-                ${{env.PR_NUMBER}} || :
-              echo "::error::One or more Testsuite tests failed ($RESULT)"
-              exit 1
-          esac
diff --git a/.github/workflows/PRSubmitActions.yml b/.github/workflows/PRSubmitActions.yml
new file mode 100644 (file)
index 0000000..fb58f19
--- /dev/null
@@ -0,0 +1,148 @@
+name: PRSubmitActions
+run-name: "PRSubmitActions: Test ${{github.event.action}}"
+on:
+  workflow_run:
+    workflows: [PRSubmitTests]
+    types:
+      - requested
+      - completed
+env:
+  ACTION:     ${{ github.event.action }}
+  CONCLUSION: ${{ github.event.workflow_run.conclusion }}
+  REPO:       ${{ github.repository }}
+
+jobs:
+  PRSubmitActions:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Get PR Number
+        id: getpr
+        uses: actions/github-script@v6
+        with:
+          retries: 5
+          script: |
+            let search = `repo:${context.repo.owner}/${context.repo.repo} ${context.payload.workflow_run.head_sha}`; 
+            let prs = await github.rest.search.issuesAndPullRequests({
+                 q: search,
+              });
+            if (prs.data.total_count == 0) {
+              core.setFailed(`Unable to get PR for ${context.payload.workflow_run.head_sha}`);
+              return;
+            }
+            let pr_number = prs.data.items[0].number;
+            core.setOutput('pr_number', pr_number);
+            return;
+
+      - name: Set Label
+        id: setlabel
+        uses: actions/github-script@v6
+        env:
+          PR_NUMBER:  ${{ steps.getpr.outputs.PR_NUMBER }}
+          LABEL_TIP:  ${{ vars.PR_SUBMIT_TESTING_IN_PROGRESS }}
+          LABEL_PASS: ${{ vars.PR_SUBMIT_TESTS_PASSED }}
+          LABEL_FAIL: ${{ vars.PR_SUBMIT_TESTS_FAILED }}
+        with:
+          retries: 5
+          script: |
+            let label;
+            if (process.env.ACTION === 'requested') {
+              label = process.env.LABEL_TIP;
+            } else {
+              if ( process.env.CONCLUSION === 'success' ) {
+                label = process.env.LABEL_PASS;
+              } else {
+                label = process.env.LABEL_FAIL;
+              }
+            }
+            core.info(`Setting label ${label}`);
+            github.rest.issues.setLabels({
+              issue_number: process.env.PR_NUMBER,
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              labels: [ label ]
+            });
+            return;
+
+      - name: Get cherry-pick branches
+        if: github.event.action == 'completed'
+        id: getbranches
+        uses: asterisk/asterisk-ci-actions/GetCherryPickBranchesFromPR@main
+        with:
+          repo:              ${{env.REPO}}
+          pr_number:         ${{steps.getpr.outputs.PR_NUMBER}}
+          cherry_pick_regex: ${{vars.CHERRY_PICK_REGEX}}
+          github_token:      ${{secrets.GITHUB_TOKEN}}
+
+      - name: Add cherry-pick reminder
+        if: github.event.action == 'completed'
+        uses: actions/github-script@v6
+        env:
+          PR_NUMBER:            ${{steps.getpr.outputs.PR_NUMBER}}
+          CHERRY_PICK_REMINDER: ${{vars.CHERRY_PICK_REMINDER}}
+          BRANCHES_OUTPUT:      ${{toJSON(steps.getbranches.outputs)}}
+          BRANCH_COUNT:         ${{steps.getbranches.outputs.branch_count}}
+          FORCED_NONE:          ${{steps.getbranches.outputs.forced_none}}
+        with:
+          retries: 5
+          script: |
+            if (process.env.FORCED_NONE === 'true' ||
+              process.env.BRANCH_COUNT > 0) {
+              core.info("No cherry-pick reminder needed.");
+              return;
+            }
+            let comments = await github.rest.issues.listComments({
+              issue_number: process.env.PR_NUMBER,
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+            });
+            let found = false;
+            for (const c of comments.data) {
+              if (c.body.startsWith("<!--CPR-->")) {
+                found = true;
+                break;
+              }
+            }
+            if (found) {
+              core.info("Cherry-pick reminder already exists.");
+              return;
+            }
+            core.info("Adding cherry-pick reminder.");
+            await github.rest.issues.createComment({
+              issue_number: process.env.PR_NUMBER,
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              body: process.env.CHERRY_PICK_REMINDER
+            })
+            return;
+
+      - name: Add reviewers
+        if: github.event.action == 'completed'
+        uses: actions/github-script@v6
+        env:
+          PR_NUMBER: ${{steps.getpr.outputs.PR_NUMBER}}
+          REVIEWERS: ${{vars.PR_REVIEWERS}}
+        with:
+          retries: 5
+          script: |
+            let rs = JSON.parse(process.env.REVIEWERS);
+            let users = [];
+            let teams = [];
+            for (const r of rs) {
+              if (r.indexOf("/") > 0) {
+                teams.push(r);
+              } else {
+                users.push(r);
+              }
+            }
+            if (teams.length > 0 || users.length > 0) {
+              core.info(`Adding user reviewers ${users}`);
+              core.info(`Adding team reviewers ${teams}`);
+              await github.pulls.requestReviewers({
+                pr_number: process.env.PR_NUMBER,
+                owner: context.repo.owner,
+                repo: context.repo.repo,
+                reviewers: users,
+                team_reviewers: teams
+              });
+            }
+            return;
diff --git a/.github/workflows/PRSubmitTests.yml b/.github/workflows/PRSubmitTests.yml
new file mode 100644 (file)
index 0000000..bcf6e79
--- /dev/null
@@ -0,0 +1,113 @@
+name: PRSubmitTests
+run-name: "PR ${{github.event.number}} ${{github.event.action}} by ${{ github.actor }}"
+on:
+  pull_request:
+    types: [opened, reopened, synchronize]
+
+concurrency:
+  group: ${{github.workflow}}-${{github.event.number}}
+  cancel-in-progress: true
+
+env:
+  ASTERISK_REPO:     ${{github.repository}}
+  PR_NUMBER:         ${{github.event.number}}
+  PR_COMMIT:         ${{github.event.pull_request.head.sha}}
+  BRANCH:            ${{github.event.pull_request.base.ref}}
+
+jobs:
+#
+# Pull requests created from forked respositories don't have access to
+# the "Action Variables" ('vars' context) so we need to retrieve control
+# data from an action.
+#
+  PRSGetControlData:
+    runs-on: ubuntu-latest
+    outputs:
+      control_data:  ${{ steps.setvars.outputs.control_data }}
+    steps:
+      - id: setvars
+        uses: asterisk/asterisk-ci-actions/GetRepoControlData@main
+        with:
+          repo: ${{ github.event.repository.name}}
+      - name: DumpEnvironment
+        uses: asterisk/asterisk-ci-actions/DumpEnvironmentAction@main
+        with:
+          action-inputs: ${{toJSON(inputs)}}
+          action-vars: ${{ toJSON(steps.setvars.outputs) }}
+
+  PRSUnitTests:
+    needs: PRSGetControlData
+    runs-on: ubuntu-latest
+    env:
+      UNITTEST_COMMAND: ${{ fromJSON(needs.PRSGetControlData.outputs.control_data).UNITTEST_COMMAND }}
+    steps:
+      - name: Run Unit Tests
+        uses: asterisk/asterisk-ci-actions/AsteriskUnitComposite@main
+        with:
+          asterisk_repo:     ${{env.ASTERISK_REPO}}
+          pr_number:         ${{env.PR_NUMBER}}
+          base_branch:       ${{env.BRANCH}}
+          unittest_command:  ${{env.UNITTEST_COMMAND}}
+
+  PRSGateTestMatrix:
+    needs: PRSGetControlData
+    env:
+      TESTSUITE_REPO:    "${{ fromJSON(needs.PRSGetControlData.outputs.control_data).TESTSUITE_REPO }}"
+      GATETEST_COMMANDS: "${{ fromJSON(needs.PRSGetControlData.outputs.control_data).GATETEST_COMMANDS }}"
+    continue-on-error: false
+    strategy:
+      fail-fast: false
+      matrix:
+        group: ${{ fromJSON(fromJSON(needs.PRSGetControlData.outputs.control_data).GATETEST_LIST) }}
+    runs-on: ubuntu-latest
+    steps:
+      - id: runtest
+        name: Run Gate Tests for ${{ matrix.group }}
+        uses: asterisk/asterisk-ci-actions/AsteriskGateComposite@main
+        with:
+          test_type:         Gate
+          asterisk_repo:     ${{env.ASTERISK_REPO}}
+          pr_number:         ${{env.PR_NUMBER}}
+          base_branch:       ${{env.BRANCH}}
+          testsuite_repo:    ${{env.TESTSUITE_REPO}}
+          gatetest_group:    ${{matrix.group}}
+          gatetest_commands: ${{env.GATETEST_COMMANDS}}
+
+  PRSTestResults:
+    if: always()
+    runs-on: ubuntu-latest
+    needs: [PRSUnitTests,PRSGateTestMatrix]
+    steps:
+      - name: Check test matrix status
+        env:
+          RESULT_UNIT: ${{ needs.PRSUnitTests.result }}
+          RESULT_GATE: ${{ needs.PRSGateTestMatrix.result }}
+        run: |
+          declare -i rc=0
+          echo "all results: ${{ toJSON(needs.*.result) }}"
+          case $RESULT_UNIT in
+            success)
+              echo "::notice::Unit tests passed"
+              ;;
+            skipped)
+              echo "::error::Unit tests were skipped because of an earlier failure"
+              rc+=1
+              ;;
+            *)
+              echo "::error::One or more unit tests failed ($RESULT_UNIT)"
+              rc+=1
+          esac
+          case $RESULT_GATE in
+            success)
+              echo "::notice::Gate tests passed"
+              ;;
+            skipped)
+              echo "::error::Gate tests were skipped because of an earlier failure"
+              rc+=1
+              ;;
+            *)
+              echo "::error::One or more gate tests failed ($RESULT_GATE)"
+              rc+=1
+          esac
+          echo "::notice::Final result code: $rc"
+          exit $rc