feat(fase-17): deploy script HEAD-tag check + tag column in deploy log
deploy-erosi.sh now runs `git describe --exact-match --tags HEAD` up front. When HEAD is not at a tag, prints a yellow warning and sleeps 5s so the operator can Ctrl-C and tag before the rsync starts (no abort — keeps untagged hotfix deploys possible). When a tag is present, surfaces it in the banner next to the SHA. `.deploys.log` gains a 4th tab-separated column: the tag (empty when absent). The 3-column compat for pre-Fase-17 rows is preserved — the rollback script's existing `cut -f1/-f2/-f3` keeps working, and `cut -f4` returns the empty string for the older rows. rollback-erosi.sh: - `--list` reformats each row through awk so the tag is visible (with "(no tag)" placeholder for older rows), falling back to the raw log when awk isn't on PATH. - The target banner shows `git tag: <tag>` when present. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,26 @@ REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|||||||
# rsync without `.git`, so the remote can't run `git rev-parse`.
|
# rsync without `.git`, so the remote can't run `git rev-parse`.
|
||||||
GIT_SHA="$(cd "$REPO_ROOT" && git rev-parse --short HEAD 2>/dev/null || echo dev)"
|
GIT_SHA="$(cd "$REPO_ROOT" && git rev-parse --short HEAD 2>/dev/null || echo dev)"
|
||||||
|
|
||||||
echo "==> Deploying to $DEPLOY_HOST:$DEPLOY_PATH (commit $GIT_SHA)"
|
# Fase 17.3 — capture the exact-match tag on HEAD (if any). Empty
|
||||||
|
# string when HEAD is between tags. Warn (don't block) when missing
|
||||||
|
# so untaggable hotfix deploys still go through, and stamp the tag
|
||||||
|
# into .deploys.log so the rollback script can surface it.
|
||||||
|
GIT_TAG="$(cd "$REPO_ROOT" && git describe --exact-match --tags HEAD 2>/dev/null || true)"
|
||||||
|
|
||||||
|
if [ -z "$GIT_TAG" ]; then
|
||||||
|
# ANSI yellow — visible enough to read past a terminal full of
|
||||||
|
# rsync output, but no exit. Sleep gives the operator a 5s window
|
||||||
|
# to Ctrl-C and tag HEAD before the rsync starts.
|
||||||
|
printf '\033[33mWARNING:\033[0m HEAD is not at a tagged commit. Deploys without a tag\n'
|
||||||
|
printf ' won'\''t map cleanly to CHANGELOG entries. Continue? [5s abort]\n'
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$GIT_TAG" ]; then
|
||||||
|
echo "==> Deploying to $DEPLOY_HOST:$DEPLOY_PATH (commit $GIT_SHA, tag $GIT_TAG)"
|
||||||
|
else
|
||||||
|
echo "==> Deploying to $DEPLOY_HOST:$DEPLOY_PATH (commit $GIT_SHA, no tag)"
|
||||||
|
fi
|
||||||
|
|
||||||
# ── 1. Ensure target dir exists ────────────────────────────────────────────
|
# ── 1. Ensure target dir exists ────────────────────────────────────────────
|
||||||
ssh "$DEPLOY_HOST" "sudo mkdir -p $DEPLOY_PATH && sudo chown \$(id -u):\$(id -g) $DEPLOY_PATH"
|
ssh "$DEPLOY_HOST" "sudo mkdir -p $DEPLOY_PATH && sudo chown \$(id -u):\$(id -g) $DEPLOY_PATH"
|
||||||
@@ -154,10 +173,15 @@ REMOTE
|
|||||||
# can substitute it into the Dockerfile build-arg (compose reads it from
|
# can substitute it into the Dockerfile build-arg (compose reads it from
|
||||||
# the same shell, not from .env, so a transient export is enough). ssh
|
# the same shell, not from .env, so a transient export is enough). ssh
|
||||||
# doesn't accept VAR=value args directly, so we prefix `env`.
|
# doesn't accept VAR=value args directly, so we prefix `env`.
|
||||||
ssh "$DEPLOY_HOST" env GIT_SHA="$GIT_SHA" bash -s << 'REMOTE'
|
#
|
||||||
|
# Fase 17.3.2: also forward GIT_TAG so the deploy log gets a 4th tab-
|
||||||
|
# separated column (empty string when HEAD is not at a tag — preserves
|
||||||
|
# the 3-column compat the rollback script's `cut -f1,2,3` already reads).
|
||||||
|
ssh "$DEPLOY_HOST" env GIT_SHA="$GIT_SHA" GIT_TAG="${GIT_TAG:-}" bash -s << 'REMOTE'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd /opt/colectivo
|
cd /opt/colectivo
|
||||||
: "${GIT_SHA:=dev}"
|
: "${GIT_SHA:=dev}"
|
||||||
|
: "${GIT_TAG:=}"
|
||||||
|
|
||||||
echo "--- Building app image (commit $GIT_SHA)"
|
echo "--- Building app image (commit $GIT_SHA)"
|
||||||
GIT_SHA="$GIT_SHA" docker compose --env-file .env -f infra/docker-compose.erosi.yml \
|
GIT_SHA="$GIT_SHA" docker compose --env-file .env -f infra/docker-compose.erosi.yml \
|
||||||
@@ -217,9 +241,13 @@ docker compose --env-file .env -f infra/docker-compose.erosi.yml exec -T db \
|
|||||||
-c "NOTIFY pgrst, 'reload schema';"
|
-c "NOTIFY pgrst, 'reload schema';"
|
||||||
|
|
||||||
# Record the successful deploy in .deploys.log (read by rollback-erosi.sh).
|
# Record the successful deploy in .deploys.log (read by rollback-erosi.sh).
|
||||||
|
# Format: <iso-ts>\t<sha>\t<backup-file>\t<tag-or-empty>
|
||||||
|
# The 4th column is Fase 17 — older rows have 3 columns; the rollback
|
||||||
|
# script's `cut -f4` returns empty for them, which is the right
|
||||||
|
# "no tag" sentinel.
|
||||||
backup_file=$(cat /tmp/.colectivo-last-backup 2>/dev/null || echo "")
|
backup_file=$(cat /tmp/.colectivo-last-backup 2>/dev/null || echo "")
|
||||||
deploy_ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
deploy_ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
printf '%s\t%s\t%s\n' "$deploy_ts" "$GIT_SHA" "$backup_file" \
|
printf '%s\t%s\t%s\t%s\n' "$deploy_ts" "$GIT_SHA" "$backup_file" "$GIT_TAG" \
|
||||||
>> /opt/colectivo/.deploys.log
|
>> /opt/colectivo/.deploys.log
|
||||||
rm -f /tmp/.colectivo-last-backup
|
rm -f /tmp/.colectivo-last-backup
|
||||||
echo "--- Recorded deploy in /opt/colectivo/.deploys.log"
|
echo "--- Recorded deploy in /opt/colectivo/.deploys.log"
|
||||||
|
|||||||
@@ -71,7 +71,19 @@ fi
|
|||||||
if [ "$MODE" = "list" ]; then
|
if [ "$MODE" = "list" ]; then
|
||||||
echo "Recent deploys ($DEPLOY_HOST):"
|
echo "Recent deploys ($DEPLOY_HOST):"
|
||||||
echo "------------------------------------------------------------"
|
echo "------------------------------------------------------------"
|
||||||
|
# Fase 17.3.3 — re-format each row so the tag (column 4, optional)
|
||||||
|
# is visible at a glance. Rows from before Fase 17 only have 3
|
||||||
|
# columns; the 4th `cut` returns empty and we substitute "(no tag)".
|
||||||
|
# Falls back to the raw log if awk isn't present (it always is on
|
||||||
|
# the deploy host, but we want the script to be robust on any
|
||||||
|
# operator laptop).
|
||||||
|
if command -v awk >/dev/null 2>&1; then
|
||||||
|
printf '%s\n' "$log" \
|
||||||
|
| awk -F '\t' '{ tag = ($4 == "" ? "(no tag)" : $4); printf "%s\t%s\t%s\t%s\n", $1, $2, tag, $3 }' \
|
||||||
|
| nl -ba
|
||||||
|
else
|
||||||
printf '%s\n' "$log" | nl -ba
|
printf '%s\n' "$log" | nl -ba
|
||||||
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -91,10 +103,15 @@ fi
|
|||||||
target_ts=$(printf '%s' "$target_row" | cut -f1)
|
target_ts=$(printf '%s' "$target_row" | cut -f1)
|
||||||
target_sha=$(printf '%s' "$target_row" | cut -f2)
|
target_sha=$(printf '%s' "$target_row" | cut -f2)
|
||||||
target_backup=$(printf '%s' "$target_row" | cut -f3)
|
target_backup=$(printf '%s' "$target_row" | cut -f3)
|
||||||
|
# Fase 17.3.3 — 4th column is the tag (optional, empty on pre-Fase-17 rows).
|
||||||
|
target_tag=$(printf '%s' "$target_row" | cut -f4)
|
||||||
|
|
||||||
echo "==> Rollback target"
|
echo "==> Rollback target"
|
||||||
echo " timestamp: $target_ts"
|
echo " timestamp: $target_ts"
|
||||||
echo " git sha: $target_sha"
|
echo " git sha: $target_sha"
|
||||||
|
if [ -n "${target_tag:-}" ]; then
|
||||||
|
echo " git tag: $target_tag"
|
||||||
|
fi
|
||||||
echo " backup: $target_backup"
|
echo " backup: $target_backup"
|
||||||
|
|
||||||
# ── 3. Verify SHA + backup ───────────────────────────────────────────────
|
# ── 3. Verify SHA + backup ───────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user