91 lines
5.1 KiB
Bash
Executable File
91 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Publish dist/ as a new version of the app:
|
|
# 1. allocate — DealSage assigns version N for this commit/branch and returns
|
|
# where the bytes go plus a short-lived upload token.
|
|
# 2. upload — through the serving Worker when CUSTOM_APPS_WORKER_URL is set
|
|
# (no R2 key on CI), else `aws s3 sync` with the org's R2 keys.
|
|
# 3. promote — ask DealSage to release it. DealSage decides: a default-branch
|
|
# build under an "auto" policy goes live; anything else is kept
|
|
# as a built version on its branch channel for preview and a
|
|
# later, deliberate promotion. CI never knows the policy.
|
|
# 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"
|
|
|
|
# --- 1. allocate ------------------------------------------------------------
|
|
manifest_json="${MANIFEST_JSON:-{\}}"
|
|
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" --arg build "${BUILD_ID:-}" \
|
|
'{appId:$appId, action:"allocate", builtBy:"ci", commitSha:$sha, branch:$branch,
|
|
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" ] || fail_build failed "allocate returned no version/prefix: $alloc"
|
|
log "Allocated v$VERSION for $BRANCH@${COMMIT_SHA:0:7} -> $PREFIX"
|
|
|
|
mark_failed() {
|
|
ds_post record-app-version "$(jq -n --arg appId "$APP_ID" --argjson v "$VERSION" --arg reason "$1" \
|
|
'{appId:$appId, action:"fail", version:$v, reason:$reason}')" >/dev/null 2>&1 || true
|
|
}
|
|
|
|
# --- 2. upload --------------------------------------------------------------
|
|
if [ -n "${CUSTOM_APPS_WORKER_URL:-}" ]; then
|
|
[ -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/
|
|
local rel="$1" code
|
|
code="$(curl -sS -o /dev/null -w '%{http_code}' -X PUT \
|
|
"$WORKER/__upload/$APP_ID/$VERSION/$rel" \
|
|
-H "Authorization: Bearer $UPLOAD_TOKEN" --data-binary "@dist/$rel")" || code=000
|
|
case "$code" in 2*) ;; *) echo "upload failed ($code): $rel" >&2; return 1 ;; esac
|
|
}
|
|
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"; 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
|
|
log "Uploading with the AWS CLI to s3://$R2_BUCKET/${PREFIX%/}"
|
|
if ! AWS_ACCESS_KEY_ID="$R2_ACCESS_KEY_ID" AWS_SECRET_ACCESS_KEY="$R2_SECRET_ACCESS_KEY" \
|
|
AWS_DEFAULT_REGION=auto AWS_REQUEST_CHECKSUM_CALCULATION=when_required \
|
|
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"; 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}')")" || 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
|
|
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}"
|
|
summary "### Published"
|
|
summary "- **v$VERSION** from \`$BRANCH\` @ \`${COMMIT_SHA:0:7}\` — $( [ "$promoted" = true ] && echo "live" || echo "built, channel \`${channel:-branch/$BRANCH}\`" )"
|