Saltar al contenido principal

Wiedii — Política de Actualizaciones Automáticas con Renovate

Renovate es un bot que abre MRs automáticas para actualizar las dependencias de un repositorio (librerías, imágenes Docker, herramientas) a sus versiones nuevas.

Todo repositorio Wiedii debe tener un renovate.json en su raíz. Sin este archivo el runner de Renovate no procesa el repositorio y sus dependencias nunca se actualizarán automáticamente.


renovate.json mínimo obligatorio

Este es el único archivo de configuración que todo repo debe tener:

{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["local>wildcat/renovate-runner//.gitlab/renovate.json"]
}

Con esto es suficiente. El preset compartido ya define todas las reglas empresariales: rangeStrategy: "pin", pinDigests, minimumReleaseAge, agrupaciones por herramienta, gestores custom (Bun, mise, Terraform, PHP, etc.) y políticas de seguridad.

📄 Referencia del preset: renovate-runner
📄 Documentación interna del preset: https://gitlab.wiedii.co/wildcat/renovate-runner/-/blob/main/docs/renovate-runner-configs.md


Overrides en el repo (solo cuando sea necesario)

Los repos pueden añadir reglas específicas sin romper el preset compartido. El preset es la fuente de verdad — solo añadir overrides si el proyecto tiene necesidades concretas que el preset no cubre:

{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["local>wildcat/renovate-runner//.gitlab/renovate.json"],
"packageRules": [
{
"description": "Ignorar este módulo de Terraform — versión fijada por contrato",
"enabled": false,
"matchPackageNames": ["terraform-aws-modules/vpc/aws"]
}
]
}

Cosas que no se deben duplicar en el renovate.json local porque ya están en el preset:

  • rangeStrategy, pinDigests, minimumReleaseAge
  • baseBranchPatterns: ["develop"]
  • semanticCommits, dependencyDashboard
  • Agrupaciones de Bun, Terraform, Terragrunt, PHP, Go, etc.

Rama base: proyectos con y sin gestión de ramas

Renovate lee el renovate.json desde la rama por defecto del repositorio (GitLab Settings → Repository → Default branch). Esa rama es también donde Renovate abre los MRs de actualización.

Tipo de proyectoRama por defecto en GitLabOverride en renovate.json
Con gestión de ramas (Git Flow)developno necesario — el preset ya tiene baseBranchPatterns: ["develop"]
Sin gestión de ramas (sin CI, simple)mainsí — agregar "baseBranchPatterns": ["main"]

Proyectos sin gestión de ramas

Un proyecto "sin gestión de ramas" es aquel que no tiene Git Flow, no tiene un pipeline de CI completo, y trabaja directamente sobre main (ej. repos de configuración, scripts puntuales, documentación independiente).

Para estos proyectos, el renovate.json debe ser:

{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["local>wildcat/renovate-runner//.gitlab/renovate.json"],
"baseBranchPatterns": ["main"]
}

Sin este override, el preset intentaría buscar la rama develop — que no existe — y Renovate no abriría MRs.

Regla práctica: si el proyecto no tiene rama develop (p. ej. usa GitHub Flow, solo main), agregar "baseBranchPatterns": ["main"] al renovate.json. Ver git-flow.

⚠️ Nombre del campo (actualizado): es baseBranchPatterns, no baseBranches. Renovate renombró baseBranchesbaseBranchPatterns (v39). configMigration: true migra el nombre viejo automáticamente, pero renovate-config-validator --strict marca baseBranches como obsoleto y falla. Usar siempre baseBranchPatterns en los renovate.json de proyecto. Acepta nombres exactos (["main"]) y regex (["/^release\\/.*/"]).


Validar la configuración

Antes de hacer merge de cualquier cambio en renovate.json:

bun run renovate:validate
# Equivalente explícito:
mise exec -- bunx --yes --package renovate@latest -- renovate-config-validator --strict

Este comando está disponible en cualquier repo que use el runner como base. Si el repo no tiene este script, ejecutar directamente con bunx.


Cómo funciona el runner de Renovate en Wiedii

El runner está en wildcat/renovate-runner. Ejecuta Renovate como contenedor Docker con RENOVATE_AUTODISCOVER: true apuntando al namespace wildcat/** (y cualquier namespace configurado). El pipeline corre en schedule (lunes 4am UTC).

Flujo de autodescubrimiento:

  1. El runner busca todos los repos en el namespace configurado.
  2. Para cada repo, busca renovate.json en la raíz de la rama por defecto del repositorio (GitLab Settings → Repository → Default branch). Para proyectos con Git Flow esa rama es develop; para proyectos sin gestión de ramas es main.
  3. Si no existe renovate.json → el repo se omite silenciosamente.
  4. Si existe → Renovate procesa las dependencias y abre MRs según las reglas del preset.

Por eso renovate.json es obligatorio: sin él, el runner simplemente ignora el repositorio.


El check renovate/stability-days (período de enfriamiento)

En las pipelines de cada proyecto aparece una etapa external con un job llamado renovate/stability-days. No es un job que corra en los runners de CI: es un commit status que Renovate publica vía la Commits API de GitLab, y GitLab lo agrupa bajo la etapa external (estados que llegan desde fuera del .gitlab-ci.yaml).

Implementa el minimumReleaseAge del preset (Wiedii lo tiene en 3 días): un período de enfriamiento anti-supply-chain. Renovate espera ese tiempo desde que se publicó una versión antes de permitir actualizarla, para dar margen a que se detecte código malicioso en releases recién publicadas.

  • Mientras la versión es más nueva que minimumReleaseAge → status pending → la MR queda retenida.
  • Cuando pasan los días suficientes → Renovate cambia el status a passing (verde).

Qué NO hace: no reserva runner, no clona el repo, no consume cómputo del proyecto y no recolecta información del repositorio. El único dato detrás es el timestamp de publicación de cada versión, que Renovate obtiene del datasource/registro (npm, GitHub Releases, Docker Hub, etc.) y compara contra ahora − minimumReleaseAge.

Con internalChecksFilter=strict (default de Renovate) la rama ni siquiera se crea hasta que el check pasa. Si se ven MRs con el status en pending, es porque la configuración permite crear la MR y retenerla con el check. Ver Minimum Release Age.


Integración con otras políticas Wiedii

PolíticaCómo la respeta Renovate
Versiones pinneadasrangeStrategy: "pin" — todas las deps se pinnean a versión exacta
No squash mergeautomergeStrategy: "merge" en el preset
Git Flow (develop como base)baseBranchPatterns: ["develop"] en el preset — la rama por defecto del repo debe ser develop
Semantic commitsRenovate genera fix(deps): para deps, chore(deps): para devDeps
Quality gatesLos MRs de Renovate pasan por el mismo CI que cualquier MR
Majors requieren revisiónLos majors no se fusionan automáticamente — requieren aprobación manual

Troubleshooting

El runner no crea MRs para mi repo:

  1. Verificar que renovate.json existe en la raíz de la rama por defecto del repo (develop para proyectos Git Flow, main para proyectos sin gestión de ramas).
  2. Verificar que el runner tiene acceso de lectura al repositorio.
  3. Revisar el Dependency Dashboard en GitLab (si dependencyDashboard: true).

Validación falla con error de schema:

mise exec -- bunx --yes --package renovate@latest -- renovate-config-validator --strict

El error indicará exactamente qué campo es inválido.

Quiero excluir un paquete específico:

{
"extends": ["local>wildcat/renovate-runner//.gitlab/renovate.json"],
"packageRules": [
{ "enabled": false, "matchPackageNames": ["nombre-del-paquete"] }
]
}

Referencias