Initial commit
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
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
This commit is contained in:
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user