.github: New PR Submit workflows

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.
This commit is contained in:
George Joseph
2023-10-17 06:59:43 -06:00
parent 2694792e13
commit 10204b9d31
3 changed files with 261 additions and 199 deletions

View File

@@ -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

148
.github/workflows/PRSubmitActions.yml vendored Normal file
View File

@@ -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;

113
.github/workflows/PRSubmitTests.yml vendored Normal file
View File

@@ -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