51 lines
2.5 KiB
Bash
Executable File
51 lines
2.5 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 SITE_URL=https://example.invalid \
|
|
-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 /sitemap.xml | grep -q 'https://example.invalid/work/' || { echo "smoke: /sitemap.xml missing or without SITE_URL"; exit 1; }
|
|
get /status | grep -q '"sources": *{' || { echo "smoke: /status has no sources object"; get /status; exit 1; }
|
|
echo "smoke: ok ($expected)"
|