-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: CI/CD Pipelines #259
Changes from 250 commits
2e760c5
b009a77
0fc137a
c991efa
cea08eb
aba10b2
eea5bc4
4544c4d
c86c788
4a47a75
b27d092
493880e
abdd1b0
54b4846
3f81e03
80d2887
109443a
d48de2b
833f6da
87445f2
99bae41
5bdc648
b29c93b
7ea6480
4fe3c48
8c0ddaf
c64fc23
febc0fa
999ea48
6e798bb
6885fdd
d99573b
8650d0d
ff1b5db
34cae62
50ec688
5324531
ec37356
4552cb5
5ab7bc5
e513bef
04d9fb9
628be60
9545572
942f442
0226a98
fb610cc
6812b08
e53adb9
921d32c
35798ce
d2fee40
b0d7836
447d14c
1d95e27
b57e636
adf4355
b32900d
618c3c3
2bbb146
4098b54
363c4e1
ca3c69c
9541128
87ad04f
44dc956
0251374
4feb237
fcb9a8b
c638386
0486d6c
1b8cbc1
e65acef
88aacb0
96b9191
1bbc488
08b4609
00eeb08
36a50ef
f69580f
d73540c
f5e808c
7341a2d
1b6ff6b
c89604b
322099f
98b5dd1
4ed3306
914f9e4
e78f61e
e3bacb3
7297fae
faa1cb7
2fcf400
66c5380
aa65ab5
be947f0
919aab4
536ca65
c419666
4e20f38
1e373f2
7a560e6
d8f280e
e830b24
4399607
2f14816
fdab7ad
9f71431
89a1c96
1ac4603
56497a3
7b68f97
7872bbe
18ef7b3
a60246f
5c7d579
39b3ecb
cea5777
96b5a19
7ec53c5
98cc1e1
3ae6e21
79cd298
eba050d
fc69dab
9676df5
a0dbdad
37dc952
bbe715b
ec98db1
6351aa0
38b9fd3
b99d1fb
30cc246
03f0938
48a7fe8
93b66d2
1e7c6d1
2e515d4
42fd988
6303e9e
44be1ca
3b09317
becfada
ecbbcb5
2d6a793
6e74b66
892c525
26a1ad1
50c5b2e
7ea2aae
3ece317
0dc8fe9
62bfd52
f662f92
eb44f6f
1c61f79
630af3f
384afa9
a05e544
be37547
f20c830
34e7b0b
9caf68d
1caa8f5
508ccaf
fbe3f28
c0e1110
4784e24
83a24b8
1592037
5bad446
c27aab3
4fc9a0a
c47cc6b
45def33
a8d9c0e
480a887
1f5c93d
f0158a2
2fc3ec3
a0070e3
ef0125f
ce94fc8
44f6423
ba09748
a603da7
b5a55c9
ae829fe
db5438c
c35a0a6
d5c9b1b
50db757
a1dc29b
fb1cce3
ef14c40
90aabaf
8dacf4f
c87e69b
7782b80
7a2a571
38becb0
489378b
cfe6e36
86350e9
c07579f
ced9c44
46bc064
16f5928
08b704e
17db073
3cc4f98
d8a913d
cfb86c6
19e4e1f
e27d2e5
e135b37
912db4d
838fd38
a405f93
6bc14bf
432f48b
008a4cc
8f32e1a
b51acbf
5f66e3b
9218d73
3a2a1f9
93d9b56
b811247
aa2f13e
448f005
f2b2cf2
488b763
f968654
5c1f167
ede7e86
2f9ee0e
fc446db
36646a2
d65214e
7cfa6eb
6ae759d
37234ac
6a0e801
e284482
fecb65b
897dbf9
e3ae4ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
name: "Await Workflow" | ||
description: "Waits until a workflow run completes." | ||
|
||
inputs: | ||
run-id: | ||
description: "The id of the workflow run to wait for." | ||
required: true | ||
poll-interval: | ||
description: "The interval (in seconds) to poll for the workflow run status." | ||
required: false | ||
default: "60" | ||
commit-status: | ||
description: "The commit status message. Leave empty to not create a commit status." | ||
required: false | ||
|
||
outputs: | ||
succeeded: | ||
description: "Whether the triggered run succeeded." | ||
value: ${{ steps.wait-for-workflow.outputs.RUN_SUCCEEDED }} | ||
conclusion: | ||
description: "The conclusion of the triggered workflow run." | ||
value: ${{ steps.wait-for-workflow.outputs.CONCLUSION }} | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Print Action Input | ||
run: | | ||
echo "[DEBUG] Starting 'Await Workflow' Action; inputs = ${{ toJson(inputs) }}" | ||
shell: bash | ||
|
||
- name: View Run | ||
if: ${{ inputs.commit-status != '' }} | ||
id: view-run | ||
env: | ||
GH_TOKEN: ${{ github.token }} | ||
run: | | ||
JSON=$(gh run view ${{ inputs.run-id }} --json url,headSha) | ||
echo "URL=$(echo $JSON | jq -r '.url')" >> $GITHUB_OUTPUT | ||
echo "HEAD_SHA=$(echo $JSON | jq -r '.headSha')" >> $GITHUB_OUTPUT | ||
shell: bash | ||
|
||
- name: Create Commit Status | ||
if: ${{ inputs.commit-status != '' }} | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
github.rest.repos.createCommitStatus({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
sha: '${{ steps.view-run.outputs.HEAD_SHA }}', | ||
state: 'pending', | ||
target_url: '${{ steps.view-run.outputs.URL }}', | ||
context: '${{ inputs.commit-status }}' | ||
}) | ||
|
||
- name: Wait for Workflow to Complete | ||
id: wait-for-workflow | ||
env: | ||
GH_TOKEN: ${{ github.token }} | ||
run: | | ||
echo "[DEBUG] Waiting for run '${{ inputs.run-id }}' to complete..." | ||
gh run watch ${{ inputs.run-id }} --interval ${{ inputs.poll-interval }} > /dev/null | ||
CONCLUSION=$(gh run view ${{ inputs.run-id }} --json conclusion | jq -r '.conclusion') | ||
|
||
echo "CONCLUSION=$CONCLUSION" >> $GITHUB_OUTPUT | ||
echo "[DEBUG] Run '${{ inputs.run-id }}' finished with conclusion '$CONCLUSION'." | ||
|
||
if [[ "$CONCLUSION" != "success" ]]; then | ||
echo "RUN_SUCCEEDED=false" >> $GITHUB_OUTPUT | ||
exit 1 | ||
fi | ||
|
||
echo "RUN_SUCCEEDED=true" >> $GITHUB_OUTPUT | ||
shell: bash | ||
|
||
- name: Determine Final Commit Status | ||
id: determine-final-commit-status | ||
if: ${{ always() && inputs.commit-status != '' }} | ||
newtork marked this conversation as resolved.
Show resolved
Hide resolved
|
||
run: | | ||
if [[ "${{ steps.wait-for-workflow.outputs.CONCLUSION }}" == "success" ]]; then | ||
echo "FINAL_COMMIT_STATUS=success" >> $GITHUB_OUTPUT | ||
else | ||
echo "FINAL_COMMIT_STATUS=failure" >> $GITHUB_OUTPUT | ||
fi | ||
shell: bash | ||
|
||
- name: Update Commit Status | ||
if: ${{ always() && inputs.commit-status != '' }} | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
github.rest.repos.createCommitStatus({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
sha: '${{ steps.view-run.outputs.HEAD_SHA }}', | ||
state: '${{ steps.determine-final-commit-status.outputs.FINAL_COMMIT_STATUS }}', | ||
target_url: '${{ steps.view-run.outputs.URL }}', | ||
context: '${{ inputs.commit-status }}' | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
name: "Deploy Snapshot" | ||
description: "Deploys release artifacts produced by a given 'Continuous Integration' workflow to a provided SNAPSHOT repository." | ||
|
||
inputs: | ||
ci-run-id: | ||
description: "The run ID of the 'Continuous Integration' workflow that produced the release artifacts." | ||
required: true | ||
repository-url: | ||
description: "The URL of the repository to which the release artifacts should be deployed." | ||
required: true | ||
repository-username: | ||
description: "The username to use when authenticating with the repository." | ||
required: true | ||
repository-password: | ||
description: "The password to use when authenticating with the repository." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not too sure if this is safe to do. Maybe input parameters are logged in plaintext somewhere? Maybe just pass the name of the secret instead? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generally, it seems to be a "best practice" to pass around secrets like this But I'd still agree: As this is our own action, we don't need to pass around the actual secrets. Using the secret names should be sufficient 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, passing the secret names (instead of their actual values), doesn't work as it would require some sort of "nested GitHub macro extension" like so: - run: something
env:
GH_TOKEN: ${{ secrets.${{ inputs.secret-name}} }} This doesn't seem to be supported by GH actions. |
||
required: true | ||
release-artifact-name: | ||
description: "The name of the artifact to download from the 'Continuous Integration' workflow." | ||
required: false | ||
default: "release-artifacts" | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: "Print Action Start" | ||
run: echo ">>>>> Starting Deploy Snapshot Action" | ||
shell: bash | ||
|
||
- name: "Setup java" | ||
uses: actions/setup-java@v3 | ||
with: | ||
distribution: "temurin" | ||
java-version: "17" | ||
server-id: artifactory-snapshots | ||
server-username: ${{ inputs.repository-username }} | ||
server-password: ${{ inputs.repository-password }} | ||
|
||
- name: "Download Release Artifacts" | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: ${{ inputs.release-artifact-name }} | ||
github-token: ${{ github.token }} | ||
run-id: ${{ inputs.ci-run-id }} | ||
|
||
- name: "Publish Snapshot" | ||
run: > | ||
mvn | ||
--batch-mode | ||
--no-transfer-progress | ||
--fail-at-end | ||
--threads 1C | ||
-Durl=${{ inputs.repository-url }} | ||
-DrepositoryId=artifactory-snapshots | ||
-Dmaven.install.skip=true | ||
-Dmaven.test.skip | ||
-Dmaven.compiler.showCompilationChanges | ||
-Dhttp.keepAlive=false | ||
deploy | ||
shell: bash | ||
|
||
- name: "Print Action End" | ||
if: always() | ||
run: echo ">>>>> Finished Deploy Snapshot Action" | ||
shell: bash |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
name: "PR Is Mergeable" | ||
description: "Checks whether the provided PR is approved and all status checks either succeeded or have been skipped" | ||
|
||
inputs: | ||
pr-ref: | ||
description: "The reference (i.e. either number or a branch) of the PR to check" | ||
required: true | ||
fail-on-unmergeable: | ||
description: "Whether to fail the action if the PR is not mergeable" | ||
required: false | ||
default: "true" | ||
repo: | ||
description: "The repository of the PR" | ||
required: false | ||
default: ${{ github.repository }} | ||
token: | ||
description: "The GitHub access token (with PR read permissions) to access the PR" | ||
required: false | ||
default: ${{ github.token }} | ||
excluded-check-runs: | ||
description: "A comma-separated list of workflow names that are excluded from the Check Runs check" | ||
required: false | ||
default: ${{ github.workflow }} | ||
|
||
outputs: | ||
pr-number: | ||
description: "The number of the PR that was checked" | ||
value: ${{ steps.check.outputs.PR_NUMBER }} | ||
is-mergeable: | ||
description: "Whether the PR is mergeable" | ||
value: ${{ steps.check.outputs.RESULT }} | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: "Print Action Start" | ||
run: echo ">>>>> Starting PR Is Mergeable Action; inputs = ${{ toJson(inputs) }}" | ||
shell: bash | ||
|
||
- name: "Check Whether PR Is Mergeable" | ||
id: check | ||
run: | | ||
PR_JSON=$(gh pr view "${{ inputs.pr-ref }}" --repo "${{ inputs.repo }}" --json number,mergeable,reviewDecision,statusCheckRollup) | ||
|
||
PR_NUMBER=$(jq -r '.number' <<< "$PR_JSON") | ||
PR_MERGEABLE=$(jq -r '.mergeable' <<< "$PR_JSON") | ||
PR_DECISION=$(jq -r '.reviewDecision' <<< "$PR_JSON") | ||
|
||
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT | ||
echo "[DEBUG] PR #$PR_NUMBER (in ${{ inputs.repo }}) is mergeable: $PR_MERGEABLE with decision $PR_DECISION" | ||
|
||
if [[ "$PR_DECISION" != "APPROVED" ]]; then | ||
echo "PR #$PR_NUMBER (in ${{ inputs.repo }}) has not been approved." | ||
echo "RESULT=false" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
|
||
if [[ "$PR_MERGEABLE" != "MERGEABLE" ]]; then | ||
echo "PR #$PR_NUMBER (in ${{ inputs.repo }}) is not mergeable (i.e. there are conflicts)." | ||
echo "RESULT=false" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
|
||
PR_CHECKS=$(jq -r '.statusCheckRollup' <<< "$PR_JSON") | ||
|
||
# check runs are things like our CI pipeline | ||
FAILED_CHECK_RUNS=$(jq -r '.[] | select(.__typename == "CheckRun" and .conclusion != "SUCCESS" and .conclusion != "NEUTRAL")' <<< "$PR_CHECKS") | ||
IFS=',' read -ra EXCLUDED_WORKFLOWS <<< "${{ inputs.excluded-check-runs }}" | ||
for EXCLUDED_WORKFLOW in "${EXCLUDED_WORKFLOWS[@]}"; do | ||
if [[ -z "$FAILED_CHECK_RUNS" ]]; then | ||
break | ||
fi | ||
|
||
FAILED_CHECK_RUNS=$(jq -r 'select(.workflowName != "$EXCLUDED_WORKFLOW")' <<< "$FAILED_CHECK_RUNS") | ||
done | ||
|
||
if [[ -n "$FAILED_CHECK_RUNS" ]]; then | ||
echo "PR #$PR_NUMBER (in ${{ inputs.repo }}) contains failed check runs: " | ||
echo "$FAILED_CHECK_RUNS" | ||
echo "RESULT=false" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
|
||
# context checks are things like the license agreement check | ||
FAILED_CONTEXT_CHECKS=$(jq -r '.[] | select(.__typename == "StatusContext" and .state != "SUCCESS" and .state != "NEUTRAL")' <<< "$PR_CHECKS") | ||
if [[ -n "$FAILED_CONTEXT_CHECKS" ]]; then | ||
echo "PR #$PR_NUMBER (in ${{ inputs.repo }}) contains failed context checks: " | ||
echo "$FAILED_CONTEXT_CHECKS" | ||
echo "RESULT=false" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
|
||
echo "RESULT=true" >> $GITHUB_OUTPUT | ||
shell: bash | ||
env: | ||
GH_TOKEN: ${{ inputs.token }} | ||
|
||
- name: "Fail If PR Is Not Mergeable" | ||
if: ${{ inputs.fail-on-unmergeable == 'true' && steps.check.outputs.RESULT != 'true' }} | ||
run: exit 1 | ||
shell: bash | ||
|
||
- name: "Print Action End" | ||
if: always() | ||
run: echo "<<<<< Finished PR Is Mergeable Action" | ||
shell: bash |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
name: "Scan with BlackDuck" | ||
KavithaSiva marked this conversation as resolved.
Show resolved
Hide resolved
|
||
description: "Scans the project with BlackDuck" | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Print Action Start | ||
run: echo ">>>>> Starting Scan with BlackDuck Action; inputs = ${{ toJson(inputs) }}" | ||
shell: bash | ||
|
||
- name: Get Major Version | ||
id: get-major-version | ||
run: echo "MAJOR_VERSION=$(cat latest.json | jq -r .version | cut -d '.' -f 1)" >> $GITHUB_OUTPUT | ||
shell: bash | ||
|
||
- name: Determine Maven Excludes | ||
id: get-maven-excludes-for-blackduck | ||
run: python .pipeline/scripts/get-maven-excludes.py --filter-key excludeFromBlackDuckScan --filter-value True | ||
shell: bash | ||
newtork marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- name: BlackDuck Scan | ||
uses: SAP/project-piper-action@master | ||
Check warning on line 22 in .github/actions/scan-with-blackduck/action.yaml
|
||
newtork marked this conversation as resolved.
Show resolved
Hide resolved
|
||
with: | ||
command: detectExecuteScan | ||
flags: \ | ||
--version=$PROJECT_VERSION \ | ||
env: | ||
PIPER_token: ${{ secrets.BLACKDUCK_TOKEN }} | ||
DETECT_MAVEN_EXCLUDED_MODULES: ${{ steps.get-maven-excludes-for-blackduck.outputs.EXCLUDES }} | ||
DETECT_MAVEN_BUILD_COMMAND: -pl ${{ steps.get-maven-excludes-for-blackduck.outputs.PREFIXED_EXCLUDES }} | ||
DETECT_TIMEOUT: "7200" | ||
PROJECT_VERSION: ${{ steps.get-major-version.outputs.MAJOR_VERSION }} | ||
|
||
- name: Print Action End | ||
if: always() | ||
run: echo "<<<<< Finished Scan with BlackDuck Action" | ||
shell: bash |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
name: "Trigger Workflow" | ||
description: "Triggers a workflow without waiting for it to complete." | ||
|
||
inputs: | ||
workflow: | ||
description: "The workflow file name" | ||
required: true | ||
workflow-ref: | ||
description: "The ref (i.e. branch name, or tag name) where the workflow is located." | ||
required: true | ||
parameters: | ||
description: "The workflow parameters" | ||
required: false | ||
commit-sha: | ||
description: "The commit SHA to trigger the workflow on" | ||
required: false | ||
default: ${{ github.sha }} | ||
|
||
outputs: | ||
run-id: | ||
description: "The id of the workflow run that was triggered." | ||
value: ${{ steps.trigger-workflow.outputs.RUN_ID }} | ||
run-url: | ||
description: "The url of the workflow run that was triggered." | ||
value: ${{ steps.trigger-workflow.outputs.RUN_URL }} | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Print Action Input | ||
run: | | ||
echo "[DEBUG] Starting 'Trigger Workflow' Action; inputs = ${{ toJson(inputs) }}" | ||
shell: bash | ||
|
||
- name: Trigger Workflow | ||
id: trigger-workflow | ||
env: | ||
GH_TOKEN: ${{ github.token }} | ||
run: | | ||
PREVIOUS_RUN_ID=$(gh run list --workflow=${{ inputs.workflow}} --commit=${{ inputs.commit-sha }} --json databaseId | jq -r '.[0].databaseId') | ||
echo "[DEBUG] Previous run id = '$PREVIOUS_RUN_ID'" | ||
|
||
gh workflow run "${{ inputs.workflow }}" --ref "${{ inputs.workflow-ref }}" ${{ inputs.parameters }} | ||
# allow for some initial delay as workflows take a moment to spin up | ||
sleep 20 | ||
|
||
for i in {0..6}; do | ||
LATEST_RUN_ID=$(gh run list --workflow=${{ inputs.workflow }} --commit=${{ inputs.commit-sha }} --json databaseId | jq -r '.[0].databaseId') | ||
|
||
if [[ -z "$LATEST_RUN_ID" || "$LATEST_RUN_ID" == "$PREVIOUS_RUN_ID" ]]; then | ||
echo "[DEBUG] No new run detected. Waiting for 10 seconds." | ||
sleep 10 | ||
else | ||
echo "[DEBUG] New workflow run detected: '$LATEST_RUN_ID'." | ||
|
||
RUN_URL=$(gh run view $LATEST_RUN_ID --json url | jq -r '.url') | ||
echo "[DEBUG] ${{ inputs.workflow }} run #$LATEST_RUN_ID successfully triggered: $RUN_URL" | ||
echo "[${{ inputs.workflow }} run (#$LATEST_RUN_ID)]($RUN_URL)" >> $GITHUB_STEP_SUMMARY | ||
echo "RUN_ID=$LATEST_RUN_ID" >> $GITHUB_OUTPUT | ||
echo "RUN_URL=$RUN_URL" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
done | ||
|
||
echo "[DEBUG] Unable to detect new run of workflow '${{ inputs.workflow }}'." | ||
exit 1 | ||
shell: bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Minor/Nitpick)
Weird
echo "... $(echo ...)"
nesting, but I don't have an immediate suggestion.