Files
portfolio-next/scripts/smoke-test.sh
T

50 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Runs an image against a git repo made from fixtures/content and checks it builds and serves.
# Source credentials are not needed: SOURCES_FIXTURES points at fixtures/sources copied in.
# Usage: scripts/smoke-test.sh <image>
# Uses only `docker cp` and `docker exec`, no bind mounts or published ports: CI jobs run in a
# container talking to the host's daemon, where neither the job's paths nor its localhost exist.
set -euo pipefail
image=$1
work=$(mktemp -d)
name="site-smoke-$$"
cleanup() { docker rm -f "$name" >/dev/null 2>&1 || true; rm -r -f "$work"; }
trap cleanup EXIT
cp -r fixtures/content "$work/content"
cp -r fixtures/sources "$work/sources"
git -C "$work/content" init -q -b main
git -C "$work/content" add -A
git -C "$work/content" -c user.name=smoke -c user.email=smoke@example.com commit -q -m smoke
expected=$(git -C "$work/content" rev-parse HEAD)
# The repo goes in root-owned, as it would from a CI job running as root. git's local transport
# drops -c / GIT_CONFIG_* settings before upload-pack, so safe.directory must come from a config file.
printf '[safe]\n\tdirectory = *\n' > "$work/smoke.gitconfig"
chmod -R a+rX "$work"
docker create --name "$name" -e CONTENT_REPO=/content -e SOURCES_FIXTURES=/sources \
-e GIT_CONFIG_GLOBAL=/smoke.gitconfig "$image" >/dev/null
tar -C "$work" --owner=0 --group=0 -c content sources smoke.gitconfig | docker cp -q - "$name:/"
docker start "$name" >/dev/null
# GET a path from inside the container; prints the body, fails on a non-2xx status.
get() {
docker exec "$name" bun -e "const r = await fetch('http://localhost:8080$1'); if (!r.ok) process.exit(1); process.stdout.write(await r.text())"
}
live=''
for _ in $(seq 1 180); do
live=$(get /status 2>/dev/null | sed -n 's/.*"liveCommit": *"\([0-9a-f]*\)".*/\1/p' || true)
[ "$live" = "$expected" ] && break
sleep 1
done
if [ "$live" != "$expected" ]; then
echo "smoke: live commit '$live' != '$expected'"; docker logs "$name"; exit 1
fi
for path in / /work/ /off-the-clock/; do
get "$path" >/dev/null || { echo "smoke: $path did not return 200"; docker logs "$name"; exit 1; }
done
get / | grep -q 'Example Person' || { echo "smoke: / did not render the fixture content"; exit 1; }
get /status | grep -q '"sources": *{' || { echo "smoke: /status has no sources object"; get /status; exit 1; }
echo "smoke: ok ($expected)"