#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$repo_root" deploy_host="${DEPLOY_HOST:-AMS-DEV01}" deploy_user="${DEPLOY_USER:-zak}" prod_path="${PROD_DEPLOY_PATH:-/home/${deploy_user}/magent}" deploy_path="${BETA_DEPLOY_PATH:-/home/${deploy_user}/magent-beta}" beta_frontend_bind="${BETA_FRONTEND_BIND:-10.30.1.32}" ssh_opts="${DEPLOY_SSH_OPTS:-"-o StrictHostKeyChecking=yes"}" timestamp="$(date -u +%Y%m%dT%H%M%SZ)" remote="${deploy_user}@${deploy_host}" echo "Deploying tracked beta repository contents to ${remote}:${deploy_path}" git archive --format=tar HEAD | ssh ${ssh_opts} "${remote}" " set -e umask 077 mkdir -p '${deploy_path}' chmod 700 '${deploy_path}' backup_root=\"\${HOME}/magent-beta-backups/${timestamp}\" mkdir -p \"\${backup_root}\" chmod 700 \"\${backup_root}\" cd '${deploy_path}' for path in backend frontend docker-compose.yml docker-compose.hub.yml docker-compose.beta.yml Dockerfile README.md docker scripts .build_number .gitattributes .gitignore; do if [ -e \"\$path\" ]; then cp -a \"\$path\" \"\${backup_root}/\" fi done tar -xf - -C '${deploy_path}' if [ ! -f '${deploy_path}/.env' ] && [ -f '${prod_path}/.env' ]; then cp '${prod_path}/.env' '${deploy_path}/.env' fi if [ -f '${deploy_path}/.env' ]; then chmod 600 '${deploy_path}/.env' fi mkdir -p '${deploy_path}/data' chmod 700 '${deploy_path}/data' if [ ! -f '${deploy_path}/data/magent.db' ] && [ -d '${prod_path}/data' ]; then cp -a '${prod_path}/data/.' '${deploy_path}/data/' fi cd '${deploy_path}' docker compose -p magent-beta -f docker-compose.beta.yml build if ! grep -Eq '^[[:space:]]*SETTINGS_ENCRYPTION_KEY=' .env; then settings_key=\"\$(docker compose -p magent-beta -f docker-compose.beta.yml run --rm --no-deps --entrypoint python magent -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')\" printf '\nSETTINGS_ENCRYPTION_KEY=%s\n' \"\${settings_key}\" >> .env chmod 600 .env fi docker compose -p magent-beta -f docker-compose.beta.yml run --rm --no-deps --entrypoint python magent -c \"from app.config import settings; from app.secret_storage import validate_secret_storage_configuration; assert len(str(settings.jwt_secret or '').strip()) >= 32, 'JWT_SECRET must contain at least 32 characters'; validate_secret_storage_configuration()\" docker compose -p magent-beta -f docker-compose.beta.yml run --rm --user 0 magent chown -R 1000:1000 /app/data docker compose -p magent-beta -f docker-compose.beta.yml up -d " echo "Running remote beta smoke checks" ssh ${ssh_opts} "${remote}" " set -e python3 - <<'PY' import time from urllib import error, request checks = [ ('http://127.0.0.1:8100/health', 200), ('http://${beta_frontend_bind}:3100/login', 200), ] # Compose returns before the app is ready. Allow the new processes to start # instead of reporting a failed deployment on the first connection reset. deadline = time.monotonic() + 90 for url, expected in checks: while True: try: with request.urlopen(url, timeout=5) as response: if response.status != expected: raise OSError(f'HTTP {response.status}, expected {expected}') print(url, response.status) break except (error.URLError, OSError, TimeoutError) as exc: if time.monotonic() >= deadline: raise SystemExit(f'Beta did not become ready: {url}: {exc}') from exc print(f'Waiting for beta to start: {url}', flush=True) time.sleep(2) PY " echo "Beta deployment completed successfully"