bin/azure_vm_deploy.sh pulled from `origin` (xiaohei/heicode.git) when GIT_REF was set. Production VM now tracks heicode-win/main and that's where the rebrand + bug fixes ship — pulling from origin would silently revert all of it on the next deploy. New GIT_REMOTE env var (defaults to heicode-win) lets operators override for one-off cherry-pick deploys. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
2.7 KiB
Bash
Executable File
84 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Azure VM deployment script with canary gate and rollback pointer.
|
|
# Prerequisites:
|
|
# - SSH access to VM
|
|
# - docker + docker compose installed on VM
|
|
# - project already synced to VM path
|
|
#
|
|
# Example:
|
|
# VM_HOST=20.1.2.3 VM_USER=azureuser REMOTE_DIR=/opt/heicode/heicode \
|
|
# IMAGE_TAG=heicode-manager:local ./bin/azure_vm_deploy.sh
|
|
|
|
VM_HOST="${VM_HOST:-}"
|
|
VM_USER="${VM_USER:-azureuser}"
|
|
REMOTE_DIR="${REMOTE_DIR:-/opt/heicode/heicode}"
|
|
IMAGE_TAG="${IMAGE_TAG:-heicode-manager:local}"
|
|
HEALTH_URL="${HEALTH_URL:-http://127.0.0.1:3000/api/status}"
|
|
COMPOSE_FILES="${COMPOSE_FILES:--f docker-compose.azure-vm.yml -f docker-compose.override.yml}"
|
|
ENV_FILE="${ENV_FILE:-.env}"
|
|
SSH_OPTS="${SSH_OPTS:-}"
|
|
# Prod VM tracks heicode-win/main (chenchen/heicode-win.git). The legacy
|
|
# `origin` remote (xiaohei/heicode.git) does not receive the rebrand + bug
|
|
# fixes that ship to production. Override to "origin" only for one-off
|
|
# cherry-pick deployments.
|
|
GIT_REMOTE="${GIT_REMOTE:-heicode-win}"
|
|
GIT_REF="${GIT_REF:-}"
|
|
|
|
if [[ -z "${VM_HOST}" ]]; then
|
|
echo "ERROR: VM_HOST is required"
|
|
exit 1
|
|
fi
|
|
|
|
REMOTE="${VM_USER}@${VM_HOST}"
|
|
SSH="ssh ${SSH_OPTS} ${REMOTE}"
|
|
|
|
echo "== Azure VM deploy start =="
|
|
echo "remote=${REMOTE}"
|
|
echo "dir=${REMOTE_DIR}"
|
|
echo "image=${IMAGE_TAG}"
|
|
echo "compose_files=${COMPOSE_FILES}"
|
|
echo "env_file=${ENV_FILE}"
|
|
if [[ -n "${GIT_REF}" ]]; then
|
|
echo "git_ref=${GIT_REF}"
|
|
fi
|
|
|
|
${SSH} "cd '${REMOTE_DIR}' && \
|
|
test -f '${ENV_FILE}' && \
|
|
test -f docker-compose.azure-vm.yml && \
|
|
docker compose version >/dev/null && \
|
|
git rev-parse --is-inside-work-tree >/dev/null"
|
|
|
|
if [[ -n "${GIT_REF}" ]]; then
|
|
${SSH} "cd '${REMOTE_DIR}' && \
|
|
git fetch --prune ${GIT_REMOTE} && \
|
|
git checkout '${GIT_REF}' && \
|
|
git pull --ff-only ${GIT_REMOTE} '${GIT_REF}'"
|
|
fi
|
|
|
|
# Persist previous image for rollback.
|
|
${SSH} "cd '${REMOTE_DIR}' && \
|
|
PREV=\$(docker inspect --format='{{.Config.Image}}' heicode 2>/dev/null || true) && \
|
|
echo \"\${PREV}\" > .last_success_image && \
|
|
echo \"last_success_image=\${PREV}\""
|
|
|
|
# Update compose image tag and redeploy.
|
|
${SSH} "cd '${REMOTE_DIR}' && \
|
|
ENV_FILE='${ENV_FILE}' docker compose ${COMPOSE_FILES} --env-file '${ENV_FILE}' pull heicode || true && \
|
|
ENV_FILE='${ENV_FILE}' IMAGE_TAG='${IMAGE_TAG}' docker compose ${COMPOSE_FILES} --env-file '${ENV_FILE}' up -d --build --force-recreate heicode"
|
|
|
|
echo "Waiting for health endpoint..."
|
|
for i in {1..20}; do
|
|
if ${SSH} "curl -fsS '${HEALTH_URL}' | grep -q '\"success\":true'"; then
|
|
echo "Health check passed."
|
|
echo "${IMAGE_TAG}" | ${SSH} "cat > '${REMOTE_DIR}/.last_success_image'"
|
|
echo "Deploy completed."
|
|
exit 0
|
|
fi
|
|
sleep 3
|
|
done
|
|
|
|
echo "Health check failed. Run rollback script."
|
|
exit 2
|