Files
wehub-resource-sync 070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:00:47 +08:00

104 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Upload a new anonymized recording to Cloudflare R2 and update the
# local manifest. Local-maintainer flow — no GitHub Action involved,
# nothing about the recording ever lands in git.
#
# bash mocks/scripts/upload-recording.sh <recording.jsonl>
#
# Prereqs
# -------
# - `wrangler login` once (OAuth, no token to manage). The logged-in
# account must have access to the powerformer R2 namespace where the
# `open-design-mocks` bucket lives.
# - That's it. Bucket is public-read, manifest is in repo; consumers
# pull via `fetch-recordings.sh`.
#
# What it does
# ------------
# 1. Validate the .jsonl (first line = meta event, UUID filename)
# 2. Compute sha256, parse meta, build manifest entry
# 3. `wrangler r2 object put` the recording → recordings/v1/<id>.jsonl
# 4. Update mocks/manifest.json with the new entry (rebuilt histograms)
# 5. `wrangler r2 object put` the manifest too → recordings/v1/manifest.json
# 6. Tell you to commit + push the manifest change
#
# The .jsonl is never copied into the repo. Only mocks/manifest.json
# (≈200B added per entry) gets git-tracked.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
MOCKS_DIR="$(cd "$HERE/.." && pwd -P)"
MANIFEST="$MOCKS_DIR/manifest.json"
LIB="$HERE/lib/manifest-utils.mjs"
BUCKET='open-design-mocks'
KEY_PREFIX='recordings/v1/'
# powerformer hosts the bucket; pin so wrangler doesn't ask which
# account in non-interactive mode when the OAuth login spans several.
export CLOUDFLARE_ACCOUNT_ID='64ad4569ffd912432d6b86d5656484c4'
if [ $# -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
sed -n '2,28p' "$0" | sed 's/^# \?//'
exit 0
fi
INPUT="$1"
if [ ! -f "$INPUT" ]; then echo "✗ no such file: $INPUT" >&2; exit 1; fi
INPUT_ABS="$(cd "$(dirname "$INPUT")" && pwd -P)/$(basename "$INPUT")"
TRACE_ID="$(basename "$INPUT" .jsonl)"
if ! printf '%s' "$TRACE_ID" | grep -qE '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'; then
echo "✗ trace id '$TRACE_ID' is not a UUID. Rename the file." >&2
exit 1
fi
if ! command -v wrangler >/dev/null 2>&1; then
echo "✗ wrangler not installed. \`npm i -g wrangler\` (or pnpm/yarn) and \`wrangler login\` first." >&2
exit 1
fi
# Step 1+2: validate + build entry preview via shared lib (Node — same code
# the consumers use, so no shape drift)
ENTRY_JSON=$(node --input-type=module -e "
import { inspectRecording } from '$LIB';
process.stdout.write(JSON.stringify(inspectRecording('$INPUT_ABS'), null, 2));
" 2>&1) || {
echo "✗ validation failed:" >&2
echo "$ENTRY_JSON" | sed 's/^/ /' >&2
exit 1
}
echo "manifest entry to add:"
echo "$ENTRY_JSON" | sed 's/^/ /'
echo
# Step 3: upload the recording itself
echo "→ uploading recording to R2…"
wrangler r2 object put "${BUCKET}/${KEY_PREFIX}${TRACE_ID}.jsonl" \
--file "$INPUT_ABS" --remote >/dev/null
echo " ✓ $TRACE_ID.jsonl"
# Step 4: update local manifest.json
echo "→ updating local mocks/manifest.json…"
node --input-type=module -e "
import { inspectRecording, upsertEntry, readManifest, writeManifest } from '$LIB';
const m = readManifest('$MANIFEST');
upsertEntry(m, inspectRecording('$INPUT_ABS'));
writeManifest('$MANIFEST', m);
console.log(' ✓ now ' + m.total + ' entries (' + (m.total_bytes/1024).toFixed(0) + ' KB total)');
"
# Step 5: upload the updated manifest to R2 so consumers see the new entry
# without waiting for the next git push.
echo "→ uploading manifest to R2…"
wrangler r2 object put "${BUCKET}/${KEY_PREFIX}manifest.json" \
--file "$MANIFEST" --remote >/dev/null
echo " ✓ manifest.json"
echo
echo "✅ done. Next:"
echo " git add mocks/manifest.json"
echo " git commit -m 'mocks: add recording $TRACE_ID'"
echo " git push"