b0170ee03dd7ba2ad445207660d2bd313a775f62
configuration/github-download-workflow-artifacts.sh
| ... | ... | @@ -1,8 +1,9 @@ |
| 1 | 1 | #!/bin/bash |
| 2 | -# Call with two arguments: |
|
| 2 | +# Call with three arguments: |
|
| 3 | 3 | # - the name of the branch for which you would like |
| 4 | 4 | # to download the latest workflow run's build artifacts |
| 5 | 5 | # - the Github PAT (personal access token) |
| 6 | +# - the Github repository {owner}/{repo}, such as SAP/sailing-analytics |
|
| 6 | 7 | # If found, the build.log.zip and test-result.zip files |
| 7 | 8 | # will be downloaded to the current working directory. |
| 8 | 9 | # The script will exit with status 0 if the workflow's |
| ... | ... | @@ -21,21 +22,64 @@ HEADERS_FILE=$( mktemp headersXXXXX ) |
| 21 | 22 | NEXT_PAGE="https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs?created=${DATE_YESTERDAY/+/%2B}..${UNIX_DATE/+/%2B}&per_page=100" |
| 22 | 23 | ARTIFACTS_JSON="" |
| 23 | 24 | LATEST_RUN_STARTED_AT="0000-00-00T00:00:00Z" |
| 25 | + |
|
| 26 | +# Function to check a workflow run and all its previous attempts |
|
| 27 | +# Arguments: $1 = workflow run JSON |
|
| 28 | +# Sets LAST_WORKFLOW_FOR_BRANCH and LATEST_RUN_STARTED_AT if a better match is found |
|
| 29 | +check_run_and_previous_attempts() { |
|
| 30 | + local RUN_JSON="${1}" |
|
| 31 | + local CURRENT_RUN="${RUN_JSON}" |
|
| 32 | + |
|
| 33 | + while [ -n "${CURRENT_RUN}" ] && [ "${CURRENT_RUN}" != "null" ]; do |
|
| 34 | + local RUN_STATUS=$( echo "${CURRENT_RUN}" | jq -r '.status' ) |
|
| 35 | + local RUN_NAME=$( echo "${CURRENT_RUN}" | jq -r '.name' ) |
|
| 36 | + local RUN_HEAD_BRANCH=$( echo "${CURRENT_RUN}" | jq -r '.head_branch' ) |
|
| 37 | + |
|
| 38 | + # Check if this run matches our criteria |
|
| 39 | + if [ "${RUN_STATUS}" == "completed" ] && [ "${RUN_NAME}" == "release" ]; then |
|
| 40 | + if [[ "${RUN_HEAD_BRANCH}" == ${BRANCH}* ]] || [[ "${RUN_HEAD_BRANCH}" == releases/${BRANCH}* ]]; then |
|
| 41 | + local RUN_STARTED_AT=$( echo "${CURRENT_RUN}" | jq -r '.run_started_at' ) |
|
| 42 | + echo "Found completed run (or previous attempt) started at ${RUN_STARTED_AT}" |
|
| 43 | + if [[ "${RUN_STARTED_AT}" > "${LATEST_RUN_STARTED_AT}" ]]; then |
|
| 44 | + echo "This is later than the latest run so far (${LATEST_RUN_STARTED_AT})" |
|
| 45 | + LAST_WORKFLOW_FOR_BRANCH="${CURRENT_RUN}" |
|
| 46 | + LATEST_RUN_STARTED_AT="${RUN_STARTED_AT}" |
|
| 47 | + fi |
|
| 48 | + fi |
|
| 49 | + fi |
|
| 50 | + # Check for previous attempt |
|
| 51 | + local PREVIOUS_ATTEMPT_URL=$( echo "${CURRENT_RUN}" | jq -r '.previous_attempt_url // empty' ) |
|
| 52 | + if [ -n "${PREVIOUS_ATTEMPT_URL}" ]; then |
|
| 53 | + echo "Checking previous attempt at ${PREVIOUS_ATTEMPT_URL} ..." |
|
| 54 | + CURRENT_RUN=$( curl --silent -L -H 'Authorization: Bearer '${BEARER_TOKEN} "${PREVIOUS_ATTEMPT_URL}" 2>/dev/null ) |
|
| 55 | + # Validate we got a proper response |
|
| 56 | + if [ -z "${CURRENT_RUN}" ] || [ "$( echo "${CURRENT_RUN}" | jq -r '.id // empty' )" == "" ]; then |
|
| 57 | + echo "Could not fetch previous attempt, stopping chain" |
|
| 58 | + break |
|
| 59 | + fi |
|
| 60 | + else |
|
| 61 | + break |
|
| 62 | + fi |
|
| 63 | + done |
|
| 64 | +} |
|
| 65 | + |
|
| 24 | 66 | # Now go through the pages as long as we have a non-empty NEXT_PAGE URL and find the completed "release" workflow that was started last |
| 25 | 67 | while [ -n "${NEXT_PAGE}" ]; do |
| 26 | 68 | echo "Trying page ${NEXT_PAGE} ..." |
| 27 | 69 | # Get the artifacts URL of the last workflow run triggered by a branch push for ${BRANCH}: |
| 28 | - LAST_WORKFLOW_FOR_BRANCH_ON_PAGE=$( curl -D "${HEADERS_FILE}" --silent -L -H 'Authorization: Bearer '${BEARER_TOKEN} "${NEXT_PAGE}" 2>/dev/null | jq -r '.workflow_runs | map(select(.status == "completed" and .name == "release" and ((.head_branch | startswith("'${BRANCH}'")) or (.head_branch | startswith("releases/'${BRANCH}'"))))) | sort_by(.updated_at) | reverse | .[0]' | sed -e '/^$/d' ) |
|
| 29 | - if [ -n "${LAST_WORKFLOW_FOR_BRANCH_ON_PAGE}" -a "${LAST_WORKFLOW_FOR_BRANCH_ON_PAGE}" != "null" ]; then |
|
| 30 | - RUN_STARTED_AT=$( echo "${LAST_WORKFLOW_FOR_BRANCH_ON_PAGE}" | jq -r '.run_started_at' ) |
|
| 31 | - echo "Found completed run started at ${RUN_STARTED_AT}" |
|
| 32 | - if [[ "${RUN_STARTED_AT}" > "${LATEST_RUN_STARTED_AT}" ]]; then |
|
| 33 | - echo "This is later than the latest run so far (${LATEST_RUN_STARTED_AT})" |
|
| 34 | - LAST_WORKFLOW_FOR_BRANCH="${LAST_WORKFLOW_FOR_BRANCH_ON_PAGE}" |
|
| 35 | - LATEST_RUN_STARTED_AT="${RUN_STARTED_AT}" |
|
| 36 | - fi |
|
| 70 | + NEXT_PAGE_CONTENTS=$( curl -D "${HEADERS_FILE}" --silent -L -H 'Authorization: Bearer '${BEARER_TOKEN} "${NEXT_PAGE}" 2>/dev/null ) |
|
| 71 | + # Get all workflow runs that match our branch criteria (completed or not, we'll check status in the function) |
|
| 72 | + MATCHING_RUNS=$( echo "${NEXT_PAGE_CONTENTS}" | jq -c '.workflow_runs | map(select(.name == "release" and ((.head_branch | startswith("'${BRANCH}'")) or (.head_branch | startswith("releases/'${BRANCH}'"))))) | .[]' 2>/dev/null ) |
|
| 73 | + if [ -n "${MATCHING_RUNS}" ]; then |
|
| 74 | + # Process each matching run |
|
| 75 | + while IFS= read -r RUN_JSON; do |
|
| 76 | + if [ -n "${RUN_JSON}" ] && [ "${RUN_JSON}" != "null" ]; then |
|
| 77 | + echo "Checking run and its previous attempts..." |
|
| 78 | + check_run_and_previous_attempts "${RUN_JSON}" |
|
| 79 | + fi |
|
| 80 | + done <<< "${MATCHING_RUNS}" |
|
| 37 | 81 | else |
| 38 | - echo "Found no completed run for branch ${BRANCH} on page" |
|
| 82 | + echo "Found no runs for branch ${BRANCH} on page" |
|
| 39 | 83 | fi |
| 40 | 84 | NEXT_PAGE=$( grep "^link: .*; rel=\"next\"" "${HEADERS_FILE}" | sed -e 's/^.*<\([^>]*\)>; rel="next".*$/\1/' ) |
| 41 | 85 | done |