This commit is contained in:
DealSage template sync
2026-09-26 05:57:32 +00:00
parent 36aeaf65c3
commit f176fca2bd
15 changed files with 472 additions and 46 deletions
+6 -3
View File
@@ -3,6 +3,7 @@
# record the build as a check so DealSage shows it beside the declared ones.
set -euo pipefail
. "$(dirname "$0")/lib.sh"
step_start build
require_env APP_ID DEALSAGE_FUNCTIONS_URL PUBLISH_TOKEN SUPABASE_ANON_KEY SUPABASE_URL
git_context
@@ -30,7 +31,9 @@ payload="$(jq -n \
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 the build check in DealSage"
rm -f "$logf"
summary "- build: **$status** (${dur}ms)"
[ "$rc" = 0 ] || die "Build failed ($summary); nothing was published."
log "Build ok: $(find dist -type f | wc -l) files"
[ "$rc" = 0 ] || fail_build build_failed "Build failed ($summary); nothing was published." "$logf"
rm -f "$logf"
files="$(find dist -type f | wc -l | tr -d ' ')"
log "Build ok: $files files"
step_done build passed "$files $([ "$files" = 1 ] && echo file || echo files) in dist/"
+12
View File
@@ -4,6 +4,9 @@
# CUSTOM_APPS_WORKER_URL). Installs are apt-based, matching the runner image.
set -euo pipefail
. "$(dirname "$0")/lib.sh"
# jq may not be here yet, so this step records itself at the end, back-dated.
started="$(iso_now)"; t0="$(now_ms)"
installed=()
need_apt=()
command -v curl >/dev/null || need_apt+=(curl)
@@ -11,6 +14,7 @@ command -v jq >/dev/null || need_apt+=(jq)
if [ "${#need_apt[@]}" -gt 0 ]; then
log "Installing ${need_apt[*]}"
apt-get update -qq && apt-get install -y -qq --no-install-recommends "${need_apt[@]}" >/dev/null
installed+=("${need_apt[@]}")
fi
if [ -z "${CUSTOM_APPS_WORKER_URL:-}" ] && ! command -v aws >/dev/null; then
@@ -19,5 +23,13 @@ if [ -z "${CUSTOM_APPS_WORKER_URL:-}" ] && ! command -v aws >/dev/null; then
curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip
unzip -q -o /tmp/awscliv2.zip -d /tmp
/tmp/aws/install >/dev/null
installed+=("the AWS CLI")
fi
echo "tools ready: curl $(curl --version | head -n1 | cut -d' ' -f2), jq $(jq --version)$( command -v aws >/dev/null && echo ", aws $(aws --version 2>&1 | cut -d' ' -f1)")"
step_start tooling "$started" "$t0"
if [ "${#installed[@]}" -gt 0 ]; then
step_done tooling passed "installed $(printf '%s, ' "${installed[@]}" | sed 's/, $//')"
else
step_done tooling passed
fi
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
# Close the build record when the run ends without publishing (skip-publish):
# checks and build passed, nothing was allocated. Usage: finish-build.sh [outcome] [reason]
set -euo pipefail
. "$(dirname "$0")/lib.sh"
require_env APP_ID DEALSAGE_FUNCTIONS_URL PUBLISH_TOKEN SUPABASE_ANON_KEY
step_done publish skipped "Checks and build only (skip-publish); nothing was published"
report_build_finish "${1:-checked}" "${2:-}"
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# The pipeline's last step, run however the steps before it ended (if:
# always()). Settles the step list with how the run ended and sends it one
# last time:
# * a step still running never finished, so it failed;
# * a step that never started was skipped;
# * when nothing closed the build record (a step died without fail_build:
# Set up Node.js, a crash), close it as failed, naming the step, so the hub
# does not show the run as running until it goes stale.
# Never fails: the run's result is already decided.
set -uo pipefail
. "$(dirname "$0")/lib.sh"
settle() {
local f before stopped reason
f="$(steps_file)"
[ -s "$f" ] && command -v jq >/dev/null || return 0
before="$(cat "$f")"
# Why the run stopped, from the step that stopped it: one still running
# (never finished), else the first that failed, else the first that never
# started (it died before it could say so).
stopped="$(jq -r '
(map(select(.status == "running"))[0] | select(.) | .name + " did not finish.")
// (map(select(.status == "failed"))[0] | select(.) | .name + (if .summary then ": " + .summary else " failed." end))
// (map(select(.status == "pending"))[0] | select(.) | "The run stopped before " + .name + ".")
// empty' "$f")"
_steps_edit 'map(if .status == "running" then .status = "failed"
elif .status == "pending" then .status = "skipped" else . end)' || return 0
# A step that was running when the run stopped gets its finish time too.
_steps_edit --arg at "$(iso_now)" --argjson ms "$(now_ms)" \
'map(if .status == "failed" and .startedMs and (.finishedAt | not)
then .finishedAt = $at | .durationMs = ($ms - .startedMs) else . end)' || return 0
if [ -n "${BUILD_ID:-}" ] && [ ! -e "$f.finished" ]; then
reason="${stopped:-The run stopped before it finished.}"
report_build_finish failed "$reason"
fi
[ "$(cat "$f")" = "$before" ] || steps_post
}
( settle ) || true
exit 0
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Install the app's dependencies with the action's install-command, run in the
# repo root under bash -eo pipefail like any run step. The output is kept, so a
# failure shows its tail on the build page, and a failure closes the build
# record (build_failed) instead of leaving the run "running" until it goes
# stale. Set up Node.js, the step before, ends here.
set -euo pipefail
. "$(dirname "$0")/lib.sh"
step_next node install
cmd="${INSTALL_COMMAND:-npm install --no-audit --no-fund}"
logf="$(mktemp)"
printf '$ %s\n' "$cmd"
set +e
bash -eo pipefail -c "$cmd" 2>&1 | tee "$logf"
rc=${PIPESTATUS[0]}
set -e
[ "$rc" = 0 ] || fail_build build_failed "Installing dependencies failed (exit code $rc); nothing was published." "$logf"
rm -f "$logf"
step_done install passed
+157 -10
View File
@@ -11,21 +11,24 @@
log() { printf '::group::%s\n' "$*" >/dev/null; printf '\n== %s\n' "$*"; }
warn() { printf '::warning::%s\n' "$*"; }
die() { printf '::error::%s\n' "$*"; exit 1; }
# die MESSAGE — stop the job; the running step (see "Pipeline steps") fails with MESSAGE.
die() { printf '::error::%s\n' "$*"; step_fail_running "$*"; exit 1; }
# now_ms — wall clock in milliseconds (GNU date; falls back to seconds*1000).
now_ms() { date +%s%3N 2>/dev/null || echo $(( $(date +%s) * 1000 )); }
# now_ms — wall clock in milliseconds (GNU date; falls back to seconds*1000
# where %N is not supported and comes back literally).
now_ms() {
local ms; ms="$(date +%s%3N 2>/dev/null || true)"
case "$ms" in ''|*[!0-9]*) echo $(( $(date +%s) * 1000 )) ;; *) echo "$ms" ;; esac
}
# iso_now — UTC timestamp for API payloads.
iso_now() { date -u +%Y-%m-%dT%H:%M:%SZ; }
# require_env NAME... — fail loudly when a required variable is missing.
require_env() {
local missing=0 v
for v in "$@"; do
if [ -z "${!v:-}" ]; then printf '::error::%s is not set\n' "$v"; missing=1; fi
done
[ "$missing" = 0 ] || exit 1
local missing=() v
for v in "$@"; do [ -n "${!v:-}" ] || missing+=("$v"); done
[ "${#missing[@]}" = 0 ] || die "${missing[*]} $([ "${#missing[@]}" = 1 ] && echo is || echo are) not set"
}
# json_escape STRING — JSON string literal (with quotes) via jq.
@@ -36,11 +39,12 @@ tail_file() { tail -n "${2:-80}" "$1" 2>/dev/null || true; }
# ds_post PATH JSON — POST JSON to a DealSage function with the publish token.
# Prints the response body; returns non-zero on HTTP failure (body still printed
# to stderr so the job log shows why).
# to stderr so the job log shows why). DS_POST_MAX_TIME caps the request in
# seconds (default 0: no cap).
ds_post() {
local path="$1" body="$2" out code
out="$(mktemp)"
code="$(curl -sS -o "$out" -w '%{http_code}' -X POST \
code="$(curl -sS --max-time "${DS_POST_MAX_TIME:-0}" -o "$out" -w '%{http_code}' -X POST \
"${DEALSAGE_FUNCTIONS_URL%/}/${path}" \
-H "Authorization: Bearer ${PUBLISH_TOKEN}" \
-H "apikey: ${SUPABASE_ANON_KEY}" \
@@ -86,3 +90,146 @@ persist_env() {
# summary MARKDOWN — append to the run's step summary when the runner supports it.
summary() { [ -n "${GITHUB_STEP_SUMMARY:-}" ] && printf '%s\n' "$*" >> "$GITHUB_STEP_SUMMARY" || true; }
# ---------------------------------------------------------------------------
# Build records (record-app-build): one row per pipeline run in DealSage, so a
# run that never reaches a version (a failed required check, a broken build)
# still shows up in the app hub. Best effort throughout: a DealSage outage must
# not fail the build.
# ---------------------------------------------------------------------------
# ci_run_id — Gitea's run id plus attempt, so a retried "start" is idempotent.
ci_run_id() {
if [ -n "${GITHUB_RUN_ID:-}" ]; then printf '%s-%s' "$GITHUB_RUN_ID" "${GITHUB_RUN_ATTEMPT:-1}"; fi
}
# report_build_start — POST start; persists BUILD_ID for the later steps.
report_build_start() {
local body resp id
body="$(jq -n --arg appId "$APP_ID" --arg sha "$COMMIT_SHA" --arg branch "$BRANCH" \
--arg msg "$COMMIT_MESSAGE" --arg author "$COMMIT_AUTHOR" --arg run "$(ci_run_id)" --arg started "$(iso_now)" \
'{appId:$appId, action:"start", commitSha:$sha, branch:$branch, commitMessage:$msg, author:$author,
ciRunId:(if $run == "" then null else $run end), reportedBy:"ci", startedAt:$started}')"
if resp="$(ds_post record-app-build "$body" 2>/dev/null)"; then
id="$(jq -r '.buildId // empty' <<<"$resp")"
if [ -n "$id" ]; then persist_env BUILD_ID "$id"; log "Build recorded in DealSage ($id)"; return 0; fi
fi
warn "could not record the build start in DealSage; the run continues without a build record"
}
# report_build_finish OUTCOME [REASON] [VERSION] [PROMOTED] — close the record.
# Leaves a marker beside the step list, so finish-steps.sh knows it was closed.
report_build_finish() {
[ -n "${BUILD_ID:-}" ] || return 0
printf '%s\n' "$1" > "$(steps_file).finished" 2>/dev/null || true
local body
body="$(jq -n --arg appId "$APP_ID" --arg id "$BUILD_ID" --arg outcome "$1" --arg reason "${2:-}" \
--arg v "${3:-}" --arg promoted "${4:-false}" --arg finished "$(iso_now)" \
'{appId:$appId, action:"finish", buildId:$id, outcome:$outcome,
failureReason:(if $reason == "" then null else $reason end),
version:(if $v == "" then null else ($v|tonumber) end),
promoted:($promoted == "true"), finishedAt:$finished}')"
ds_post record-app-build "$body" >/dev/null 2>&1 || warn "could not record the build outcome in DealSage"
}
# fail_build OUTCOME MESSAGE [LOGFILE] — fail the running step (with the tail
# of LOGFILE), record the outcome, then stop the job.
fail_build() { step_fail_running "$2" "${3:-}"; report_build_finish "$1" "$2"; die "$2"; }
# ---------------------------------------------------------------------------
# Pipeline steps (record-app-build, action "steps"). Gitea sees this whole
# action as one step of the job, so the pipeline reports its own steps and the
# build page in the app hub lists them while they run: status, duration, a
# short summary and, for a step that failed, the tail of its output.
#
# The list lives in a file the composite steps share, so whatever a dying step
# wrote survives it, and finish-steps.sh (the always() step at the end)
# settles it with how the run ended. Best effort, like the build record:
# reporting never fails a step, and once DealSage refuses a post the run stops
# trying. The list is only sent once the build is recorded (BUILD_ID); the
# steps before that are sent with the first post.
# ---------------------------------------------------------------------------
# id|name of every step, in the order action.yml runs them (keep the two in step).
PIPELINE_STEPS="tooling|Tooling
manifest|Read the app manifest
record|Record the build
node|Set up Node.js
install|Install dependencies
checks|Checks
build|Build
publish|Publish"
# steps_file — this run's step list, one per run attempt and job.
steps_file() {
printf '%s/dealsage-steps-%s-%s-%s.json' "${RUNNER_TEMP:-/tmp}" \
"${GITHUB_RUN_ID:-local}" "${GITHUB_RUN_ATTEMPT:-1}" "${GITHUB_JOB:-job}"
}
# _steps_edit JQ_ARGS... — rewrite the list with a jq program; the first edit
# of a run creates it with every step pending.
_steps_edit() {
local f; f="$(steps_file)"
if [ ! -s "$f" ]; then
jq -cn --arg steps "$PIPELINE_STEPS" \
'$steps | split("\n") | map(select(length > 0) | split("|") | {id: .[0], name: .[1], status: "pending"})' \
> "$f" || return 1
fi
jq -c "$@" "$f" > "$f.tmp" && mv "$f.tmp" "$f"
}
# _step_begin ID [STARTED_ISO STARTED_MS] — ID is running (since the given time).
_step_begin() {
_steps_edit --arg id "$1" --arg at "${2:-$(iso_now)}" --argjson ms "${3:-$(now_ms)}" \
'map(if .id == $id then {id, name, status: "running", startedAt: $at, startedMs: $ms} else . end)'
}
# _step_end ID STATUS [SUMMARY] [LOGFILE] — ID ended; a step that started gets
# its finish time and duration.
_step_end() {
local log=""
[ -z "${4:-}" ] || log="$(tail_file "$4")"
_steps_edit --arg id "$1" --arg status "$2" --arg summary "${3:-}" --arg log "$log" \
--arg at "$(iso_now)" --argjson ms "$(now_ms)" '
map(if .id != $id then . else
.status = $status
| (if .startedMs then .finishedAt = $at | .durationMs = ($ms - .startedMs) else . end)
| (if $summary != "" then .summary = $summary else . end)
| (if $log != "" then .logTail = $log else . end)
end)'
}
# steps_post — send the list to DealSage (a no-op until the build is recorded).
steps_post() {
[ -n "${BUILD_ID:-}" ] || return 0
local f body; f="$(steps_file)"
[ -s "$f" ] && [ ! -e "$f.off" ] || return 0
body="$(jq -c --arg appId "${APP_ID:-}" --arg id "$BUILD_ID" \
'{appId: $appId, action: "steps", buildId: $id, steps: map(del(.startedMs))}' "$f")" || return 0
if ! DS_POST_MAX_TIME=20 ds_post record-app-build "$body" >/dev/null 2>&1; then
: > "$f.off"
warn "could not record the pipeline steps in DealSage; the build page will not list this run's steps"
fi
}
# step_start ID [STARTED_ISO STARTED_MS] — ID is running. The optional start
# time is for the Tooling step, which can only record itself once jq is there.
step_start() { ( set +e; _step_begin "$@" && steps_post ) || true; }
# step_done ID STATUS [SUMMARY] [LOGFILE] — ID ended: passed, failed or
# skipped, with a short summary and, when given, the tail of LOGFILE.
step_done() { ( set +e; _step_end "$@" && steps_post ) || true; }
# step_next DONE NEXT — DONE passed and NEXT is running, in one post. This is
# how Set up Node.js (a stock action, nothing of ours runs inside it) is
# tracked: the step before starts it, the step after ends it.
step_next() { ( set +e; _step_end "$1" passed && _step_begin "$2" && steps_post ) || true; }
# step_fail_running SUMMARY [LOGFILE] — the step that is running failed.
step_fail_running() {
( set +e
local id
id="$(jq -r 'map(select(.status == "running"))[0].id // empty' "$(steps_file)" 2>/dev/null)"
[ -z "$id" ] || { _step_end "$id" failed "$1" "${2:-}" && steps_post; }
) || true
}
+4 -1
View File
@@ -7,6 +7,7 @@
# fails fast, before install. The schema of record is ../manifest.schema.json.
set -euo pipefail
. "$(dirname "$0")/lib.sh"
step_start manifest
MANIFEST_PATH="${MANIFEST_PATH:-.dealsage/app.json}"
[ -f "$MANIFEST_PATH" ] || die "Manifest not found at $MANIFEST_PATH"
@@ -45,5 +46,7 @@ manifest="$(jq -c . "$MANIFEST_PATH")"
persist_env APP_ID "$app_id"
persist_env MANIFEST_JSON "$manifest"
persist_env CHECKS_JSON "$checks"
log "Manifest: app $app_id, $(jq 'length' <<<"$checks") check(s)"
count="$(jq 'length' <<<"$checks")"
log "Manifest: app $app_id, $count check(s)"
jq -r '.[] | " - \(.id) (\(if .required then "required" else "advisory" end)): \(.run // ("platform:" + .uses))"' <<<"$checks"
step_done manifest passed "$count $([ "$count" = 1 ] && echo check || echo checks) declared"
+15 -9
View File
@@ -11,6 +11,7 @@
# The live pointer only ever moves after the bytes are in place.
set -euo pipefail
. "$(dirname "$0")/lib.sh"
step_start publish
require_env APP_ID DEALSAGE_FUNCTIONS_URL PUBLISH_TOKEN SUPABASE_ANON_KEY
git_context
[ -f dist/index.html ] || die "dist/index.html not found; run the build first"
@@ -21,14 +22,15 @@ checks_json="${CHECKS_RESULT_JSON:-[]}"
alloc_body="$(jq -n \
--arg appId "$APP_ID" --arg sha "$COMMIT_SHA" --arg branch "$BRANCH" \
--arg msg "$COMMIT_MESSAGE" --arg author "$COMMIT_AUTHOR" \
--argjson manifest "$manifest_json" --argjson checks "$checks_json" \
--argjson manifest "$manifest_json" --argjson checks "$checks_json" --arg build "${BUILD_ID:-}" \
'{appId:$appId, action:"allocate", builtBy:"ci", commitSha:$sha, branch:$branch,
commitMessage:$msg, author:$author, manifest:$manifest, checks:$checks}')"
alloc="$(ds_post record-app-version "$alloc_body")" || die "allocate failed"
commitMessage:$msg, author:$author, manifest:$manifest, checks:$checks,
buildId:(if $build == "" then null else $build end)}')"
alloc="$(ds_post record-app-version "$alloc_body")" || fail_build failed "allocate failed"
VERSION="$(jq -r '.version // empty' <<<"$alloc")"
PREFIX="$(jq -r '.r2Prefix // empty' <<<"$alloc")"
UPLOAD_TOKEN="$(jq -r '.uploadToken // empty' <<<"$alloc")"
[ -n "$VERSION" ] && [ -n "$PREFIX" ] || die "allocate returned no version/prefix: $alloc"
[ -n "$VERSION" ] && [ -n "$PREFIX" ] || fail_build failed "allocate returned no version/prefix: $alloc"
log "Allocated v$VERSION for $BRANCH@${COMMIT_SHA:0:7} -> $PREFIX"
mark_failed() {
@@ -38,7 +40,7 @@ mark_failed() {
# --- 2. upload --------------------------------------------------------------
if [ -n "${CUSTOM_APPS_WORKER_URL:-}" ]; then
[ -n "$UPLOAD_TOKEN" ] || { mark_failed "no upload token"; die "allocate returned no uploadToken but CUSTOM_APPS_WORKER_URL is set"; }
[ -n "$UPLOAD_TOKEN" ] || { mark_failed "no upload token"; fail_build failed "allocate returned no uploadToken but CUSTOM_APPS_WORKER_URL is set"; }
log "Uploading through the Worker"
export WORKER="${CUSTOM_APPS_WORKER_URL%/}" UPLOAD_TOKEN APP_ID VERSION
upload_one() { # relative path under dist/
@@ -50,7 +52,7 @@ if [ -n "${CUSTOM_APPS_WORKER_URL:-}" ]; then
}
export -f upload_one
if ! (cd dist && find . -type f | sed 's|^\./||') | xargs -P 6 -n 1 bash -c 'upload_one "$0"'; then
mark_failed "upload failed"; die "Upload failed; v$VERSION marked failed and was not promoted."
mark_failed "upload failed"; fail_build upload_failed "Upload failed; v$VERSION marked failed and was not promoted."
fi
else
require_env R2_ACCOUNT_ID R2_BUCKET R2_ACCESS_KEY_ID R2_SECRET_ACCESS_KEY
@@ -60,23 +62,27 @@ else
AWS_RESPONSE_CHECKSUM_VALIDATION=when_required \
aws s3 sync dist "s3://$R2_BUCKET/${PREFIX%/}" \
--endpoint-url "https://$R2_ACCOUNT_ID.r2.cloudflarestorage.com" --delete; then
mark_failed "upload failed"; die "Upload failed; v$VERSION marked failed and was not promoted."
mark_failed "upload failed"; fail_build upload_failed "Upload failed; v$VERSION marked failed and was not promoted."
fi
fi
log "Uploaded $(find dist -type f | wc -l) files"
# --- 3. promote (DealSage applies the app's publish policy) ------------------
promote="$(ds_post record-app-version "$(jq -n --arg appId "$APP_ID" --argjson v "$VERSION" \
'{appId:$appId, action:"promote", version:$v}')")" || die "promote request failed"
'{appId:$appId, action:"promote", version:$v}')")" || fail_build failed "promote request failed"
promoted="$(jq -r '.promoted // false' <<<"$promote")"
channel="$(jq -r '.channel // empty' <<<"$promote")"
current="$(jq -r '.currentVersion // empty' <<<"$promote")"
if [ "$promoted" = true ]; then
log "v$VERSION is live"
outcome_note="v$VERSION is live"
log "$outcome_note"
else
live_note="nothing is live yet"; [ -n "$current" ] && live_note="live stays at v$current"
outcome_note="v$VERSION kept on ${channel:-branch/$BRANCH}; $live_note"
log "v$VERSION built and kept on channel '${channel:-branch/$BRANCH}' ($live_note); promote it from DealSage when ready"
fi
step_done publish passed "$outcome_note"
report_build_finish built "" "$VERSION" "$promoted"
{
echo "version=$VERSION"; echo "promoted=$promoted"; echo "channel=${channel}"
} >> "${GITHUB_OUTPUT:-/dev/null}"
+13 -2
View File
@@ -8,6 +8,7 @@
# a failure: the build should not be blocked by the dashboard being down.
set -euo pipefail
. "$(dirname "$0")/lib.sh"
step_start checks
require_env APP_ID CHECKS_JSON DEALSAGE_FUNCTIONS_URL PUBLISH_TOKEN SUPABASE_ANON_KEY
git_context
CHECKS_DIR="$(cd "$(dirname "$0")/../checks" && pwd)"
@@ -28,10 +29,12 @@ post_check() { # id name status required duration_ms summary logfile started fin
results='[]'
required_failed=()
advisory_failed=()
count="$(jq 'length' <<<"$CHECKS_JSON")"
if [ "$count" = 0 ]; then
log "No checks declared in .dealsage/app.json"
persist_env CHECKS_RESULT_JSON '[]'
step_done checks skipped "No checks declared in .dealsage/app.json"
exit 0
fi
@@ -59,7 +62,9 @@ while IFS= read -r check; do
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
if [ "$status" != passed ]; then
if [ "$required" = true ]; then required_failed+=("$name"); else advisory_failed+=("$name"); fi
fi
rm -f "$logf"
done < <(jq -c '.[]' <<<"$CHECKS_JSON")
@@ -68,6 +73,12 @@ 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."
fail_build checks_failed "Required check(s) failed: ${required_failed[*]}. The build was not published."
fi
log "All required checks passed"
passed="$(jq '[.[] | select(.status == "passed")] | length' <<<"$results")"
note="$passed of $count passed"
if [ "${#advisory_failed[@]}" -gt 0 ]; then
note="$note ($(printf '%s, ' "${advisory_failed[@]}" | sed 's/, $//') failed, not required)"
fi
step_done checks passed "$note"
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Record the start of this pipeline run in DealSage (custom_app_builds), so the
# app hub shows the run while it is in progress and keeps it if it fails before
# a version exists. Later steps close it through report_build_finish. The first
# post of the step list goes with it, and Set up Node.js (next) starts here.
set -euo pipefail
. "$(dirname "$0")/lib.sh"
step_start record
require_env APP_ID DEALSAGE_FUNCTIONS_URL PUBLISH_TOKEN SUPABASE_ANON_KEY
git_context
report_build_start
step_next record node