-
Notifications
You must be signed in to change notification settings - Fork 68
157 lines (142 loc) · 6.12 KB
/
build-pull-request-jenkins.yml
File metadata and controls
157 lines (142 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
name: Build Pull Request Jenkins
on:
pull_request:
paths-ignore:
- '.github/**'
- 'docs/**'
- '!.github/workflows/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: read
jobs:
jenkins-ci-docker:
runs-on: ubuntu-latest
env:
JENKINS_URL: ${{ vars.JENKINS_URL || 'https://starjenkins.sdcc.bnl.gov' }}
JENKINS_JOB: ${{ vars.JENKINS_JOB || 'star-sw-ci-pipeline' }}
JENKINS_USER: ${{ secrets.JENKINS_USER }}
JENKINS_TOKEN: ${{ secrets.JENKINS_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
BRANCH_NAME: ${{ github.event.pull_request.head.ref }}
GIT_COMMIT: ${{ github.event.pull_request.head.sha }}
REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }}
steps:
- name: Validate Jenkins configuration
run: |
set -euo pipefail
for var in JENKINS_URL JENKINS_JOB JENKINS_USER JENKINS_TOKEN PR_NUMBER BRANCH_NAME GIT_COMMIT REPO_URL; do
if [ -z "${!var:-}" ]; then
echo "::error::Missing required value for ${var}"
exit 1
fi
done
- name: Fetch Jenkins crumb
id: crumb
run: |
set -euo pipefail
curl_auth="${JENKINS_USER}:${JENKINS_TOKEN}"
crumb="$(curl --silent --show-error --fail --retry 3 --retry-all-errors --user "$curl_auth" \
"${JENKINS_URL}/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)")"
echo "::add-mask::$crumb"
echo "value=$crumb" >> "$GITHUB_OUTPUT"
- name: Cancel older Jenkins builds for this PR
env:
JENKINS_CRUMB: ${{ steps.crumb.outputs.value }}
run: |
set -euo pipefail
curl_auth="${JENKINS_USER}:${JENKINS_TOKEN}"
build_api="${JENKINS_URL}/job/${JENKINS_JOB}/api/json?tree=builds[number,url,building,actions[parameters[name,value]]]"
queue_api="${JENKINS_URL}/queue/api/json?tree=items[id,task[name],actions[parameters[name,value]]]"
running_builds="$(
curl --silent --show-error --fail --retry 3 --retry-all-errors --user "$curl_auth" "$build_api" |
jq -r --arg pr "$PR_NUMBER" --arg branch "$BRANCH_NAME" --arg repo "$REPO_URL" '
def param($name): ([.actions[]?.parameters[]? | select(.name == $name) | (.value | tostring)][0] // "");
.builds[]?
| select(.building == true)
| select(
(param("PR_NUMBER") != "" and param("PR_NUMBER") == $pr)
or
(param("PR_NUMBER") == "" and param("BRANCH_NAME") == $branch and param("REPO_URL") == $repo)
)
| .url
'
)"
queued_items="$(
curl --silent --show-error --fail --retry 3 --retry-all-errors --user "$curl_auth" "$queue_api" |
jq -r --arg job "$JENKINS_JOB" --arg pr "$PR_NUMBER" --arg branch "$BRANCH_NAME" --arg repo "$REPO_URL" '
def param($name): ([.actions[]?.parameters[]? | select(.name == $name) | (.value | tostring)][0] // "");
.items[]?
| select(.task.name == $job)
| select(
(param("PR_NUMBER") != "" and param("PR_NUMBER") == $pr)
or
(param("PR_NUMBER") == "" and param("BRANCH_NAME") == $branch and param("REPO_URL") == $repo)
)
| .id
'
)"
if [ -n "$queued_items" ]; then
while IFS= read -r item_id; do
[ -n "$item_id" ] || continue
echo "Canceling queued Jenkins item ${item_id}"
curl --silent --show-error --fail \
--request POST \
--retry 3 \
--retry-all-errors \
--user "$curl_auth" \
--header "$JENKINS_CRUMB" \
--output /dev/null \
"${JENKINS_URL}/queue/cancelItem?id=${item_id}"
done <<< "$queued_items"
fi
if [ -n "$running_builds" ]; then
while IFS= read -r build_url; do
[ -n "$build_url" ] || continue
echo "Stopping running Jenkins build ${build_url}"
curl --silent --show-error --fail \
--request POST \
--retry 3 \
--retry-all-errors \
--user "$curl_auth" \
--header "$JENKINS_CRUMB" \
--output /dev/null \
"${build_url}stop"
done <<< "$running_builds"
fi
- name: Trigger Jenkins docker job
env:
JENKINS_CRUMB: ${{ steps.crumb.outputs.value }}
run: |
set -euo pipefail
curl_auth="${JENKINS_USER}:${JENKINS_TOKEN}"
response_headers="$(mktemp)"
curl --silent --show-error --fail \
--request POST \
--retry 3 \
--retry-all-errors \
--user "$curl_auth" \
--header "$JENKINS_CRUMB" \
--data-urlencode "PR_NUMBER=${PR_NUMBER}" \
--data-urlencode "BRANCH_NAME=${BRANCH_NAME}" \
--data-urlencode "GIT_COMMIT=${GIT_COMMIT}" \
--data-urlencode "REPO_URL=${REPO_URL}" \
--dump-header "$response_headers" \
--output /dev/null \
"${JENKINS_URL}/job/${JENKINS_JOB}/buildWithParameters"
queue_url="$(awk 'BEGIN {IGNORECASE=1} /^Location:/ {print $2}' "$response_headers" | tr -d '\r')"
echo "Triggered Jenkins job ${JENKINS_JOB} for ${BRANCH_NAME}@${GIT_COMMIT}"
if [ -n "$queue_url" ]; then
echo "Queue item: ${queue_url}"
{
echo "### Jenkins Triggered"
echo
echo "- Job: \`${JENKINS_JOB}\`"
echo "- Pull request: \`${PR_NUMBER}\`"
echo "- Branch: \`${BRANCH_NAME}\`"
echo "- Commit: \`${GIT_COMMIT}\`"
echo "- Queue item: ${queue_url}"
} >> "$GITHUB_STEP_SUMMARY"
fi