74 lines
3.4 KiB
Bash
Executable File
74 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Run the checks declared in the manifest, record each result in DealSage, and
|
|
# stop the pipeline if a required check failed. Advisory checks never block.
|
|
#
|
|
# Every result is posted to record-app-check with the commit and branch, so
|
|
# DealSage can show checks per commit before a version exists and attach them
|
|
# to the version once it is allocated. A DealSage outage is a warning here, not
|
|
# a failure: the build should not be blocked by the dashboard being down.
|
|
set -euo pipefail
|
|
. "$(dirname "$0")/lib.sh"
|
|
require_env APP_ID CHECKS_JSON DEALSAGE_FUNCTIONS_URL PUBLISH_TOKEN SUPABASE_ANON_KEY
|
|
git_context
|
|
CHECKS_DIR="$(cd "$(dirname "$0")/../checks" && pwd)"
|
|
|
|
post_check() { # id name status required duration_ms summary logfile started finished
|
|
local payload
|
|
payload="$(jq -n \
|
|
--arg appId "$APP_ID" --arg sha "$COMMIT_SHA" --arg branch "$BRANCH" \
|
|
--arg id "$1" --arg name "$2" --arg status "$3" --argjson required "$4" \
|
|
--argjson duration "$5" --arg summary "$6" --rawfile log "$7" \
|
|
--arg started "$8" --arg finished "$9" \
|
|
'{appId:$appId, commitSha:$sha, branch:$branch, checkId:$id, name:$name, status:$status,
|
|
required:$required, durationMs:$duration, summary:$summary,
|
|
logTail:($log | split("\n") | .[-80:] | join("\n")), reportedBy:"ci",
|
|
startedAt:$started, finishedAt:$finished}')"
|
|
ds_post record-app-check "$payload" >/dev/null || warn "could not record check $1 in DealSage"
|
|
}
|
|
|
|
results='[]'
|
|
required_failed=()
|
|
count="$(jq 'length' <<<"$CHECKS_JSON")"
|
|
if [ "$count" = 0 ]; then
|
|
log "No checks declared in .dealsage/app.json"
|
|
persist_env CHECKS_RESULT_JSON '[]'
|
|
exit 0
|
|
fi
|
|
|
|
while IFS= read -r check; do
|
|
id="$(jq -r .id <<<"$check")"; name="$(jq -r .name <<<"$check")"
|
|
run="$(jq -r '.run // empty' <<<"$check")"; uses="$(jq -r '.uses // empty' <<<"$check")"
|
|
required="$(jq -r .required <<<"$check")"; timeout_min="$(jq -r .timeoutMinutes <<<"$check")"
|
|
logf="$(mktemp)"; started="$(iso_now)"; t0="$(now_ms)"
|
|
echo "::group::check: $name ($id)"
|
|
if [ -n "$uses" ]; then
|
|
printf '$ platform check %s\n' "$uses" | tee "$logf"
|
|
set +e; timeout "${timeout_min}m" bash "$CHECKS_DIR/$uses.sh" 2>&1 | tee -a "$logf"; rc=${PIPESTATUS[0]}; set -e
|
|
else
|
|
printf '$ %s\n' "$run" | tee "$logf"
|
|
set +e; timeout "${timeout_min}m" bash -o pipefail -c "$run" 2>&1 | tee -a "$logf"; rc=${PIPESTATUS[0]}; set -e
|
|
fi
|
|
echo "::endgroup::"
|
|
dur=$(( $(now_ms) - t0 ))
|
|
case "$rc" in
|
|
0) status=passed; summary="passed in $(( dur / 1000 ))s" ;;
|
|
124) status=error; summary="timed out after ${timeout_min} minutes" ;;
|
|
*) status=failed; summary="exit code $rc" ;;
|
|
esac
|
|
printf '%s: %s (%s)\n' "$name" "$status" "$summary"
|
|
post_check "$id" "$name" "$status" "$required" "$dur" "$summary" "$logf" "$started" "$(iso_now)"
|
|
results="$(jq -c --arg id "$id" --arg status "$status" --argjson d "$dur" --argjson req "$required" \
|
|
'. + [{id:$id, status:$status, durationMs:$d, required:$req}]' <<<"$results")"
|
|
if [ "$status" != passed ] && [ "$required" = true ]; then required_failed+=("$name"); fi
|
|
rm -f "$logf"
|
|
done < <(jq -c '.[]' <<<"$CHECKS_JSON")
|
|
|
|
persist_env CHECKS_RESULT_JSON "$results"
|
|
summary "### Checks"
|
|
summary "$(jq -r '.[] | "- \(.id): **\(.status)** (\(.durationMs)ms\(if .required then "" else ", advisory" end))"' <<<"$results")"
|
|
|
|
if [ "${#required_failed[@]}" -gt 0 ]; then
|
|
die "Required check(s) failed: ${required_failed[*]}. The build was not published."
|
|
fi
|
|
log "All required checks passed"
|