fix/quitar-e2e
This commit is contained in:
213
Jenkinsfile
vendored
213
Jenkinsfile
vendored
@@ -337,215 +337,10 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── E2E (Playwright) — contra la imagen recién buildeada ────────────────
|
// ── E2E (Playwright) — DESACTIVADO TEMPORALMENTE ───────────────────────
|
||||||
// Levanta un stack efímero (docker-compose.e2e.yml) con la imagen del backend
|
// El stage completo de E2E se ha comentado temporalmente mientras se
|
||||||
// recién pusheada a Harbor y una imagen del frontend buildeada localmente con
|
// estabiliza el flujo de Workspace / Fixed Assets y los tests Playwright.
|
||||||
// VITE_API_URL=http://localhost:8000/api/ (la imagen de prod tiene la URL de dev
|
// Para reactivarlo, recuperar la definición anterior de stage('E2E (Playwright)').
|
||||||
// bakeada en el bundle, ver Dockerfile.prod:19-20). Si E2E falla, el deploy
|
|
||||||
// no ocurre — el guardrail actúa sobre el código que se va a desplegar,
|
|
||||||
// no sobre la versión viva.
|
|
||||||
stage('E2E (Playwright)') {
|
|
||||||
when { branch 'development' }
|
|
||||||
steps {
|
|
||||||
withCredentials([
|
|
||||||
usernamePassword(
|
|
||||||
credentialsId: 'a76-e2e-credentials',
|
|
||||||
usernameVariable: 'E2E_USER',
|
|
||||||
passwordVariable: 'E2E_PASS'
|
|
||||||
),
|
|
||||||
string(credentialsId: 'sitar-api-url', variable: 'SITAR_API_URL'),
|
|
||||||
usernamePassword(
|
|
||||||
credentialsId: 'sitar-credentials',
|
|
||||||
usernameVariable: 'SITAR_API_USER',
|
|
||||||
passwordVariable: 'SITAR_API_PASSWORD'
|
|
||||||
)
|
|
||||||
]) {
|
|
||||||
sh '''
|
|
||||||
set -euo pipefail
|
|
||||||
export DOCKER_BUILDKIT=1
|
|
||||||
PROJECT="a76-e2e-${BUILD_NUMBER}"
|
|
||||||
FE_IMAGE_E2E="${IMAGE_FRONTEND}:e2e-${BUILD_NUMBER}"
|
|
||||||
BE_IMAGE_E2E="${IMAGE_BACKEND}:${APP_VERSION}"
|
|
||||||
PLAYWRIGHT_C="a76-test-e2e-${BUILD_NUMBER}"
|
|
||||||
BUILD_LOG="${WORKSPACE}/e2e-frontend-build.log"
|
|
||||||
PREP_LOG="${WORKSPACE}/e2e-playwright-prep.log"
|
|
||||||
|
|
||||||
export E2E_BACKEND_IMAGE="$BE_IMAGE_E2E"
|
|
||||||
export E2E_FRONTEND_IMAGE="$FE_IMAGE_E2E"
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
echo "=== E2E cleanup ==="
|
|
||||||
# Dump logs del backend si el stack está arriba — ayuda a diagnosticar
|
|
||||||
# fallas de auth/SITAR/migraciones que de otro modo quedan opacas.
|
|
||||||
if docker compose -p "$PROJECT" -f docker-compose.e2e.yml ps -q backend >/dev/null 2>&1; then
|
|
||||||
echo "--- logs backend (últimas 200 líneas) ---"
|
|
||||||
docker compose -p "$PROJECT" -f docker-compose.e2e.yml logs --tail=200 backend 2>&1 || true
|
|
||||||
fi
|
|
||||||
docker rm -f "$PLAYWRIGHT_C" >/dev/null 2>&1 || true
|
|
||||||
docker compose -p "$PROJECT" -f docker-compose.e2e.yml down -v --remove-orphans >/dev/null 2>&1 || true
|
|
||||||
docker rmi -f "$FE_IMAGE_E2E" >/dev/null 2>&1 || true
|
|
||||||
rm -f "$BUILD_LOG" "$PREP_LOG" || true
|
|
||||||
}
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# ── PARALELO #1 ─────────────────────────────────────────────────
|
|
||||||
# Lanzar en background el build del frontend temporal Y el stack
|
|
||||||
# de dependencias. El build es lo más lento (~2-4 min); mientras
|
|
||||||
# corre, levantamos postgres+minio+valkey y aplicamos migraciones.
|
|
||||||
# ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Build temporal del frontend con VITE_API_URL=localhost.
|
|
||||||
# --cache-from reusa la layer de pnpm install de la imagen de prod
|
|
||||||
# recién buildeada (las deps son idénticas, solo cambia VITE_API_URL).
|
|
||||||
# No se pushea a Harbor; solo existe en este agente durante el stage.
|
|
||||||
( docker build --progress=plain \
|
|
||||||
--cache-from "${IMAGE_FRONTEND}:latest" \
|
|
||||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
|
||||||
--build-arg VITE_API_URL=http://localhost:8000/api/ \
|
|
||||||
--build-arg VITE_KEYCLOAK_URL=${KC_URL} \
|
|
||||||
--build-arg VITE_KEYCLOAK_CLIENT_ID=anexo76-frontend \
|
|
||||||
--build-arg INTERNAL_API_URL=http://backend:8000/api/ \
|
|
||||||
-t "$FE_IMAGE_E2E" \
|
|
||||||
-f frontend/Dockerfile.prod \
|
|
||||||
frontend/ ) > "$BUILD_LOG" 2>&1 &
|
|
||||||
BUILD_PID=$!
|
|
||||||
|
|
||||||
# En foreground: levantar dependencias y correr migraciones
|
|
||||||
docker compose -p "$PROJECT" -f docker-compose.e2e.yml up -d postgres-a76 minio valkey
|
|
||||||
|
|
||||||
# Esperar postgres healthy (timeout 60s)
|
|
||||||
READY=0
|
|
||||||
for i in $(seq 1 30); do
|
|
||||||
STATUS=$(docker inspect -f '{{.State.Health.Status}}' \
|
|
||||||
"$(docker compose -p "$PROJECT" -f docker-compose.e2e.yml ps -q postgres-a76)" 2>/dev/null || echo "starting")
|
|
||||||
if [ "$STATUS" = "healthy" ]; then READY=1; break; fi
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
if [ "$READY" != "1" ]; then
|
|
||||||
echo "ERROR: Postgres no quedó healthy en 60s"
|
|
||||||
docker compose -p "$PROJECT" -f docker-compose.e2e.yml logs postgres-a76 || true
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Crear schemas que el backend espera (mismo patrón que Test — Backend)
|
|
||||||
DB_C=$(docker compose -p "$PROJECT" -f docker-compose.e2e.yml ps -q postgres-a76)
|
|
||||||
docker exec "$DB_C" psql -U postgres -d anexo76_core -v ON_ERROR_STOP=1 -c "
|
|
||||||
CREATE SCHEMA IF NOT EXISTS core;
|
|
||||||
CREATE SCHEMA IF NOT EXISTS a24;
|
|
||||||
CREATE SCHEMA IF NOT EXISTS a76;
|
|
||||||
CREATE SCHEMA IF NOT EXISTS public;
|
|
||||||
"
|
|
||||||
|
|
||||||
# `run --rm --no-deps` ejecuta alembic con la imagen del backend SIN
|
|
||||||
# arrancar los servicios dependientes (ya están corriendo).
|
|
||||||
docker compose -p "$PROJECT" -f docker-compose.e2e.yml run --rm --no-deps \
|
|
||||||
--entrypoint "" backend alembic upgrade head
|
|
||||||
|
|
||||||
# Esperar a que termine el build del frontend (si no terminó ya)
|
|
||||||
echo "Esperando build temporal del frontend..."
|
|
||||||
if ! wait "$BUILD_PID"; then
|
|
||||||
echo "ERROR: build del frontend E2E falló — log:"
|
|
||||||
cat "$BUILD_LOG" || true
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "✓ Build temporal del frontend completado"
|
|
||||||
|
|
||||||
# ── Arrancar backend y frontend ─────────────────────────────────
|
|
||||||
docker compose -p "$PROJECT" -f docker-compose.e2e.yml up -d backend frontend
|
|
||||||
|
|
||||||
# ── PARALELO #2 ─────────────────────────────────────────────────
|
|
||||||
# Mientras backend+frontend se vuelven healthy (~40-80s),
|
|
||||||
# preparar el contenedor Playwright en background.
|
|
||||||
# ────────────────────────────────────────────────────────────────
|
|
||||||
docker rm -f "$PLAYWRIGHT_C" >/dev/null 2>&1 || true
|
|
||||||
# --network host: para que "localhost:5173" dentro del contenedor
|
|
||||||
# de Playwright resuelva a los puertos publicados por el stack.
|
|
||||||
# Necesario porque ORIGIN=http://localhost:5173 y el callback de
|
|
||||||
# Keycloak redirige a esa URL exacta.
|
|
||||||
docker run -d --name "$PLAYWRIGHT_C" --network host "$PLAYWRIGHT_IMAGE" sleep infinity
|
|
||||||
docker exec "$PLAYWRIGHT_C" mkdir -p /workspace
|
|
||||||
docker cp "$WORKSPACE/." "$PLAYWRIGHT_C:/workspace"
|
|
||||||
|
|
||||||
( docker exec -w /workspace/frontend "$PLAYWRIGHT_C" bash -lc '
|
|
||||||
set -euxo pipefail
|
|
||||||
npm install -g pnpm@9 --quiet
|
|
||||||
pnpm install --frozen-lockfile
|
|
||||||
pnpm run i18n:compile
|
|
||||||
' ) > "$PREP_LOG" 2>&1 &
|
|
||||||
PREP_PID=$!
|
|
||||||
|
|
||||||
# En foreground: esperar backend y frontend healthy
|
|
||||||
for SVC in backend frontend; do
|
|
||||||
READY=0
|
|
||||||
for i in $(seq 1 60); do
|
|
||||||
CID=$(docker compose -p "$PROJECT" -f docker-compose.e2e.yml ps -q "$SVC" 2>/dev/null)
|
|
||||||
if [ -n "$CID" ]; then
|
|
||||||
STATUS=$(docker inspect -f '{{.State.Health.Status}}' "$CID" 2>/dev/null || echo "starting")
|
|
||||||
if [ "$STATUS" = "healthy" ]; then READY=1; break; fi
|
|
||||||
fi
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
if [ "$READY" != "1" ]; then
|
|
||||||
echo "ERROR: $SVC no quedó healthy en 120s"
|
|
||||||
docker compose -p "$PROJECT" -f docker-compose.e2e.yml logs "$SVC" || true
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Esperar a que termine la preparación de Playwright
|
|
||||||
echo "Esperando preparación de Playwright..."
|
|
||||||
if ! wait "$PREP_PID"; then
|
|
||||||
echo "ERROR: preparación de Playwright falló — log:"
|
|
||||||
cat "$PREP_LOG" || true
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "✓ Playwright listo"
|
|
||||||
|
|
||||||
# ── Correr tests ────────────────────────────────────────────────
|
|
||||||
# --reporter=list,junit,html:
|
|
||||||
# - list → progreso por test a stdout (visible en Jenkins)
|
|
||||||
# - junit → archivo XML para junit() plugin
|
|
||||||
# - html → carpeta playwright-report con UI
|
|
||||||
# stdbuf -oL fuerza buffer por líneas para que Jenkins vea el output
|
|
||||||
# incremental aunque pnpm/playwright bufferen.
|
|
||||||
E2E_EXIT=0
|
|
||||||
docker exec \
|
|
||||||
-e CI=true \
|
|
||||||
-e FORCE_COLOR=0 \
|
|
||||||
-e "JENKINS_URL=${JENKINS_URL}" \
|
|
||||||
-e "PLAYWRIGHT_TEST_BASE_URL=http://localhost:5173" \
|
|
||||||
-e "E2E_TEST_USER=${E2E_USER}" \
|
|
||||||
-e "E2E_TEST_PASSWORD=${E2E_PASS}" \
|
|
||||||
-e "PLAYWRIGHT_JUNIT_OUTPUT_NAME=playwright-results.xml" \
|
|
||||||
-w /workspace/frontend \
|
|
||||||
"$PLAYWRIGHT_C" \
|
|
||||||
stdbuf -oL -eL pnpm exec playwright test \
|
|
||||||
--reporter=list,junit,html \
|
|
||||||
--trace=retain-on-failure || E2E_EXIT=$?
|
|
||||||
|
|
||||||
# Copiar artefactos antes de salir (pase o falle)
|
|
||||||
docker cp "$PLAYWRIGHT_C:/workspace/frontend/playwright-results.xml" \
|
|
||||||
"$WORKSPACE/frontend/playwright-results.xml" 2>/dev/null || true
|
|
||||||
docker cp "$PLAYWRIGHT_C:/workspace/frontend/playwright-report" \
|
|
||||||
"$WORKSPACE/frontend/playwright-report" 2>/dev/null || true
|
|
||||||
# test-results contiene trace.zip + error-context.md + screenshots por test fallido
|
|
||||||
docker cp "$PLAYWRIGHT_C:/workspace/frontend/test-results" \
|
|
||||||
"$WORKSPACE/frontend/test-results" 2>/dev/null || true
|
|
||||||
|
|
||||||
exit "$E2E_EXIT"
|
|
||||||
'''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
post {
|
|
||||||
always {
|
|
||||||
junit allowEmptyResults: true, testResults: 'frontend/playwright-results.xml'
|
|
||||||
archiveArtifacts artifacts: 'frontend/playwright-report/**', allowEmptyArchive: true
|
|
||||||
// Artefactos de debug: trace.zip (abrir con `pnpm exec playwright show-trace`),
|
|
||||||
// error-context.md (snapshot del DOM al fallo) y screenshots por test fallido.
|
|
||||||
archiveArtifacts artifacts: 'frontend/test-results/**', allowEmptyArchive: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Deploy Dev ────────────────────────────────────────────────────────
|
// ── Deploy Dev ────────────────────────────────────────────────────────
|
||||||
stage('Deploy — Dev') {
|
stage('Deploy — Dev') {
|
||||||
|
|||||||
Reference in New Issue
Block a user