merge-conflic-fix

This commit is contained in:
2026-04-07 08:21:16 -06:00
3 changed files with 57 additions and 28 deletions

75
Jenkinsfile vendored
View File

@@ -57,7 +57,6 @@ pipeline {
DB_NAME="anexo76_test"
DB_USER="anexo76"
DB_PASS="anexo76"
DB_PORT="55432"
export TEST_DATABASE_URL="postgresql://${DB_USER}:${DB_PASS}@${DB_CONTAINER}:5432/${DB_NAME}"
PY_CONTAINER="anexo76-test-py-${BUILD_NUMBER}"
TEST_NETWORK="anexo76-test-net-${BUILD_NUMBER}"
@@ -80,13 +79,19 @@ pipeline {
-e POSTGRES_PASSWORD="$DB_PASS" \
postgres:16-alpine
# Espera a que Postgres acepte conexiones
# Espera a que Postgres acepte conexiones (hasta ~60s)
READY=0
for i in $(seq 1 30); do
if docker exec "$DB_CONTAINER" pg_isready -U "$DB_USER" -d "$DB_NAME" >/dev/null 2>&1; then
READY=1
break
fi
sleep 2
done
if [ "$READY" != "1" ]; then
echo "ERROR: Postgres no quedó listo a tiempo (30 intentos × 2s)."
exit 1
fi
docker exec "$DB_CONTAINER" pg_isready -U "$DB_USER" -d "$DB_NAME"
docker exec "$DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -v ON_ERROR_STOP=1 -c "
CREATE SCHEMA IF NOT EXISTS core;
@@ -165,33 +170,47 @@ pipeline {
stage('Build + push backend') {
steps {
sh '''
set -euo pipefail
docker build \
--build-arg APP_VERSION="${APP_VERSION}" \
-t "${REGISTRY}/${IMAGE_NAMESPACE}/backend:latest" \
-f ./backend/Dockerfile \
./backend
script {
retry(3) {
sh '''
set -euo pipefail
export DOCKER_BUILDKIT=1
docker build \
--build-arg APP_VERSION="${APP_VERSION}" \
-t "${REGISTRY}/${IMAGE_NAMESPACE}/backend:${APP_VERSION}" \
-t "${REGISTRY}/${IMAGE_NAMESPACE}/backend:latest" \
-f ./backend/Dockerfile \
./backend
docker push "${REGISTRY}/${IMAGE_NAMESPACE}/backend:latest"
'''
docker push "${REGISTRY}/${IMAGE_NAMESPACE}/backend:${APP_VERSION}"
docker push "${REGISTRY}/${IMAGE_NAMESPACE}/backend:latest"
'''
}
}
}
}
stage('Build + push frontend') {
steps {
sh '''
set -euo pipefail
docker build \
--build-arg VITE_API_URL=https://anexo76-dev.aduanasoft.com/api/ \
--build-arg VITE_KEYCLOAK_URL=https://anexo76-dev.aduanasoft.com/kcauth/ \
--build-arg INTERNAL_API_URL=http://backend:3467/api/ \
-t "${REGISTRY}/${IMAGE_NAMESPACE}/frontend:latest" \
-f ./frontend/Dockerfile.prod \
./frontend
script {
retry(3) {
sh '''
set -euo pipefail
export DOCKER_BUILDKIT=1
docker build \
--build-arg VITE_API_URL=https://anexo76-dev.aduanasoft.com/api/ \
--build-arg VITE_KEYCLOAK_URL=https://anexo76-dev.aduanasoft.com/kcauth/ \
--build-arg INTERNAL_API_URL=http://backend:3467/api/ \
-t "${REGISTRY}/${IMAGE_NAMESPACE}/frontend:${APP_VERSION}" \
-t "${REGISTRY}/${IMAGE_NAMESPACE}/frontend:latest" \
-f ./frontend/Dockerfile.prod \
./frontend
docker push "${REGISTRY}/${IMAGE_NAMESPACE}/frontend:latest"
'''
docker push "${REGISTRY}/${IMAGE_NAMESPACE}/frontend:${APP_VERSION}"
docker push "${REGISTRY}/${IMAGE_NAMESPACE}/frontend:latest"
'''
}
}
}
}
@@ -229,13 +248,20 @@ pipeline {
)
]) {
script {
def devHost = env.DEV_SERVER_HOST?.trim()
def knownHostsFile = "${env.WORKSPACE}/.jenkins-anexo76-known_hosts"
sh """
set -euo pipefail
ssh-keyscan -T 15 -H '${devHost}' > '${knownHostsFile}'
"""
def remote = [
name: 'dev-server',
host: env.DEV_SERVER_HOST,
host: devHost,
user: env.DEV_SERVER_USER ?: env.DEV_SERVER_SSH_USER,
identityFile: env.DEV_SERVER_KEY,
passphrase: env.DEV_SERVER_KEY_PASSPHRASE,
allowAnyHosts: true
allowAnyHosts: false,
knownHosts: knownHostsFile
]
sshCommand remote: remote, command: '''
set -euo pipefail
@@ -243,6 +269,7 @@ pipeline {
# Asume docker login ya configurado en el host destino para evitar exponer secretos por interpolación.
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
# Solo imágenes colgantes (sin tag); no borra imágenes en uso por otros contenedores.
docker image prune -f
'''
}

View File

@@ -45,6 +45,10 @@ RUN pip install --no-cache-dir -r requirements.txt
# Copiar código
COPY . .
# Jenkins / CI pasan --build-arg APP_VERSION=…; debe quedar en ENV para runtime (API /version, OpenAPI, etc.)
ARG APP_VERSION=dev-local
ENV APP_VERSION=${APP_VERSION}
# Exponer puerto
EXPOSE 8000

View File

@@ -2,7 +2,6 @@
Configuración centralizada de la aplicación usando Pydantic Settings
"""
import os
from typing import List, Literal
from pydantic import field_validator
@@ -14,9 +13,8 @@ class Settings(BaseSettings):
# Application
APP_NAME: str = "Anexo76"
# La versión se obtiene de la variable de entorno APP_VERSION que se pasa desde Docker
# Si no existe, usa un valor por defecto de desarrollo
APP_VERSION: str = os.getenv("APP_VERSION", "dev-local")
# Sobreescribible con APP_VERSION (Dockerfile/Jenkins: build-arg + ENV) o entorno en runtime
APP_VERSION: str = "dev-local"
DEBUG: bool = True
ENVIRONMENT: str = "development"