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__/
|
__pycache__/
|
||||||
plans/codex-shots*/
|
plans/codex-shots*/
|
||||||
plans/codex-report*.md
|
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