feat(ecommerce): release Ari Shopping Frontend v2
Build and Push Frontend / build (push) Successful in 1m57s
Build and Push Frontend / build (push) Successful in 1m57s
This commit is contained in:
+25
-456
@@ -1,33 +1,29 @@
|
||||
name: Build, Push and Validate Frontend
|
||||
name: Build and Push Frontend
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'workloads/ecommerce/index.html'
|
||||
- 'workloads/ecommerce/Dockerfile'
|
||||
- 'workloads/ecommerce/**'
|
||||
- '.gitea/workflows/build.yaml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
timeout-minutes: 20 # Aumentamos a 20 min para evitar que se corte el clone
|
||||
steps:
|
||||
- name: Checkout del código
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 1 # IMPORTANTE: Solo descarga el último commit, no todo el historial
|
||||
|
||||
# 1. NUEVO: Generamos la versión semántica dinámica
|
||||
- name: Definir Versión Semántica
|
||||
id: vars
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="v1.0.${{ gitea.run_number }}"
|
||||
echo "VERSION=${VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "Versión generada: ${VERSION}"
|
||||
# Formato v1.0.X (X = número de ejecución del pipeline)
|
||||
echo "VERSION=v1.0.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Login en Gitea Registry
|
||||
uses: docker/login-action@v2
|
||||
@@ -36,6 +32,7 @@ jobs:
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
# 2. ACTUALIZADO: Usamos la nueva variable para los tags de Docker
|
||||
- name: Construir y Subir Imagen
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
@@ -45,453 +42,25 @@ jobs:
|
||||
gitea.cruzcloud.net/devops/ecommerce-frontend:${{ steps.vars.outputs.VERSION }}
|
||||
gitea.cruzcloud.net/devops/ecommerce-frontend:latest
|
||||
|
||||
# 3. ACTUALIZADO: Inyectamos la versión limpia en el manifiesto YAML
|
||||
- name: Actualizar Manifiesto GitOps (CD)
|
||||
shell: bash
|
||||
env:
|
||||
VERSION: ${{ steps.vars.outputs.VERSION }}
|
||||
MANIFEST: workloads/ecommerce/frontend.yaml
|
||||
IMAGE_REPOSITORY: gitea.cruzcloud.net/devops/ecommerce-frontend
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
git config user.name "Cristian Felipe"
|
||||
git config user.email "[email protected]"
|
||||
|
||||
for intento in 1 2 3; do
|
||||
echo "--------------------------------------------------"
|
||||
echo "Intento ${intento}/3"
|
||||
echo "Versión: ${VERSION}"
|
||||
echo "Manifiesto: ${MANIFEST}"
|
||||
echo "--------------------------------------------------"
|
||||
|
||||
git fetch origin main
|
||||
git checkout -B main origin/main
|
||||
|
||||
if [ ! -f "${MANIFEST}" ]; then
|
||||
echo "ERROR: no existe ${MANIFEST}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -qE "image:[[:space:]]*${IMAGE_REPOSITORY}:" "${MANIFEST}"; then
|
||||
echo "ERROR: no se encontró ${IMAGE_REPOSITORY} en ${MANIFEST}."
|
||||
grep -nE '^[[:space:]]*image:' "${MANIFEST}" || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed -i -E \
|
||||
"s|(image:[[:space:]]*${IMAGE_REPOSITORY}:).*|\\1${VERSION}|g" \
|
||||
"${MANIFEST}"
|
||||
|
||||
echo "Imagen resultante:"
|
||||
grep -nE '^[[:space:]]*image:' "${MANIFEST}" || true
|
||||
|
||||
git add "${MANIFEST}"
|
||||
|
||||
if git diff --cached --quiet; then
|
||||
echo "El manifiesto ya contiene ${VERSION}."
|
||||
break
|
||||
fi
|
||||
|
||||
git commit -m "chore: release ${VERSION} [skip ci]"
|
||||
|
||||
if git push origin HEAD:main; then
|
||||
echo "Manifiesto actualizado correctamente con ${VERSION}."
|
||||
break
|
||||
fi
|
||||
|
||||
if [ "${intento}" -eq 3 ]; then
|
||||
echo "ERROR: no fue posible actualizar main después de 3 intentos."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
espera=$((intento * 3))
|
||||
echo "origin/main cambió. Reintentando en ${espera} segundos..."
|
||||
sleep "${espera}"
|
||||
done
|
||||
|
||||
- name: Validar despliegue y tag ejecutado en Kubernetes
|
||||
shell: bash
|
||||
env:
|
||||
VERSION: ${{ steps.vars.outputs.VERSION }}
|
||||
IMAGE_REPOSITORY: gitea.cruzcloud.net/devops/ecommerce-frontend
|
||||
NAMESPACE: ecommerce
|
||||
DEPLOY_TIMEOUT_SECONDS: '420'
|
||||
KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_DATA }}
|
||||
K8S_SERVER: ${{ secrets.K8S_SERVER }}
|
||||
K8S_CA_B64: ${{ secrets.K8S_CA_B64 }}
|
||||
K8S_TOKEN: ${{ secrets.K8S_TOKEN }}
|
||||
K8S_TLS_SERVER_NAME: ${{ secrets.K8S_TLS_SERVER_NAME }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
EXPECTED_IMAGE="${IMAGE_REPOSITORY}:${VERSION}"
|
||||
KUBECONFIG_PATH="${RUNNER_TEMP:-/tmp}/kubeconfig"
|
||||
CA_PATH="${RUNNER_TEMP:-/tmp}/kubernetes-ca.crt"
|
||||
|
||||
echo "=================================================="
|
||||
echo "Validación posterior al despliegue"
|
||||
echo "Namespace: ${NAMESPACE}"
|
||||
echo "Imagen esperada: ${EXPECTED_IMAGE}"
|
||||
echo "Timeout: ${DEPLOY_TIMEOUT_SECONDS} segundos"
|
||||
echo "=================================================="
|
||||
|
||||
normalize_base64() {
|
||||
local value="$1"
|
||||
value="$(printf '%s' "${value}" | tr -d '\r\n\t ')"
|
||||
|
||||
if ! printf '%s' "${value}" |
|
||||
grep -Eq '^[A-Za-z0-9+/]*={0,2}$'; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
case $(( ${#value} % 4 )) in
|
||||
0) ;;
|
||||
2) value="${value}==" ;;
|
||||
3) value="${value}=" ;;
|
||||
1) return 1 ;;
|
||||
esac
|
||||
|
||||
printf '%s' "${value}"
|
||||
}
|
||||
|
||||
USE_ATOMIC_KUBECONFIG='false'
|
||||
KUBE_CONFIG_DATA="$(printf '%s' "${KUBE_CONFIG_DATA:-}" | tr -d '\r\n\t ')"
|
||||
|
||||
if [ -n "${KUBE_CONFIG_DATA}" ]; then
|
||||
echo 'Usando secret atómico KUBE_CONFIG_DATA.'
|
||||
|
||||
if ! KUBE_CONFIG_DATA="$(normalize_base64 "${KUBE_CONFIG_DATA}")"; then
|
||||
echo 'ERROR: KUBE_CONFIG_DATA no contiene Base64 válido.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! printf '%s' "${KUBE_CONFIG_DATA}" |
|
||||
base64 --decode > "${KUBECONFIG_PATH}" 2>/dev/null; then
|
||||
echo 'ERROR: no se pudo decodificar KUBE_CONFIG_DATA.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -q '^kind:[[:space:]]*Config' "${KUBECONFIG_PATH}"; then
|
||||
echo 'ERROR: KUBE_CONFIG_DATA no contiene un kubeconfig válido.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
USE_ATOMIC_KUBECONFIG='true'
|
||||
|
||||
# 1. Forzamos a Git a ignorar la historia local y sincronizarse 100% con el servidor
|
||||
git fetch origin main
|
||||
git reset --hard origin/main
|
||||
|
||||
# 2. Aplicamos el cambio de versión
|
||||
sed -i -E "s|(image: gitea.cruzcloud.net/devops/ecommerce-frontend:).*|\1${{ steps.vars.outputs.VERSION }}|g" workloads/ecommerce/frontend.yaml
|
||||
|
||||
# 3. Solo hacemos commit si realmente hubo un cambio
|
||||
git add workloads/ecommerce/frontend.yaml
|
||||
if git diff --cached --quiet; then
|
||||
echo "No hay cambios en el manifiesto."
|
||||
else
|
||||
echo 'KUBE_CONFIG_DATA no está configurado; usando secrets K8S_* de compatibilidad.'
|
||||
|
||||
for variable in K8S_SERVER K8S_CA_B64 K8S_TOKEN; do
|
||||
if [ -z "${!variable:-}" ]; then
|
||||
echo "ERROR: no está configurado el secret ${variable}."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
K8S_SERVER="$(printf '%s' "${K8S_SERVER}" | tr -d '\r\n\t ')"
|
||||
K8S_TOKEN="$(printf '%s' "${K8S_TOKEN}" | tr -d '\r\n')"
|
||||
K8S_CA_B64="$(printf '%s' "${K8S_CA_B64}" | tr -d '\r\n\t ')"
|
||||
K8S_TLS_SERVER_NAME="$(printf '%s' "${K8S_TLS_SERVER_NAME:-}" | tr -d '\r\n\t ')"
|
||||
|
||||
if ! printf '%s' "${K8S_SERVER}" |
|
||||
grep -Eq '^https://[^[:space:]]+:[0-9]+$'; then
|
||||
echo 'ERROR: K8S_SERVER no tiene un formato válido.'
|
||||
echo 'Ejemplo: https://192.168.68.61:46421'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if printf '%s' "${K8S_SERVER}" |
|
||||
grep -Eq '^https://(127\.0\.0\.1|localhost|0\.0\.0\.0)(:|/)'; then
|
||||
echo 'ERROR: K8S_SERVER usa una dirección no accesible desde el contenedor.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
K8S_SERVER_HOST="$(
|
||||
printf '%s' "${K8S_SERVER}" |
|
||||
sed -E 's#^https://\[?([^]]+)\]?:[0-9]+$#\1#'
|
||||
)"
|
||||
|
||||
if [ -z "${K8S_TLS_SERVER_NAME}" ]; then
|
||||
K8S_TLS_SERVER_NAME="${K8S_SERVER_HOST}"
|
||||
fi
|
||||
|
||||
if [ "${K8S_TLS_SERVER_NAME}" != "${K8S_SERVER_HOST}" ]; then
|
||||
echo 'ERROR: K8S_TLS_SERVER_NAME no coincide con el host de K8S_SERVER.'
|
||||
echo "Host de K8S_SERVER: ${K8S_SERVER_HOST}"
|
||||
echo "Valor esperado del secret K8S_TLS_SERVER_NAME: ${K8S_SERVER_HOST}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! K8S_CA_B64="$(normalize_base64 "${K8S_CA_B64}")"; then
|
||||
echo 'ERROR: K8S_CA_B64 no contiene Base64 válido.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! printf '%s' "${K8S_CA_B64}" |
|
||||
base64 --decode > "${CA_PATH}" 2>/dev/null; then
|
||||
echo 'ERROR: no se pudo decodificar K8S_CA_B64.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -q 'BEGIN CERTIFICATE' "${CA_PATH}"; then
|
||||
echo 'ERROR: K8S_CA_B64 no contiene un certificado PEM.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod 600 "${CA_PATH}"
|
||||
|
||||
{
|
||||
echo 'apiVersion: v1'
|
||||
echo 'kind: Config'
|
||||
echo 'clusters:'
|
||||
echo '- name: lab-cluster'
|
||||
echo ' cluster:'
|
||||
echo " server: ${K8S_SERVER}"
|
||||
echo " certificate-authority: ${CA_PATH}"
|
||||
echo " tls-server-name: ${K8S_TLS_SERVER_NAME}"
|
||||
echo 'users:'
|
||||
echo '- name: gitea-postdeploy-validator'
|
||||
echo ' user:'
|
||||
echo " token: ${K8S_TOKEN}"
|
||||
echo 'contexts:'
|
||||
echo '- name: gitea-postdeploy-validator'
|
||||
echo ' context:'
|
||||
echo ' cluster: lab-cluster'
|
||||
echo ' user: gitea-postdeploy-validator'
|
||||
echo " namespace: ${NAMESPACE}"
|
||||
echo 'current-context: gitea-postdeploy-validator'
|
||||
} > "${KUBECONFIG_PATH}"
|
||||
fi
|
||||
|
||||
chmod 600 "${KUBECONFIG_PATH}"
|
||||
export KUBECONFIG="${KUBECONFIG_PATH}"
|
||||
|
||||
if ! command -v kubectl >/dev/null 2>&1; then
|
||||
case "$(uname -m)" in
|
||||
x86_64) KUBECTL_ARCH='amd64' ;;
|
||||
aarch64|arm64) KUBECTL_ARCH='arm64' ;;
|
||||
*)
|
||||
echo "ERROR: arquitectura no soportada: $(uname -m)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
KUBECTL_VERSION="$(curl -fsSL https://dl.k8s.io/release/stable.txt)"
|
||||
echo "Instalando kubectl ${KUBECTL_VERSION} (${KUBECTL_ARCH})..."
|
||||
|
||||
curl -fsSLo /tmp/kubectl \
|
||||
"https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${KUBECTL_ARCH}/kubectl"
|
||||
curl -fsSLo /tmp/kubectl.sha256 \
|
||||
"https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${KUBECTL_ARCH}/kubectl.sha256"
|
||||
|
||||
echo "$(cat /tmp/kubectl.sha256) /tmp/kubectl" |
|
||||
sha256sum --check
|
||||
|
||||
chmod +x /tmp/kubectl
|
||||
export PATH="/tmp:${PATH}"
|
||||
fi
|
||||
|
||||
kubectl version --client
|
||||
|
||||
EFFECTIVE_SERVER="$(
|
||||
kubectl config view --raw --minify \
|
||||
-o jsonpath='{.clusters[0].cluster.server}'
|
||||
)"
|
||||
EFFECTIVE_TLS_NAME="$(
|
||||
kubectl config view --raw --minify \
|
||||
-o jsonpath='{.clusters[0].cluster.tls-server-name}'
|
||||
)"
|
||||
EFFECTIVE_CA_B64="$(
|
||||
kubectl config view --raw --minify \
|
||||
-o jsonpath='{.clusters[0].cluster.certificate-authority-data}'
|
||||
)"
|
||||
EFFECTIVE_TOKEN="$(
|
||||
kubectl config view --raw --minify \
|
||||
-o jsonpath='{.users[0].user.token}'
|
||||
)"
|
||||
|
||||
if [ -z "${EFFECTIVE_TOKEN}" ]; then
|
||||
echo 'ERROR: el kubeconfig no contiene un token de autenticación.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "API Server efectivo: ${EFFECTIVE_SERVER}"
|
||||
echo "TLS server name efectivo: ${EFFECTIVE_TLS_NAME:-<host del API Server>}"
|
||||
|
||||
if [ -n "${EFFECTIVE_CA_B64}" ]; then
|
||||
printf '%s' "${EFFECTIVE_CA_B64}" | base64 --decode > "${CA_PATH}"
|
||||
fi
|
||||
|
||||
if [ ! -s "${CA_PATH}" ] || ! grep -q 'BEGIN CERTIFICATE' "${CA_PATH}"; then
|
||||
echo 'ERROR: el kubeconfig no contiene una CA PEM válida.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
echo 'Huella SHA256 de la CA usada por el workflow:'
|
||||
openssl x509 -in "${CA_PATH}" -noout -fingerprint -sha256
|
||||
fi
|
||||
|
||||
TOKEN_METADATA="$(
|
||||
printf '%s' "${EFFECTIVE_TOKEN}" |
|
||||
python3 -c '
|
||||
import base64
|
||||
import datetime
|
||||
import json
|
||||
import sys
|
||||
|
||||
token = sys.stdin.read().strip()
|
||||
parts = token.split(".")
|
||||
if len(parts) != 3:
|
||||
print("formato=no-jwt")
|
||||
raise SystemExit(0)
|
||||
|
||||
payload = parts[1] + "=" * (-len(parts[1]) % 4)
|
||||
data = json.loads(base64.urlsafe_b64decode(payload.encode()))
|
||||
|
||||
subject = data.get("sub", "desconocido")
|
||||
expiration = data.get("exp")
|
||||
|
||||
if expiration is None:
|
||||
print(f"subject={subject}; expiracion=sin-exp")
|
||||
else:
|
||||
when = datetime.datetime.fromtimestamp(
|
||||
expiration, datetime.timezone.utc
|
||||
).isoformat()
|
||||
print(f"subject={subject}; expiracion={when}")
|
||||
'
|
||||
)"
|
||||
|
||||
echo "Identidad del token: ${TOKEN_METADATA}"
|
||||
|
||||
if ! kubectl get deployments \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--request-timeout='15s' >/dev/null; then
|
||||
echo "ERROR: no hay conectividad o permisos para leer Deployments en ${NAMESPACE}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Conectividad y permisos de lectura confirmados."
|
||||
|
||||
DEADLINE=$((SECONDS + DEPLOY_TIMEOUT_SECONDS))
|
||||
DEPLOYMENT=''
|
||||
|
||||
while [ "${SECONDS}" -lt "${DEADLINE}" ]; do
|
||||
mapfile -t MATCHES < <(
|
||||
kubectl get deployments \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output go-template="{{range .items}}{{\$name := .metadata.name}}{{range .spec.template.spec.containers}}{{if eq .image \"${EXPECTED_IMAGE}\"}}{{\$name}}{{\"\\n\"}}{{end}}{{end}}{{end}}" |
|
||||
sort -u
|
||||
)
|
||||
|
||||
if [ "${#MATCHES[@]}" -eq 1 ] && [ -n "${MATCHES[0]}" ]; then
|
||||
DEPLOYMENT="${MATCHES[0]}"
|
||||
echo "Deployment actualizado por Argo CD: ${DEPLOYMENT}"
|
||||
break
|
||||
fi
|
||||
|
||||
if [ "${#MATCHES[@]}" -gt 1 ]; then
|
||||
echo "ERROR: más de un Deployment usa ${EXPECTED_IMAGE}: ${MATCHES[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Argo CD aún no ha aplicado ${EXPECTED_IMAGE}. Reintentando en 10 segundos..."
|
||||
sleep 10
|
||||
done
|
||||
|
||||
if [ -z "${DEPLOYMENT}" ]; then
|
||||
echo "ERROR: Argo CD no aplicó ${EXPECTED_IMAGE} dentro del tiempo límite."
|
||||
kubectl get deployments \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output custom-columns='DEPLOYMENT:.metadata.name,IMAGES:.spec.template.spec.containers[*].image'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl rollout status "deployment/${DEPLOYMENT}" \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--timeout="${DEPLOY_TIMEOUT_SECONDS}s"
|
||||
|
||||
CONTAINER_NAME="$(
|
||||
kubectl get deployment "${DEPLOYMENT}" \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output go-template="{{range .spec.template.spec.containers}}{{if eq .image \"${EXPECTED_IMAGE}\"}}{{.name}}{{end}}{{end}}"
|
||||
)"
|
||||
|
||||
if [ -z "${CONTAINER_NAME}" ]; then
|
||||
echo "ERROR: no se encontró el contenedor con ${EXPECTED_IMAGE}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SELECTOR="$(
|
||||
kubectl get deployment "${DEPLOYMENT}" \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output go-template='{{range $key, $value := .spec.selector.matchLabels}}{{printf "%s=%s," $key $value}}{{end}}' |
|
||||
sed 's/,$//'
|
||||
)"
|
||||
|
||||
EXPECTED_REPLICAS="$(
|
||||
kubectl get deployment "${DEPLOYMENT}" \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output jsonpath='{.spec.replicas}'
|
||||
)"
|
||||
|
||||
mapfile -t PODS < <(
|
||||
kubectl get pods \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--selector "${SELECTOR}" \
|
||||
--output go-template='{{range .items}}{{if not .metadata.deletionTimestamp}}{{if eq .status.phase "Running"}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}{{end}}'
|
||||
)
|
||||
|
||||
if [ "${#PODS[@]}" -ne "${EXPECTED_REPLICAS}" ]; then
|
||||
echo "ERROR: se esperaban ${EXPECTED_REPLICAS} Pods Running y se encontraron ${#PODS[@]}."
|
||||
kubectl get pods \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--selector "${SELECTOR}" \
|
||||
-o wide
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VALIDATED_PODS=0
|
||||
|
||||
for pod in "${PODS[@]}"; do
|
||||
DECLARED_IMAGE="$(
|
||||
kubectl get pod "${pod}" \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output go-template="{{range .spec.containers}}{{if eq .name \"${CONTAINER_NAME}\"}}{{.image}}{{end}}{{end}}"
|
||||
)"
|
||||
|
||||
READY="$(
|
||||
kubectl get pod "${pod}" \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output go-template="{{range .status.containerStatuses}}{{if eq .name \"${CONTAINER_NAME}\"}}{{.ready}}{{end}}{{end}}"
|
||||
)"
|
||||
|
||||
IMAGE_ID="$(
|
||||
kubectl get pod "${pod}" \
|
||||
--namespace "${NAMESPACE}" \
|
||||
--output go-template="{{range .status.containerStatuses}}{{if eq .name \"${CONTAINER_NAME}\"}}{{.imageID}}{{end}}{{end}}"
|
||||
)"
|
||||
|
||||
echo "Pod: ${pod}"
|
||||
echo " Ready: ${READY}"
|
||||
echo " Imagen declarada: ${DECLARED_IMAGE}"
|
||||
echo " Image ID: ${IMAGE_ID}"
|
||||
|
||||
if [ "${DECLARED_IMAGE}" != "${EXPECTED_IMAGE}" ]; then
|
||||
echo "ERROR: ${pod} ejecuta ${DECLARED_IMAGE}, no ${EXPECTED_IMAGE}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${READY}" != 'true' ]; then
|
||||
echo "ERROR: el contenedor ${CONTAINER_NAME} de ${pod} no está Ready."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VALIDATED_PODS=$((VALIDATED_PODS + 1))
|
||||
done
|
||||
|
||||
echo "=================================================="
|
||||
echo "VALIDACIÓN EXITOSA"
|
||||
echo "Deployment: ${DEPLOYMENT}"
|
||||
echo "Pods validados: ${VALIDATED_PODS}/${EXPECTED_REPLICAS}"
|
||||
echo "Tag ejecutado: ${EXPECTED_IMAGE}"
|
||||
echo "=================================================="
|
||||
git commit -m "chore: release ${{ steps.vars.outputs.VERSION }} [skip ci]"
|
||||
# 4. Forzamos el push usando --force para limpiar cualquier discrepancia
|
||||
git push origin HEAD:main --force
|
||||
fi
|
||||
@@ -0,0 +1,22 @@
|
||||
name: Sync Ari Shopping Catalog
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '@daily'
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: python3 -m pip install --user -r workloads/ecommerce/tools/requirements.txt
|
||||
- run: python3 workloads/ecommerce/tools/catalog_sync.py --source workloads/ecommerce/catalog-source.csv --download-images
|
||||
- run: |
|
||||
git config user.name "Ari Shopping Catalog Bot"
|
||||
git config user.email "[email protected]"
|
||||
git add workloads/ecommerce/data/products.json workloads/ecommerce/assets/img/products
|
||||
git diff --cached --quiet && exit 0
|
||||
git commit -m "chore(catalog): sync products"
|
||||
git pull --rebase origin main
|
||||
git push origin HEAD:main
|
||||
Reference in New Issue
Block a user