Add shell fixture script and verify production build tag
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -40,3 +40,7 @@ legacy/releases/
|
||||
__pycache__/
|
||||
plans/codex-shots*/
|
||||
plans/codex-report*.md
|
||||
|
||||
# performance harness artifacts and temp files
|
||||
perf/fixtures/
|
||||
perf/.tmp/
|
||||
|
||||
126
perf/make-shell-fixture.sh
Executable file
126
perf/make-shell-fixture.sh
Executable file
@@ -0,0 +1,126 @@
|
||||
#!/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"
|
||||
Reference in New Issue
Block a user