mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 23:13:12 +00:00
Some checks failed
Frontend checks / Build and test (push) Has been cancelled
Frontend checks / governance (push) Has been cancelled
Frontend checks / Visual regression (push) Has been cancelled
Deploy dev content / Deploy shoc-frontend-new-dev through Terraform (push) Has been cancelled
Capturing the curl body in "$(...)" strips the trailing newline, so the served sha256 never matched dist/index.html and every release and rollback verify polled to the budget and failed. Hash the response stream directly and give the test fixture a trailing newline so the suite covers it.
302 lines
11 KiB
Bash
Executable file
302 lines
11 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Stubbed aws/curl tests for scripts/verify-cloudfront-release.sh.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
VERIFY="${ROOT}/scripts/verify-cloudfront-release.sh"
|
|
CURRENT="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-2-1"
|
|
PREVIOUS="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-1-1"
|
|
NEW_HASH="1111111111111111111111111111111111111111111111111111111111111111"
|
|
OLD_HASH="0000000000000000000000000000000000000000000000000000000000000000"
|
|
# Vite writes index.html with a trailing newline. Keep it in the fixture so
|
|
# the expected hash covers every served byte, exactly like dist/index.html.
|
|
INDEX_HTML=$'<!doctype html><html><head><script type="module" src="/assets/app.js"></script></head><body></body></html>\n'
|
|
INDEX_HASH="$(printf '%s' "${INDEX_HTML}" | python3 -c 'import hashlib,sys; print(hashlib.sha256(sys.stdin.buffer.read()).hexdigest())')"
|
|
|
|
failures=0
|
|
assert_exit() {
|
|
local name="$1" expected="$2" got="$3" log="$4"
|
|
if [[ "${got}" != "${expected}" ]]; then
|
|
echo "FAIL: ${name}: expected exit ${expected}, got ${got}" >&2
|
|
sed -n '1,80p' "${log}" >&2
|
|
failures=$((failures + 1))
|
|
else
|
|
echo "PASS: ${name}"
|
|
fi
|
|
}
|
|
|
|
make_stubs() {
|
|
local bin="$1"
|
|
mkdir -p "${bin}"
|
|
cat > "${bin}/aws" << 'AWS'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
state_dir="${STUB_STATE}"
|
|
if [[ "${1:-}" == "s3" ]]; then
|
|
cat "${state_dir}/pointer.json"
|
|
exit 0
|
|
fi
|
|
cat "${state_dir}/distribution.json"
|
|
AWS
|
|
cat > "${bin}/curl" << 'CURL'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
state_dir="${STUB_STATE}"
|
|
method="GET"
|
|
url=""
|
|
dump=""
|
|
output=""
|
|
write_out=""
|
|
args=("$@")
|
|
i=0
|
|
while [[ $i -lt ${#args[@]} ]]; do
|
|
arg="${args[$i]}"
|
|
case "${arg}" in
|
|
-X) i=$((i + 1)); method="${args[$i]}" ;;
|
|
-D) i=$((i + 1)); dump="${args[$i]}" ;;
|
|
-o) i=$((i + 1)); output="${args[$i]}" ;;
|
|
-w) i=$((i + 1)); write_out="${args[$i]}" ;;
|
|
-H|--max-time|-s|-S|-f|-fsS|-sS) ;;
|
|
http*) url="${arg}" ;;
|
|
esac
|
|
i=$((i + 1))
|
|
done
|
|
if [[ "${method}" == "OPTIONS" ]]; then
|
|
[[ -n "${dump}" ]] && printf 'HTTP/1.1 204 No Content\nAccess-Control-Allow-Origin: https://dev.seahaven.com\n\n' > "${dump}"
|
|
[[ -n "${write_out}" ]] && printf '204'
|
|
exit 0
|
|
fi
|
|
if [[ "${url}" == *"/assets/"* ]]; then
|
|
[[ -n "${dump}" ]] && printf 'HTTP/1.1 200 OK\nCache-Control: public,max-age=31536000,immutable\n\n' > "${dump}"
|
|
if [[ -f "${state_dir}/asset.js" ]]; then
|
|
body="$(cat "${state_dir}/asset.js")"
|
|
else
|
|
body='const api="https://api.dev.seahaven.com/api";'
|
|
fi
|
|
[[ -n "${output}" ]] && printf '%s' "${body}" > "${output}"
|
|
[[ -z "${output}" ]] && printf '%s' "${body}"
|
|
exit 0
|
|
fi
|
|
# Serve index.html byte-for-byte, trailing newline included, like real curl.
|
|
[[ -n "${dump}" ]] && printf 'HTTP/1.1 200 OK\nCache-Control: no-cache,no-store,must-revalidate\n\n' > "${dump}"
|
|
if [[ -n "${output}" ]]; then
|
|
cat "${state_dir}/index.html" > "${output}"
|
|
else
|
|
cat "${state_dir}/index.html"
|
|
fi
|
|
exit 0
|
|
CURL
|
|
chmod +x "${bin}/aws" "${bin}/curl"
|
|
}
|
|
|
|
dist_json() {
|
|
local status="$1" current_path="$2"
|
|
python3 -c 'import json,sys
|
|
status, path = sys.argv[1], sys.argv[2]
|
|
print(json.dumps({
|
|
"Distribution": {
|
|
"Status": status,
|
|
"DistributionConfig": {
|
|
"Origins": {"Items": [
|
|
{"Id": "current", "OriginPath": path},
|
|
{"Id": "previous", "OriginPath": ""},
|
|
]}
|
|
}
|
|
}
|
|
}))' "${status}" "${current_path}"
|
|
}
|
|
|
|
pointer_json() {
|
|
python3 -c 'import json,sys; print(json.dumps({"current": sys.argv[1], "previous": sys.argv[2]}))' "$1" "$2"
|
|
}
|
|
|
|
run_case() {
|
|
local name="$1"
|
|
local dir
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
printf '%s' "${INDEX_HTML}" > "${dir}/index.html"
|
|
export STUB_STATE="${dir}"
|
|
export PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P"
|
|
export EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${NEW_HASH}"
|
|
export PREVIOUS_INDEX_SHA256="${OLD_HASH}"
|
|
export SITE_URL="https://dev.seahaven.com"
|
|
export SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=3
|
|
export INTERVAL=0
|
|
local log="${dir}/log.txt"
|
|
set +e
|
|
bash "${VERIFY}" > "${log}" 2>&1
|
|
local code=$?
|
|
set -e
|
|
assert_exit "${name}" "$2" "${code}" "${log}"
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
# 1. Right config, then propagates (InProgress -> Deployed, hash already matches).
|
|
{
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
printf '%s' "${INDEX_HTML}" > "${dir}/index.html"
|
|
pointer_json "${CURRENT}" "${PREVIOUS}" > "${dir}/pointer.json"
|
|
printf 'InProgress\n' > "${dir}/status"
|
|
cat > "${dir}/bin/aws" << AWS
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
if [[ "\${1:-}" == "s3" ]]; then
|
|
cat "${dir}/pointer.json"
|
|
exit 0
|
|
fi
|
|
status="\$(cat "${dir}/status")"
|
|
python3 -c 'import json,sys; print(json.dumps({"Distribution":{"Status":sys.argv[1],"DistributionConfig":{"Origins":{"Items":[{"Id":"current","OriginPath":"/releases/${CURRENT}"},{"Id":"previous","OriginPath":""}]}}}}))' "\${status}"
|
|
echo Deployed > "${dir}/status"
|
|
AWS
|
|
chmod +x "${dir}/bin/aws"
|
|
export STUB_STATE="${dir}" PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P" EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${INDEX_HASH}" PREVIOUS_INDEX_SHA256="${OLD_HASH}"
|
|
export SITE_URL="https://dev.seahaven.com" SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=5 INTERVAL=0
|
|
set +e
|
|
bash "${VERIFY}" > "${dir}/log.txt" 2>&1
|
|
code=$?
|
|
set -e
|
|
assert_exit "right-config-then-propagates" 0 "${code}" "${dir}/log.txt"
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
# 2. Right config never propagates (Deployed, stale hash).
|
|
{
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
pointer_json "${CURRENT}" "${PREVIOUS}" > "${dir}/pointer.json"
|
|
dist_json "Deployed" "/releases/${CURRENT}" > "${dir}/distribution.json"
|
|
printf 'stale' > "${dir}/index.html"
|
|
export STUB_STATE="${dir}" PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P" EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${NEW_HASH}" PREVIOUS_INDEX_SHA256="$(printf 'stale' | python3 -c 'import hashlib,sys; print(hashlib.sha256(sys.stdin.buffer.read()).hexdigest())')"
|
|
export SITE_URL="https://dev.seahaven.com" SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=2 INTERVAL=0
|
|
set +e
|
|
bash "${VERIFY}" > "${dir}/log.txt" 2>&1
|
|
code=$?
|
|
set -e
|
|
assert_exit "right-config-never-propagates" 1 "${code}" "${dir}/log.txt"
|
|
grep -q "last observed" "${dir}/log.txt" || { echo "FAIL: timeout missing last observed state" >&2; failures=$((failures + 1)); }
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
# 3. Wrong origin path fails fast.
|
|
{
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
pointer_json "${CURRENT}" "${PREVIOUS}" > "${dir}/pointer.json"
|
|
dist_json "Deployed" "/releases/${PREVIOUS}" > "${dir}/distribution.json"
|
|
printf '%s' "${INDEX_HTML}" > "${dir}/index.html"
|
|
export STUB_STATE="${dir}" PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P" EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${NEW_HASH}" PREVIOUS_INDEX_SHA256="${OLD_HASH}"
|
|
export SITE_URL="https://dev.seahaven.com" SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=2 INTERVAL=0
|
|
set +e
|
|
bash "${VERIFY}" > "${dir}/log.txt" 2>&1
|
|
code=$?
|
|
set -e
|
|
assert_exit "wrong-origin-path" 1 "${code}" "${dir}/log.txt"
|
|
grep -q "origin_path" "${dir}/log.txt" || { echo "FAIL: wrong origin path did not name origin_path" >&2; failures=$((failures + 1)); }
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
# 4. Wrong pointer fails fast.
|
|
{
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
pointer_json "${PREVIOUS}" "${PREVIOUS}" > "${dir}/pointer.json"
|
|
dist_json "Deployed" "/releases/${CURRENT}" > "${dir}/distribution.json"
|
|
printf '%s' "${INDEX_HTML}" > "${dir}/index.html"
|
|
export STUB_STATE="${dir}" PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P" EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${NEW_HASH}" PREVIOUS_INDEX_SHA256="${OLD_HASH}"
|
|
export SITE_URL="https://dev.seahaven.com" SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=2 INTERVAL=0
|
|
set +e
|
|
bash "${VERIFY}" > "${dir}/log.txt" 2>&1
|
|
code=$?
|
|
set -e
|
|
assert_exit "wrong-pointer" 1 "${code}" "${dir}/log.txt"
|
|
grep -q "pointer current" "${dir}/log.txt" || { echo "FAIL: wrong pointer did not name pointer current" >&2; failures=$((failures + 1)); }
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
# 5. Never Deployed.
|
|
{
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
pointer_json "${CURRENT}" "${PREVIOUS}" > "${dir}/pointer.json"
|
|
dist_json "InProgress" "/releases/${CURRENT}" > "${dir}/distribution.json"
|
|
printf '%s' "${INDEX_HTML}" > "${dir}/index.html"
|
|
export STUB_STATE="${dir}" PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P" EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${NEW_HASH}" PREVIOUS_INDEX_SHA256="${OLD_HASH}"
|
|
export SITE_URL="https://dev.seahaven.com" SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=2 INTERVAL=0
|
|
set +e
|
|
bash "${VERIFY}" > "${dir}/log.txt" 2>&1
|
|
code=$?
|
|
set -e
|
|
assert_exit "never-deployed" 1 "${code}" "${dir}/log.txt"
|
|
grep -q "last observed" "${dir}/log.txt" || { echo "FAIL: never-deployed missing last observed state" >&2; failures=$((failures + 1)); }
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
# 6. Hash-matched Deployed release whose JS assets omit the baked API URL.
|
|
{
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
pointer_json "${CURRENT}" "${PREVIOUS}" > "${dir}/pointer.json"
|
|
dist_json "Deployed" "/releases/${CURRENT}" > "${dir}/distribution.json"
|
|
printf '%s' "${INDEX_HTML}" > "${dir}/index.html"
|
|
printf 'const x=1;' > "${dir}/asset.js"
|
|
export STUB_STATE="${dir}" PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P" EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${INDEX_HASH}" PREVIOUS_INDEX_SHA256="${OLD_HASH}"
|
|
export SITE_URL="https://dev.seahaven.com" SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=2 INTERVAL=0
|
|
set +e
|
|
bash "${VERIFY}" > "${dir}/log.txt" 2>&1
|
|
code=$?
|
|
set -e
|
|
assert_exit "missing-baked-api-url" 1 "${code}" "${dir}/log.txt"
|
|
grep -q "baked dev API URL" "${dir}/log.txt" || { echo "FAIL: missing API URL did not name baked dev API URL" >&2; failures=$((failures + 1)); }
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
# 7. Hash-matched Deployed release whose JS assets contain the staging API URL.
|
|
{
|
|
dir="$(mktemp -d)"
|
|
make_stubs "${dir}/bin"
|
|
pointer_json "${CURRENT}" "${PREVIOUS}" > "${dir}/pointer.json"
|
|
dist_json "Deployed" "/releases/${CURRENT}" > "${dir}/distribution.json"
|
|
printf '%s' "${INDEX_HTML}" > "${dir}/index.html"
|
|
printf 'const api="https://api.staging.seahaven.com/api";' > "${dir}/asset.js"
|
|
export STUB_STATE="${dir}" PATH="${dir}/bin:${PATH}"
|
|
export DISTRIBUTION_ID="E2CWLM1AFB964P" EXPECTED_LABEL="${CURRENT}"
|
|
export EXPECTED_INDEX_SHA256="${INDEX_HASH}" PREVIOUS_INDEX_SHA256="${OLD_HASH}"
|
|
export SITE_URL="https://dev.seahaven.com" SITE_BUCKET="seahaven-shoc-frontend-dev"
|
|
export BUDGET=2 INTERVAL=0
|
|
set +e
|
|
bash "${VERIFY}" > "${dir}/log.txt" 2>&1
|
|
code=$?
|
|
set -e
|
|
assert_exit "forbidden-staging-api-url" 1 "${code}" "${dir}/log.txt"
|
|
grep -q "forbidden URL api.staging.seahaven.com" "${dir}/log.txt" || { echo "FAIL: staging API URL did not name forbidden URL" >&2; failures=$((failures + 1)); }
|
|
rm -rf "${dir}"
|
|
}
|
|
|
|
if [[ "${failures}" -ne 0 ]]; then
|
|
echo "FAIL: ${failures} verify-cloudfront-release cases failed" >&2
|
|
exit 1
|
|
fi
|
|
echo "PASS: CloudFront release verify checks"
|