chore(release): add runtime image artifact deploy
This commit is contained in:
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
VERSION="${1:-${RELEASE_VERSION:-}}"
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "Usage: $0 <version>"
|
||||
echo "Example: $0 v0.1.5"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ROOT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-$ROOT_DIR/dist/release-images}"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
API_IMAGE="xiaoxia-saas-api:$VERSION"
|
||||
WORKER_IMAGE="xiaoxia-saas-worker:$VERSION"
|
||||
API_LATEST="xiaoxia-saas-api:dev"
|
||||
WORKER_LATEST="xiaoxia-saas-worker:dev"
|
||||
TAR_PATH="$OUTPUT_DIR/xiaoxia-runtime-images-$VERSION.tar"
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
docker build --pull=false -f infra/docker/api.Dockerfile -t "$API_IMAGE" -t "$API_LATEST" .
|
||||
docker build --pull=false -f infra/docker/worker.Dockerfile -t "$WORKER_IMAGE" -t "$WORKER_LATEST" .
|
||||
docker save "$API_IMAGE" "$API_LATEST" "$WORKER_IMAGE" "$WORKER_LATEST" -o "$TAR_PATH"
|
||||
|
||||
printf '%s\n' "$TAR_PATH"
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
VERSION="${1:-${RELEASE_VERSION:-}}"
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "Usage: $0 <version> <runtime-images.tar>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IMAGE_TAR="${2:-${RUNTIME_IMAGE_TAR:-}}"
|
||||
if [ -z "$IMAGE_TAR" ]; then
|
||||
echo "Usage: $0 <version> <runtime-images.tar>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HOST_PREFIX="${HOST_PREFIX-/host}"
|
||||
PRODUCTION_ROOT="$HOST_PREFIX/var/lib/xiaoxia-saas-production"
|
||||
REPO_DIR="$PRODUCTION_ROOT/repo"
|
||||
ENV_FILE="$PRODUCTION_ROOT/.env"
|
||||
TARGET_TAR="$PRODUCTION_ROOT/runtime-images-$VERSION.tar"
|
||||
|
||||
if [ ! -f "$IMAGE_TAR" ]; then
|
||||
echo "Missing runtime image tar: $IMAGE_TAR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$REPO_DIR" ]; then
|
||||
echo "Missing production repo artifact: $REPO_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "Missing production env file: $ENV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$PRODUCTION_ROOT"
|
||||
cp "$IMAGE_TAR" "$TARGET_TAR"
|
||||
docker load -i "$TARGET_TAR"
|
||||
|
||||
cd "$REPO_DIR/infra/docker"
|
||||
export COMPOSE_PROJECT_NAME=xiaoxia-production-app
|
||||
export WEB_DOCKERFILE=infra/docker/web-artifact.Dockerfile
|
||||
export WEB_NGINX_CONF=infra/docker/nginx-production.conf
|
||||
export API_IMAGE="xiaoxia-saas-api:$VERSION"
|
||||
export WORKER_IMAGE="xiaoxia-saas-worker:$VERSION"
|
||||
export ALLOW_PRODUCTION_BUILDS=false
|
||||
|
||||
if [ ! -f "$REPO_DIR/apps/web/dist/index.html" ]; then
|
||||
echo "Missing prebuilt web artifact: $REPO_DIR/apps/web/dist/index.html"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "$ENV_FILE" "$REPO_DIR/.env"
|
||||
docker compose --env-file "$ENV_FILE" build --pull=false web
|
||||
docker compose --env-file "$ENV_FILE" run --rm --no-deps api sh -c '
|
||||
cd /app &&
|
||||
python /app/scripts/validate_release_env.py --from-environ --strict-external &&
|
||||
alembic upgrade head
|
||||
'
|
||||
docker compose --env-file "$ENV_FILE" up -d api worker web
|
||||
docker compose --env-file "$ENV_FILE" ps
|
||||
@@ -148,6 +148,22 @@ def test_subscription_api_is_not_wired_to_ui_until_backend_exists():
|
||||
assert importers == []
|
||||
|
||||
|
||||
def test_runtime_image_release_scripts_keep_builds_off_production():
|
||||
build_script = Path("scripts/build_release_images.sh").read_text(encoding="utf-8")
|
||||
deploy_script = Path("scripts/deploy_release_images_production.sh").read_text(encoding="utf-8")
|
||||
|
||||
assert "docker build --pull=false -f infra/docker/api.Dockerfile" in build_script
|
||||
assert "docker build --pull=false -f infra/docker/worker.Dockerfile" in build_script
|
||||
assert "docker save" in build_script
|
||||
assert "docker load -i" in deploy_script
|
||||
assert "API_IMAGE=\"xiaoxia-saas-api:$VERSION\"" in deploy_script
|
||||
assert "WORKER_IMAGE=\"xiaoxia-saas-worker:$VERSION\"" in deploy_script
|
||||
assert "ALLOW_PRODUCTION_BUILDS=false" in deploy_script
|
||||
assert "docker compose --env-file \"$ENV_FILE\" build --pull=false web" in deploy_script
|
||||
assert "docker compose --env-file \"$ENV_FILE\" build --pull=false api" not in deploy_script
|
||||
assert "docker compose --env-file \"$ENV_FILE\" build --pull=false worker" not in deploy_script
|
||||
|
||||
|
||||
def test_backup_postgres_writes_manifest_and_version():
|
||||
script = Path("scripts/backup_postgres.sh").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user