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