ci: add Jenkins PR workflow #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |