This commit is contained in:
2026-09-24 18:50:08 -03:00
parent 4417645639
commit f7bcad0b38
3 changed files with 69 additions and 20 deletions
+57 -11
View File
@@ -6,7 +6,7 @@
# - Image name/tag default to pom.xml properties (artifactId and version)
# - Builds for linux/amd64 by default (cross-compile from arm64 hosts)
# - Transfers layers over the tunnel (no external registry required)
# - On the remote, tags the image as <version>, latest, and vYYYY.MM.DD-HH.MM (UTC)
# - On the remote, durable tags are :latest and vYYYY.MM.DD-HH.MM (UTC) only
set -euo pipefail
IFS=$'\n\t'
@@ -65,8 +65,8 @@ Required:
Image identity (defaults read from pom.xml):
--name NAME Image repository name
--tag TAG Version tag. The remote also receives :latest
and a vYYYY.MM.DD-HH.MM release tag (UTC).
--tag TAG Local build tag (from pom.xml by default). On the
remote only :latest and vYYYY.MM.DD-HH.MM (UTC).
Working directory (defaults to the parent of the script's directory):
--project-dir PATH Project root containing pom.xml
@@ -84,9 +84,9 @@ Post-push:
--no-verify Skip the ssh/docker images verification step
Maintenance:
--cleanup Remove leftover temporary registry containers and
localhost:<port>/... image tags on the remote
(no build, no push; Docker local not required)
--cleanup Remove temporary registry leftovers on the remote,
drop stale tags (version, sha256-*, etc.), and keep
at most two app images (current + previous release)
Other:
-h, --help Show this help
@@ -237,6 +237,46 @@ cleanup_remote_registry() {
ok "Remote cleanup complete."
}
# Keep :latest plus the two newest vYYYY.MM.DD-HH.MM releases; drop other tags/IDs.
prune_remote_image_history() {
local repo="${1:-$IMAGE_NAME}"
[[ -n "$repo" ]] || return 0
log "Pruning ${repo} on remote (keep latest and previous release)…"
run_remote "bash -s" <<EOS
set -euo pipefail
RD='${REMOTE_DOCKER}'
REPO='${repo}'
release_re='^v[0-9]{4}\\.[0-9]{2}\\.[0-9]{2}-[0-9]{2}\\.[0-9]{2}\$'
rmi_ref() {
\${RD} rmi "\$1" 2>/dev/null || true
}
while IFS= read -r ref; do
tag="\${ref#*:}"
[[ "\$tag" == latest ]] && continue
if [[ "\$tag" =~ \${release_re} ]]; then continue; fi
rmi_ref "\$ref"
done < <(\${RD} images --format '{{.Repository}}:{{.Tag}}' | grep -E "^\${REPO}:" || true)
mapfile -t release_refs < <(\${RD} images --format '{{.Repository}}:{{.Tag}}' | grep -E "^\${REPO}:v[0-9]{4}\\." | sort -t: -k2)
declare -A keep_ids=()
n=\${#release_refs[@]}
if (( n == 0 )); then exit 0; fi
for (( i=n-1; i>=0 && i>=n-2; i-- )); do
id=\$(\${RD} images --format '{{.ID}}' "\${release_refs[i]}" | head -1)
[[ -n "\$id" ]] && keep_ids["\$id"]=1
done
while IFS= read -r ref; do
id=\$(\${RD} images --format '{{.ID}}' "\$ref" | head -1)
[[ -n "\${keep_ids[\$id]:-}" ]] && continue
rmi_ref "\$ref"
done < <(\${RD} images --format '{{.Repository}}:{{.Tag}}' | grep -E "^\${REPO}:" || true)
EOS
ok "Remote ${repo} pruned."
}
REG_PUSH_CONTAINER=""
REG_REMOTE_PORT=""
REG_LOCAL_PORT=""
@@ -324,13 +364,13 @@ push_via_registry_tunnel() {
docker tag "$IMAGE_REF" "$latest_ref"
docker tag "$IMAGE_REF" "$RELEASE_REF"
log "Pulling image on remote and tagging ${IMAGE_REF}, ${latest_ref}, ${RELEASE_REF}…"
log "Pulling image on remote and tagging ${latest_ref}, ${RELEASE_REF}…"
run_remote "${REMOTE_DOCKER} pull ${remote_registry_ref}"
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${IMAGE_REF}"
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${latest_ref}"
run_remote "${REMOTE_DOCKER} tag ${remote_registry_ref} ${RELEASE_REF}"
run_remote "${REMOTE_DOCKER} rmi ${remote_registry_ref}" >/dev/null || true
ok "Remote tags: ${IMAGE_REF}, ${latest_ref}, ${RELEASE_REF}."
prune_remote_image_history "${IMAGE_NAME}"
ok "Remote tags: ${latest_ref}, ${RELEASE_REF}."
}
# ---------- arg parsing ----------
@@ -368,10 +408,16 @@ fi
if [[ "$CLEANUP" -eq 1 ]]; then
log "Remote: ${REMOTE_TARGET}"
require ssh
if ! cd "${PROJECT_DIR}" 2>/dev/null; then
die "Invalid --project-dir: ${PROJECT_DIR}"
fi
[[ -z "$IMAGE_NAME" ]] \
&& IMAGE_NAME=$(read_pom "/*[local-name()='project']/*[local-name()='artifactId']" "test-quarkus" "artifactId")
parse_ssh_target
build_ssh_args
detect_remote_docker
cleanup_remote_registry
prune_remote_image_history "${IMAGE_NAME}"
exit 0
fi
@@ -441,14 +487,14 @@ else
log "Verifying tags on ${REMOTE_TARGET}…"
remote_images=$(run_remote "${REMOTE_DOCKER} images --format '{{.Repository}}:{{.Tag}}'")
missing=0
for ref in "${IMAGE_REF}" "${IMAGE_NAME}:latest" "${RELEASE_REF}"; do
for ref in "${IMAGE_NAME}:latest" "${RELEASE_REF}"; do
if ! printf '%s\n' "$remote_images" | grep -Fxq "$ref"; then
err "Missing on remote: ${ref}"
missing=1
fi
done
[[ "$missing" -eq 0 ]] || die "Expected tags were not found on ${REMOTE_TARGET} after push."
ok "Remote has ${IMAGE_REF}, ${IMAGE_NAME}:latest and ${RELEASE_REF}."
ok "Remote has ${IMAGE_NAME}:latest and ${RELEASE_REF}."
fi
# ---------- next step hint ----------