Files
Goldebek/scripts/deploy-and-verify.sh
T
Per Hoener 0d45331f5c
Deploy / validate-dispatch (push) Successful in 43s
Deploy / scheduled-rebuild-dev (push) Skipped
Deploy / scheduled-rebuild-master (push) Skipped
Deploy / rollback-dev (push) Skipped
Deploy / rollback-master (push) Skipped
Deploy / changes (push) Successful in 13s
Deploy / secret-scan (push) Successful in 9s
Deploy / app-quality (push) Successful in 11m21s
Deploy / security-deps (push) Successful in 14s
Deploy / context (push) Failing after 1s
Deploy / app-image (push) Skipped
Deploy / deploy-dev (push) Skipped
Deploy / deploy-master (push) Skipped
Initial commit
2026-09-18 23:37:19 +02:00

44 lines
1.9 KiB
Bash
Executable File

#!/bin/sh
set -eu
previous_image=""
app_container_id=""
wait_for_health() {
attempt=1
while [ "$attempt" -le 40 ]; do
status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' "$app_container_id" 2>/dev/null || echo unknown)"
[ "$status" = healthy ] && return 0
[ "$status" = unhealthy ] && return 1
sleep 3
attempt=$((attempt + 1))
done
return 1
}
verify_routes() {
docker exec -i "$app_container_id" node --input-type=module - <<'NODE'
const request = (path, init) => fetch(`http://127.0.0.1:3000${path}`, { signal: AbortSignal.timeout(20000), ...init });
for (const [path, text] of [["/", "Bereit für Ihre neue Website"], ["/kalender/", "Kalender"], ["/robots.txt", "Sitemap:"]]) {
const response = await request(path);
if (!response.ok || !(await response.text()).includes(text)) throw new Error(`${path} failed`);
}
const events = await request("/api/events");
const etag = events.headers.get("etag");
if (!events.ok || !etag || !Array.isArray(await events.json())) throw new Error("events failed");
if ((await request("/api/events", { headers: { "If-None-Match": etag } })).status !== 304) throw new Error("ETag failed");
for (const path of ["/health/live", "/health/ready"]) if (!(await request(path)).ok) throw new Error(`${path} failed`);
NODE
}
current_id="$(docker compose ps -q app 2>/dev/null || true)"
if [ -n "$current_id" ]; then previous_image="$(docker inspect --format '{{.Config.Image}}' "$current_id" 2>/dev/null || true)"; fi
if ! docker compose up -d --no-build --remove-orphans app; then exit 1; fi
app_container_id="$(docker compose ps -q app)"
if ! wait_for_health || ! verify_routes; then
docker compose ps || true
docker compose logs app || true
if [ -n "$previous_image" ]; then APP_IMAGE_NAME="$previous_image" docker compose up -d --no-build --remove-orphans app; fi
exit 1
fi