Add Policy Store deployment gate catalog

What does this MR do and why?

The Build policy step renders whatever the catalog declares: a trigger, the rules that gate it, and the actions taken when they match. This adds that catalog for the CD deployment gate experiment as local constants, so the editor can be built and tested before the metadata endpoints exist.

MR A2 of the Build policy step plan in https://gitlab.com/gitlab-org/gitlab/-/issues/607341#mr-breakdown.

Scope: one trigger, five rules, two actions

Entry Persisted id
Trigger Deployment deployment_requested
Rule Custom (Rego) custom
Rule Freeze window freeze_window
Rule Environment state environment_state
Rule Soak time soak_time
Rule Environment promotion environment_promotion
Action Block block
Action Require approval require_approval

A new catalog/ directory

Catalog entries are data, not components, so they live in policy_store/catalog/ rather than under components/. rego_templates.js and helpers.js move there from components/editor/ for the same reason — two renames, no behaviour change.

Three things worth a reviewer's attention

  1. id is the wire value. Each id is what gets persisted and read back, so there is no translation layer between editor and API. The prototype this is ported from carried alias maps (regocustom, freeze_windowcalendar, …) to paper over a mismatch; those are deliberately not brought across.

    custom in particular is fixed rather than chosen. EE::Ci::ProcessBuildService#rego_of finds a policy's Rego with rule['type'] == 'custom', so the prototype's rego would simply not have been found.

  2. There is no warn action. Warn is an enforcement mode, and block behaves differently depending on it. The UX prototype's Warn action conflates the two; see https://gitlab.com/groups/gitlab-org/-/work_items/22027#note_3503222326.

  3. Only the Rego rule is evaluated today. The deployment gate does next false if rego_of(policy).blank?, so a policy built from freeze_window, environment_state, soak_time or environment_promotion alone is authorable, persisted, and silently ignored at deployment time. The four typed rules ship as authoring-only until the policy engine lands (https://gitlab.com/groups/gitlab-org/-/work_items/22543). That is a scope decision, recorded here so it is not a surprise.

Field definitions come from the prototype in ee/app/assets/javascripts/security_policies/constants, renamed to the persisted ids and re-namespaced to PolicyStore|.

References

Screenshots or screen recordings

No UI change. Nothing consumes the catalog yet — the Build policy step that renders it is MR A3. This MR is data plus a shape spec.

How to set up and validate locally

There is nothing to click in this MR alone. To see the catalog rendered, use the A3 branch, which includes these commits.

yarn jest ee/spec/frontend/policy_store

The shape spec is the point of the tests here: it asserts every entry has a unique id, every field declares a type that GenericConfig can actually render, every select and multi_badge field has non-empty { id, label } options, and that the scope is exactly the eight entries above with no warn action. A mistyped type in catalog data otherwise fails silently — it falls through to a text input.

MR acceptance checklist

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

Merge request reports

Loading
Loading