Skip to content

ci: add Jenkins PR workflow #10

ci: add Jenkins PR workflow

ci: add Jenkins PR workflow #10

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