From f7bcad0b38096e74fcebf4a5c94a1244e6f72d49 Mon Sep 17 00:00:00 2001 From: Daniel Arroyo Date: Thu, 24 Sep 2026 18:50:08 -0300 Subject: [PATCH] cambios --- README.md | 19 ++++++----- pom.xml | 2 +- scripts/build-and-push.sh | 68 ++++++++++++++++++++++++++++++++------- 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 6000393..1ee2d65 100644 --- a/README.md +++ b/README.md @@ -16,16 +16,19 @@ remote Docker daemon. No external registry is required. ./scripts/build-and-push.sh --remote deploy@prod.example.com ``` -The script reads `artifactId` and `version` from `pom.xml` for the image name -and version tag, builds for `linux/amd64`, and verifies the image is present on -the remote after pushing. On the remote (and locally) that push is tagged three -ways, all pointing at the same image: +The script reads `artifactId` and `version` from `pom.xml` for the local build tag +and image name, builds for `linux/amd64`, and verifies the deploy on the remote. +On the remote, durable tags are only: -- `:` — the version from `pom.xml` or `--tag` -- `:latest` — moved to this push on every successful deploy -- `:vYYYY.MM.DD-HH.MM` — UTC timestamp of the push (for rollback; list with `docker images`) +- `:latest` — always the most recent successful push +- `:vYYYY.MM.DD-HH.MM` — UTC timestamp of that push (for rollback) -To roll back on the remote, pick an older `v…` tag from `docker images test-quarkus` and run that reference instead of `:latest`. +Older releases stay tagged by date only: the script keeps the current image (with +`latest` and its date tag) and the previous date tag, and removes other tags and +images (including old `1.0.x`, `sha256-*`, and third copies). Run +`--cleanup` on the remote to apply the same pruning without a new push. + +To roll back on the remote, run a previous `v…` tag from `docker images` instead of `:latest`. The temporary registry container and SSH tunnel are removed when the script finishes. See `./scripts/build-and-push.sh --help` for all flags. diff --git a/pom.xml b/pom.xml index 485ae07..bdb9cc2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.example test-quarkus - 1.0.2 + 1.0.3 jar Test Quarkus diff --git a/scripts/build-and-push.sh b/scripts/build-and-push.sh index a0f5c94..1e5eaeb 100755 --- a/scripts/build-and-push.sh +++ b/scripts/build-and-push.sh @@ -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 , 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:/... 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" </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 ----------