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,minimumReleaseAgebaseBranchPatterns: ["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 proyecto | Rama por defecto en GitLab | Override en renovate.json |
|---|---|---|
| Con gestión de ramas (Git Flow) | develop | no necesario — el preset ya tiene baseBranchPatterns: ["develop"] |
| Sin gestión de ramas (sin CI, simple) | main | sí — 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, solomain), agregar"baseBranchPatterns": ["main"]alrenovate.json. Ver git-flow.
⚠️ Nombre del campo (actualizado): es
baseBranchPatterns, nobaseBranches. Renovate renombróbaseBranches→baseBranchPatterns(v39).configMigration: truemigra el nombre viejo automáticamente, perorenovate-config-validator --strictmarcabaseBranchescomo obsoleto y falla. Usar siemprebaseBranchPatternsen losrenovate.jsonde 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:
- El runner busca todos los repos en el namespace configurado.
- Para cada repo, busca
renovate.jsonen la raíz de la rama por defecto del repositorio (GitLab Settings → Repository → Default branch). Para proyectos con Git Flow esa rama esdevelop; para proyectos sin gestión de ramas esmain. - Si no existe
renovate.json→ el repo se omite silenciosamente. - 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→ statuspending→ 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 enpending, 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ítica | Cómo la respeta Renovate |
|---|---|
| Versiones pinneadas | rangeStrategy: "pin" — todas las deps se pinnean a versión exacta |
| No squash merge | automergeStrategy: "merge" en el preset |
Git Flow (develop como base) | baseBranchPatterns: ["develop"] en el preset — la rama por defecto del repo debe ser develop |
| Semantic commits | Renovate genera fix(deps): para deps, chore(deps): para devDeps |
| Quality gates | Los MRs de Renovate pasan por el mismo CI que cualquier MR |
| Majors requieren revisión | Los majors no se fusionan automáticamente — requieren aprobación manual |
Troubleshooting
El runner no crea MRs para mi repo:
- Verificar que
renovate.jsonexiste en la raíz de la rama por defecto del repo (developpara proyectos Git Flow,mainpara proyectos sin gestión de ramas). - Verificar que el runner tiene acceso de lectura al repositorio.
- 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
- renovate-runner — documentación completa del runner y el preset compartido
- Renovate Docs
- Preset compartido (fuente)
- Documentación interna del preset