mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
ci: smoke-test the release image before publishing to Docker Hub (#487)
Starts the already-loaded localhost/sencho:release-scan image headless on the runner and polls /api/health for up to 30 seconds. Catches entrypoint regressions, native module ABI breakage, and first-boot crashes on the exact artifact that the multi-arch push step below will republish moments later. Placed BEFORE the build-push step so a smoke failure does not move the `latest`, semver, or minor tags on Docker Hub. The image reused here is the same amd64 artifact Trivy scanned a step earlier, so there is no extra build or pull on the critical path. The container is started without --rm so that docker logs in the trap can surface the stack trace when the container crashes during boot; the trap force-removes it after capturing logs whether it exited or is still running. /api/health is public and returns before any DB, JWT, or Docker socket work, so no env vars, volume mounts, or bind mounts are required for the smoke test to be a valid signal that the process booted and the HTTP server is accepting connections.
This commit is contained in:
@@ -100,6 +100,34 @@ jobs:
|
||||
severity: 'CRITICAL,HIGH'
|
||||
format: 'table'
|
||||
|
||||
# Start the scanned image headless on the runner and poll /api/health
|
||||
# until it returns 200. Catches entrypoint regressions, native module
|
||||
# ABI breakage, and first-boot crashes on the exact artifact that the
|
||||
# multi-arch push below will republish moments later. Intentionally
|
||||
# placed BEFORE the publish step so a smoke failure does not move
|
||||
# `latest` or the semver tags on Docker Hub. The health endpoint is
|
||||
# public and returns before any DB or Docker-socket work, so the
|
||||
# container only needs a free port, no env vars, and no volume mounts.
|
||||
- name: Smoke test release image (pre-publish)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Not using --rm so that a crashed container sticks around long
|
||||
# enough for `docker logs` in the trap to surface the stack trace.
|
||||
# The trap force-removes it explicitly whether it is still running
|
||||
# or already exited.
|
||||
docker run -d --name sencho-smoke -p 3000:3000 localhost/sencho:release-scan
|
||||
trap 'docker logs sencho-smoke 2>&1 || true; docker rm -f sencho-smoke >/dev/null 2>&1 || true' EXIT
|
||||
for i in $(seq 1 30); do
|
||||
if curl -fsS http://localhost:3000/api/health >/dev/null 2>&1; then
|
||||
echo "Container healthy after ${i}s"
|
||||
curl -s http://localhost:3000/api/health
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "FAILED: /api/health did not become ready within 30s"
|
||||
exit 1
|
||||
|
||||
- name: Build and push Docker image
|
||||
id: build
|
||||
uses: docker/build-push-action@v7
|
||||
|
||||
Reference in New Issue
Block a user