Warn when the HTTP Router routing snapshot has drifted

What does this MR do and why?

GitLab owns the canonical route list in config/routing/gitlab_routes.json. The Cells HTTP Router mirrors it at test/routes/gitlab_routes.json, but nothing told a route author when the router had fallen behind. Until the paired router MR merges, the router cannot classify the new route, so requests can reach the wrong cell.

This MR adds:

  • Gitlab::Cells::HttpRouter::SnapshotComparison in gems/gitlab-cells-http_router: compares two snapshot payloads, reporting byte equality plus which route templates each side holds exclusively. A payload that is not a routing snapshot raises rather than reporting every route as drifted. Covered by 12 specs in the gem's suite.
  • scripts/cells/check_router_routes_sync.rb: thin caller. Downloads the router's copy, maps the result to an exit code, prints the report. Exits 1 on drift, 2 on a download failure.
  • A job cells-routes:router-in-sync in .gitlab/ci/cells.gitlab-ci.yml. Runs on ruby:${RUBY_VERSION}-alpine3.23 with needs: [] and allow_failure: true.
  • Rules in .gitlab/ci/rules.gitlab-ci.yml: MR pipelines only, only when config/routing/gitlab_routes.json changes, never on FOSS, JiHu, or stable branches. Skippable with the pipeline:skip-router-sync label.
  • A new section in doc/development/cells/http_router.md.

The logic sits in the gem and the script stays thin, mirroring how lib/tasks/gitlab/cells/routes.rake already delegates to RoutesSnapshot. That puts the part with real edge cases where it can have specs. The gem has no runtime dependencies, so the job loads it with plain Ruby and still needs no bundle, keeping needs: [].

The changes: scoping is required: the router MR merges first by design, so the router stays ahead of master until the GitLab side lands. An unscoped job would fail on unrelated MRs meanwhile.

The separate exit code for a download failure exists because a 404 returns an HTML page, which would otherwise look like drift. It also allows a later switch to allow_failure: exit_codes: 2, blocking on real drift while treating a network blip as non-blocking.

Verified all four outcomes (in sync, drift, wrong ref, non-snapshot payload) against the live router on macOS and on a bare ruby:3.3-alpine3.23 container with no bundle, and confirmed the rules against a dry-run pipeline.

Example of the script's output can be found in !252485 (comment 3787111133).

References

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Marco Gregorius

Merge request reports

Loading
Loading