Merge pull request 'ci-cd/migrations' (#253) from ci-cd/migrations into development
Reviewed-on: ADUANASOFT/anexo76#253
This commit is contained in:
@@ -36,7 +36,7 @@ jobs:
|
||||
set -e
|
||||
if [ -z "$TEST_DATABASE_URL" ]; then
|
||||
echo "::error::Define el secret TEST_DATABASE_URL en el repo (Gitea → Ajustes → Secretos)."
|
||||
echo "Ejemplo: postgresql://usuario:clave@host:5432/nombre_bd"
|
||||
echo "Ejemplo: postgresql://usuario:clave@127.0.0.1:5432/nombre_bd (host real, no el texto \"host\")"
|
||||
exit 1
|
||||
fi
|
||||
python3 --version
|
||||
|
||||
@@ -46,10 +46,27 @@ def _validate_sqlalchemy_url(url: str, env_key: str) -> None:
|
||||
except Exception as e:
|
||||
raise RuntimeError(
|
||||
f"{env_key} no es una URL de SQLAlchemy válida. "
|
||||
"Ejemplo: postgresql://usuario:clave@host:5432/nombre_bd"
|
||||
"Ejemplo: postgresql://usuario:clave@127.0.0.1:5432/nombre_bd"
|
||||
) from e
|
||||
|
||||
|
||||
def _reject_documentation_placeholder_host(url: str, source: str) -> None:
|
||||
"""
|
||||
Evita el error críptico de DNS: muchos ejemplos usan @host:5432 como texto literal.
|
||||
"""
|
||||
try:
|
||||
parsed = make_url(url)
|
||||
except Exception:
|
||||
return
|
||||
h = (parsed.host or "").strip().lower()
|
||||
if h == "host":
|
||||
raise RuntimeError(
|
||||
f"{source}: el hostname \"host\" es un placeholder de documentación, no un servidor real. "
|
||||
"Usa el host alcanzable desde el runner (IP, nombre DNS, servicio en docker-compose, "
|
||||
"o host.docker.internal si act corre en contenedor y Postgres en tu máquina)."
|
||||
)
|
||||
|
||||
|
||||
def get_database_url():
|
||||
"""Obtiene la URL de la base de datos (PostgreSQL) desde variables de entorno o alembic.ini."""
|
||||
# CI / pytest: misma URL que los tests (secret TEST_DATABASE_URL) o DATABASE_URL explícita.
|
||||
@@ -60,6 +77,7 @@ def get_database_url():
|
||||
if raw and raw.strip():
|
||||
normalized = _normalize_alembic_sqlalchemy_url(raw)
|
||||
_validate_sqlalchemy_url(normalized, env_key)
|
||||
_reject_documentation_placeholder_host(normalized, env_key)
|
||||
return normalized
|
||||
|
||||
# Construcción desde settings (CORE_DB_* en .env / entorno)
|
||||
@@ -74,7 +92,9 @@ def get_database_url():
|
||||
encoded_user = quote_plus(user)
|
||||
encoded_password = quote_plus(password)
|
||||
encoded_db = quote_plus(db)
|
||||
return f"postgresql+psycopg2://{encoded_user}:{encoded_password}@{host}:{port}/{encoded_db}"
|
||||
built = f"postgresql+psycopg2://{encoded_user}:{encoded_password}@{host}:{port}/{encoded_db}"
|
||||
_reject_documentation_placeholder_host(built, "CORE_DB_HOST")
|
||||
return built
|
||||
except Exception as e:
|
||||
logger.error(f"Error al construir URL: {e}")
|
||||
|
||||
@@ -87,6 +107,7 @@ def get_database_url():
|
||||
"sqlalchemy.url en alembic.ini con placeholders ${...} no está soportado."
|
||||
)
|
||||
|
||||
_reject_documentation_placeholder_host(url, "alembic.ini sqlalchemy.url")
|
||||
return url
|
||||
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ Si `TEST_DATABASE_URL` apunta a una base con datos previos, los builders reutili
|
||||
|
||||
- PostgreSQL test database available.
|
||||
- Environment variable:
|
||||
- `TEST_DATABASE_URL=postgresql://user:pass@host:5432/db_name`
|
||||
- `TEST_DATABASE_URL=postgresql://user:pass@127.0.0.1:5432/db_name` (sustituye por el host real alcanzable desde el runner; no uses el literal `host` de los ejemplos genéricos)
|
||||
|
||||
## Run commands
|
||||
|
||||
|
||||
Reference in New Issue
Block a user