Files
chenchenandClaude Opus 4.7 b91a68fe2b ops(deploy): default Azure VM deploy to pull from heicode-win remote
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>
2026-05-11 17:25:57 +08:00

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