Last active
March 31, 2022 08:32
-
-
Save sonodar/667a142158ecfae3f5213e1213ea161d to your computer and use it in GitHub Desktop.
Wait for AWS CodeBuild jobs to complete while also outputting logs
This file contains 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
#!/bin/bash | |
# aws-cli, jq, GNU-sed are required | |
set -euC -o pipefail | |
# Shortcut for get-log-events command. | |
get_log_events() { | |
local cmdArgs="--start-from-head --limit 100 --log-group-name ${1} --log-stream-name ${2}" | |
[[ -n ${3:-} ]] && cmdArgs="${cmdArgs} --next-token ${3}" | |
aws logs get-log-events ${cmdArgs} | |
} | |
# Since a log stream is created for each job, there is no problem with outputting all the logs in the stream. | |
print_log_events() { | |
local logEvents=$(get_log_events "${1}" "${2}" "${3:-}") | |
# Escape newlines so that they do not disappear when `echo` is executed. | |
local messages=$(echo "${logEvents}" | jq -r .events[].message | sed -z 's/\n\+/\\n/g') | |
# The `nextForwardToken` will have a value whether or not the next log is present. | |
local nextToken=$(echo "${logEvents}" | jq -r .nextForwardToken) | |
# Log output to the end will be `events: []`. Therefore, the message will be an empty string. | |
while [[ -n ${messages} ]]; do | |
echo -e "${messages}" | |
logEvents=$(get_log_events "${1}" "${2}" "${nextToken}") | |
messages=$(echo "${logEvents}" | jq -r .events[].message | sed -z 's/\n\+/\\n/g') | |
nextToken=$(echo "${logEvents}" | jq -r .nextForwardToken) | |
done | |
} | |
get_current_build_status_and_print_logs() { | |
local buildStatus=$(aws codebuild batch-get-builds --ids "${1}" | jq .builds[0]) | |
local logGroup=$(echo "${buildStatus}" | jq -r .logs.groupName) | |
local logStream=$(echo "${buildStatus}" | jq -r .logs.streamName) | |
if [[ ${logGroup} != "null" ]] && [[ ${logStream} != "null" ]]; then | |
print_log_events "${logGroup}" "${logStream}" >&2 | |
fi | |
echo "${buildStatus}" | |
} | |
wait_for_build_complete() { | |
local id=${1} | |
declare -i timeoutTime=$(date -d "${2:-900} seconds" +%s) | |
while true; do | |
buildStatus=$(get_current_build_status_and_print_logs "${id}") | |
isCompleted=$(echo "${buildStatus}" | jq -r .buildComplete) | |
currentStatus=$(echo "${buildStatus}" | jq -r .buildStatus) | |
if [[ ${isCompleted} == "true" ]]; then | |
echo "${currentStatus}" | |
[[ ${currentStatus} != "SUCCEEDED" ]] || return 1 | |
return 0 | |
fi | |
if [[ $(date +%s) -ge ${timeoutTime} ]]; then | |
echo "Waiting for build completion timed out" >&2 | |
return 124 | |
fi | |
sleep 10s | |
done | |
} | |
wait_for_build_complete "${@}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment