feat(danger): Block post-deploy migrations on security MRs

What does this MR do and why?

Adds a Danger rule that blocks post-deploy migrations on security merge requests.

Security MRs that add post-deploy migrations create a point of no return in production: once the migration runs, rollback becomes unavailable and the only mitigation is roll-forward (6+ hours, subject to pipeline failures). Historically ~1.3% of security fixes include post-deploy migrations, so blocking them by default is a low-risk, high-value change that guarantees a rollback window during patch releases.

The rule:

  • Fails on any security MR touching db/post_migrate/ (including the ee/ path).
  • Allows an authorized exception when the patch-release::pdm-approved label is present and was applied by a member of an authorized group (@gitlab-org/release/managers, @gitlab-org/delivery, or @gitlab-com/gl-security/product-security/psirt-group), verified via the label-events API.
  • Removes the label via the API and fails the check when it was applied by anyone outside those groups.
  • Records every bypass event — approved or rejected — as a permanent MR discussion thread for audit purposes.

This composes with the existing project-level PSIRT approval rule on the security mirror rather than replacing it.

References

How to set up and validate locally

The rule was validated end-to-end on a purpose-built test project (anganga/pdm-danger-test!2) since triggering it here requires a real security MR:

  1. Default block — a security MR adds db/post_migrate/* with no bypass label → Danger fails, comments the block message + runbook link.
  2. Authorized bypass — the patch-release::pdm-approved label is applied by a member of an authorized group → Danger warns (does not fail) and posts an approval audit thread.
  3. Unauthorized bypass — the label is applied by anyone else → the label is removed via the API, a rejection audit thread is posted, and the check fails.

All three paths are covered by spec/tooling/danger/post_deployment_migration_spec.rb (runs in CI on this MR).

Risk

Low. The rule only activates on security MRs (helper.security_mr?) that touch db/post_migrate/ — regular MRs and security MRs without post-deploy migrations are unaffected. All API calls (label-events lookup, group-membership check, label removal, audit-thread creation) are wrapped in rescue blocks that degrade gracefully (fail-safe to a warning) rather than crashing the Danger run. No changes to any existing rule.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Merge request reports

Loading