Wiedii — Branch Protection Policy (GitLab)
Configurar en GitLab → Settings → Repository → Protected branches, tanto para main como para develop:
| Ajuste | main | develop |
|---|---|---|
| Allowed to push and merge | Maintainers | Maintainers |
| Allowed to merge (MRs) | Developers + Maintainers | Developers + Maintainers |
| Required approvals (min 1) | ✅ | ✅ |
| Dismiss stale MR approvals | ✅ | ✅ |
| Require status checks (pipelines) to pass | ✅ | ✅ |
| Require branch up to date | ✅ | ❌ |
| Allow force pushes | ❌ | ❌ |
| Allow deletions | ❌ | ❌ |
Qué logra esta configuración — push directo: solo mantenedores:
- Los mantenedores del proyecto (rol Maintainer) pueden hacer push directo a
mainydevelop, además de mergear MRs. - El resto del equipo (Developers) NO puede hacer push directo: debe integrar cambios vía Merge Request. Sí pueden mergear MRs aprobados (la regla "nadie fusiona su propio MR" sigue vigente).
- Nadie puede force-push ni borrar las ramas protegidas.
Aun teniendo permiso, se recomienda que los mantenedores usen MR para cambios no triviales (revisión + CI). El push directo queda para casos puntuales (hotfix operativo, sync, corrección menor).
GitLab → Settings → General → Merge Requests:
- ✅ Allow merge commits (for
--no-ff) - ❌ Allow squash merging — DISABLED
- ❌ Allow rebase merging — DISABLED
Nota sobre CE vs Premium
Las Approval Rules avanzadas (múltiples reglas, "Require Code Owner approval" forzado por sección) y CODEOWNERS son features Premium/Ultimate. En CE se cubre con:
- Política operativa documentada explícita: "nadie mergea su propio MR; un MR que toque
/docs/05-seguridad/requiere visto bueno escrito del equipo de Seguridad". - Pipeline CI/CD valida cada cambio antes de permitir merge.
- Required approvals (min 1) en la protección de rama garantiza revisión antes de merge.
Ver ci-caching para el pipeline.
Aplicar la protección al crear el repo (bloque copy-paste, CE-safe)
Al crear un repo, un humano con permisos de Maintainer/Owner aplica la protección el mismo día, tras el primer push (la rama debe existir). Es un bloque que se pega y se revisa antes de ejecutar (confirm-by-construction) — no una automatización que corra un agente ni una receta fleet-wide, porque POST .../protected_branches da 409 sobre una protección existente y la variante idempotente DELETE-luego-POST deja una ventana en la que main queda desprotegida. Solo campos CE (sin reglas de aprobación EE/Premium, sin CODEOWNERS, sin allowed_to_* por usuario — eso se cubre con política operativa + CI gate):
# Reemplazar :id por el project id o el path URL-encoded (p.ej. wildcat%2Fmi-repo)
glab api -X POST "projects/:id/protected_branches" -f name=main \
-f push_access_level=40 -f merge_access_level=40 -f allow_force_push=false
glab api -X PUT "projects/:id" -f merge_method=merge -f squash_option=never \
-f remove_source_branch_after_merge=true \
-f only_allow_merge_if_all_discussions_are_resolved=true
# Git Flow (repos con develop): repetir el POST para name=develop
glab api -X POST "projects/:id/protected_branches" -f name=develop \
-f push_access_level=40 -f merge_access_level=40 -f allow_force_push=false
push_access_level=40 / merge_access_level=40 = rol Maintainer (40); merge_method=merge + squash_option=never fuerzan --no-ff sin squash. /audit-project verifica este estado (detector de drift, solo lectura) pero no lo aplica — la aplicación necesita permisos que un dev normal no tiene. La reconciliación fleet-wide como config-as-code (Terraform provider GitLab) es un tema de Infra, fuera del plugin.