127 lines
3.8 KiB
Bash
Executable File
127 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ==============================================================================
|
|
# perf/make-shell-fixture.sh
|
|
# Archives frontend from <commit> into perf/fixtures/shell-<tag>/,
|
|
# computes the build tag the way server.js computeBuildTag() does,
|
|
# and verifies that it matches expected-tag (or live prod tag).
|
|
# ==============================================================================
|
|
|
|
if [ $# -lt 1 ]; then
|
|
echo "Usage: $0 <commit> [expected-tag]" >&2
|
|
exit 1
|
|
fi
|
|
|
|
COMMIT="$1"
|
|
EXPECTED_TAG="${2:-}"
|
|
|
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
PERF_DIR="$REPO_ROOT/perf"
|
|
FIXTURES_DIR="$PERF_DIR/fixtures"
|
|
TMP_DIR="$PERF_DIR/.tmp"
|
|
|
|
mkdir -p "$FIXTURES_DIR" "$TMP_DIR"
|
|
|
|
PROD_URL="https://worship.hesed.sbs/api/version"
|
|
|
|
fetch_prod_tag() {
|
|
curl -s -S --max-time 10 "$PROD_URL" | node -e '
|
|
let data = "";
|
|
process.stdin.on("data", chunk => { data += chunk; });
|
|
process.stdin.on("end", () => {
|
|
try {
|
|
const j = JSON.parse(data);
|
|
if (j.buildTag) {
|
|
process.stdout.write(j.buildTag);
|
|
process.exit(0);
|
|
}
|
|
} catch {}
|
|
process.exit(1);
|
|
});
|
|
' 2>/dev/null || echo ""
|
|
}
|
|
|
|
# Verify the commit exists in git
|
|
if ! git rev-parse --verify "$COMMIT^{commit}" >/dev/null 2>&1; then
|
|
echo "Error: commit '$COMMIT' not found in git repository" >&2
|
|
exit 1
|
|
fi
|
|
|
|
RESOLVED_COMMIT="$(git rev-parse --short=7 "$COMMIT")"
|
|
echo "Extracting frontend from commit $RESOLVED_COMMIT..."
|
|
|
|
STAGING_DIR="$(mktemp -d "$TMP_DIR/fixture-staging-XXXXXX")"
|
|
cleanup() {
|
|
rm -rf "$STAGING_DIR"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Archive frontend tree into staging dir
|
|
git archive "$COMMIT" frontend | tar -x -C "$STAGING_DIR" --strip-components=1
|
|
|
|
# Compute build tag using the exact logic from server/server.js computeBuildTag()
|
|
COMPUTED_TAG=$(node -e '
|
|
const { createHash } = require("crypto");
|
|
const { readdirSync, statSync, readFileSync } = require("fs");
|
|
|
|
function computeTag(dir) {
|
|
const hash = createHash("sha256");
|
|
const walk = (d, prefix) => {
|
|
for (const name of readdirSync(d).sort()) {
|
|
const full = `${d}/${name}`;
|
|
const rel = `${prefix}/${name}`;
|
|
if (statSync(full).isDirectory()) {
|
|
walk(full, rel);
|
|
} else {
|
|
hash.update(rel);
|
|
hash.update(readFileSync(full));
|
|
}
|
|
}
|
|
};
|
|
walk(dir, "./public");
|
|
return hash.digest("hex").slice(0, 12);
|
|
}
|
|
|
|
const tag = computeTag(process.argv[1]);
|
|
process.stdout.write(tag);
|
|
' "$STAGING_DIR")
|
|
|
|
echo "Computed build tag for $RESOLVED_COMMIT: $COMPUTED_TAG"
|
|
|
|
# Determine target expected tag
|
|
if [ -z "$EXPECTED_TAG" ]; then
|
|
echo "Querying live production tag from $PROD_URL..."
|
|
EXPECTED_TAG="$(fetch_prod_tag)"
|
|
if [ -z "$EXPECTED_TAG" ]; then
|
|
echo "Error: failed to fetch live buildTag from $PROD_URL" >&2
|
|
exit 1
|
|
fi
|
|
echo "Live production build tag: $EXPECTED_TAG"
|
|
|
|
# If mismatch, deploy might be in progress: wait 5 minutes and retry once
|
|
if [ "$COMPUTED_TAG" != "$EXPECTED_TAG" ]; then
|
|
echo "Tag mismatch detected (computed=$COMPUTED_TAG vs prod=$EXPECTED_TAG)."
|
|
echo "Deploy may be in progress. Waiting 300 seconds to retry once..."
|
|
sleep 300
|
|
EXPECTED_TAG="$(fetch_prod_tag)"
|
|
echo "Retried production build tag: $EXPECTED_TAG"
|
|
fi
|
|
fi
|
|
|
|
if [ "$COMPUTED_TAG" != "$EXPECTED_TAG" ]; then
|
|
echo "Error: build tag mismatch! Computed '$COMPUTED_TAG' does not match expected '$EXPECTED_TAG'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
TARGET_FIXTURE_DIR="$FIXTURES_DIR/shell-$COMPUTED_TAG"
|
|
echo "Installing fixture into $TARGET_FIXTURE_DIR..."
|
|
rm -rf "$TARGET_FIXTURE_DIR"
|
|
mkdir -p "$TARGET_FIXTURE_DIR"
|
|
cp -a "$STAGING_DIR"/. "$TARGET_FIXTURE_DIR"/
|
|
|
|
FILE_COUNT=$(find "$TARGET_FIXTURE_DIR" -type f | wc -l)
|
|
echo "Success: shell fixture created at $TARGET_FIXTURE_DIR with $FILE_COUNT files."
|
|
echo "Verified commit: $RESOLVED_COMMIT"
|
|
echo "Verified build tag: $COMPUTED_TAG"
|