From f93b7e4d31e87d0901b44ad40b9e41d5993016ca Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 12 Sep 2025 12:13:38 +0000 Subject: [PATCH] Pipeline fixes to mirror prod AR --- .woodpecker.yml | 60 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 1ed565b..67773dd 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -174,8 +174,60 @@ kind: pipeline type: docker name: prod-promotion +steps: + - name: promote-tag-and-mirror + image: google/cloud-sdk:latest + entrypoint: + - bash + - -c + - | + set -euo pipefail + [[ "${PROMOTE:-}" == "prod" ]] || { echo "⏭ Skipping (PROMOTE=$PROMOTE)"; exit 0; } + + # Dev is the single source of truth for IMG_TAG + IMG_TAG="$(gcloud secrets versions access latest --secret=IMG_TAG --project=aptivaai-dev)" + SRC="us-central1-docker.pkg.dev/aptivaai-dev/aptiva-repo" + DST="us-central1-docker.pkg.dev/aptivaai-prod/aptiva-repo" + + apt-get update -qq + apt-get install -y -qq docker.io + gcloud auth configure-docker us-central1-docker.pkg.dev -q + + for svc in server1 server2 server3 nginx; do + docker pull "$SRC/$svc:$IMG_TAG" + docker tag "$SRC/$svc:$IMG_TAG" "$DST/$svc:$IMG_TAG" + docker push "$DST/$svc:$IMG_TAG" + done + + # Publish the exact tag to prod SM so deploy & scan read the same value + printf "%s" "${IMG_TAG}" | gcloud secrets versions add IMG_TAG --data-file=- --project="aptivaai-prod" >/dev/null + echo "🏷 Promoted IMG_TAG=${IMG_TAG} → aptivaai-prod & mirrored images" + + - name: verify-sync + depends_on: [promote-tag-and-mirror] + image: google/cloud-sdk:latest + entrypoint: + - bash + - -c + - | + set -euo pipefail + [[ "${PROMOTE:-}" == "prod" ]] || { echo "⏭ Skipping (PROMOTE=$PROMOTE)"; exit 0; } + IMG_TAG="$(gcloud secrets versions access latest --secret=IMG_TAG --project=aptivaai-dev)" + prod_val="$(gcloud secrets versions access latest --secret=IMG_TAG --project=aptivaai-prod)" + [[ "$IMG_TAG" == "$prod_val" ]] || { echo "❌ Tag mismatch: dev=$IMG_TAG prod=$prod_val"; exit 1; } + echo "✅ Tag parity confirmed: $IMG_TAG" + # Ensure images truly exist in PROD AR + DST="us-central1-docker.pkg.dev/aptivaai-prod/aptiva-repo" + apt-get update -qq && apt-get install -y -qq docker.io + gcloud auth configure-docker us-central1-docker.pkg.dev -q + for svc in server1 server2 server3 nginx; do + docker pull "$DST/$svc:$IMG_TAG" >/dev/null + done + echo "✅ Prod AR has all images at :$IMG_TAG" + steps: - name: security-scan + depends_on: [verify-sync] image: google/cloud-sdk:latest entrypoint: - bash @@ -223,8 +275,9 @@ steps: PROD_SSH_TARGET="$(gcloud secrets versions access latest --secret=PROD_SSH_TARGET --project=aptivaai-dev)" - # Use the IMG_TAG stored in PROD (the exact one mirrored there) - IMG_TAG="$(gcloud secrets versions access latest --secret=IMG_TAG --project=aptivaai-prod)" + # single source of truth for deploy as well + IMG_TAG="$(gcloud secrets versions access latest --secret=IMG_TAG --project=aptivaai-dev)" + echo "🔑 SSH prerequisites installed" @@ -238,6 +291,9 @@ steps: PROJECT=aptivaai-prod; \ ENV=prod; \ export IMG_TAG='"$IMG_TAG"'; \ + # sanity: ensure prod SM matches the single source (dev) before pull + prod_val=$(gcloud secrets versions access latest --secret=IMG_TAG --project=$PROJECT); \ + [ "$prod_val" = "$IMG_TAG" ] || { echo "❌ Prod SM IMG_TAG ($prod_val) != dev IMG_TAG ($IMG_TAG)"; exit 1; }; \ \ # Pull all runtime secrets from aptivaai-prod JWT_SECRET=$(gcloud secrets versions access latest --secret=JWT_SECRET_$ENV --project=$PROJECT); export JWT_SECRET; \