Files
adcloud-advertiser-console/deploy/deploy.sh
T
codex-bot 8d319fb34e
Advertiser console CI and test deployment / build-deploy (push) Failing after 1m4s
Validate candidate pages before public ingress and deployment checks
2026-09-16 15:21:08 +08:00

60 lines
2.9 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
name=adcloud-advertiser-console
image="adcloud-advertiser:${SOURCE_REVISION:?}"
port="${DEPLOY_PORT:-18081}"
[[ "$port" =~ ^[0-9]+$ ]] && (( port > 0 && port < 65536 )) || { echo 'Invalid deploy port'; exit 1; }
case "${API_UPSTREAM:?}" in http://*|https://*) ;; *) echo 'Invalid API upstream'; exit 1;; esac
# A unique candidate verifies the proxy before replacing the published service.
candidate="${name}-candidate-${SOURCE_REVISION:0:12}"
cleanup() { docker rm -f "$candidate" >/dev/null 2>&1 || true; }
trap cleanup EXIT
docker run -d --name "$candidate" --add-host host.docker.internal:host-gateway -e API_UPSTREAM "$image"
ready=false
for attempt in {1..30}; do
if docker exec "$candidate" wget -q -O /dev/null http://127.0.0.1/healthz; then ready=true; break; fi
sleep 1
done
[[ "$ready" == true ]] || { echo 'Candidate failed health check'; exit 1; }
# Auth endpoint should exist and reject unauthenticated requests, rather than 404/502.
docker exec "$candidate" sh -c 'wget -S -O /dev/null http://127.0.0.1/v1/advertiser/me 2>&1 | grep "401 Unauthorized"'
# Validate functionality on the runner before changing the published service.
# This loopback origin is already permitted by the API's development CORS policy.
docker run --rm --network "container:$candidate" --shm-size=256m -e BASE_URL=http://localhost:5173 "adcloud-advertiser:$SOURCE_REVISION-tests"
old=false
if docker container inspect "$name" >/dev/null 2>&1; then
docker stop "$name"
docker rename "$name" "${name}-previous"
old=true
fi
rollback() {
docker rm -f "$name" >/dev/null 2>&1 || true
if [[ "$old" == true ]]; then docker rename "${name}-previous" "$name"; docker start "$name"; fi
}
if ! docker run -d --name "$name" --restart unless-stopped --add-host host.docker.internal:host-gateway -p "$port:80" -e API_UPSTREAM "$image"; then rollback; exit 1; fi
ready=false
for attempt in {1..30}; do
if docker exec "$name" wget -q -O /dev/null http://127.0.0.1/healthz; then ready=true; break; fi
sleep 1
done
if [[ "$ready" != true ]]; then rollback; exit 1; fi
if ! docker exec "$candidate" wget -q -O /dev/null "http://host.docker.internal:$port/healthz"; then
echo "Published port probe failed; restoring previous deployment"
rollback
exit 1
fi
# Check public ingress from the CI container before opening the browser.
if ! curl --fail --silent --show-error --connect-timeout 10 --max-time 20 "${BASE_URL%/}/healthz"; then
echo 'Public frontend ingress is unreachable; check TCP 18081 security group / reverse proxy.'
rollback
exit 1
fi
# Use the runner's normal bridge network, like the successful public API probe.
if ! docker run --rm --shm-size=256m -e BASE_URL "adcloud-advertiser:$SOURCE_REVISION-tests"; then
echo 'Deployed browser checks failed; restoring previous frontend'
rollback
exit 1
fi
if [[ "$old" == true ]]; then docker rm "${name}-previous"; fi
echo "Advertiser console deployed on port $port, revision $SOURCE_REVISION"