Add monthly cadence option to scan execution policy rule mode
Why are we doing this work
Scan execution policies support scheduled scans via a cadence cron expression. The backend already accepts monthly cadences (for example 0 0 1 * * or 0 0 1,15 * *) — the CadenceChecker regex, Gitlab::Ci::CronParser, and the rule-mode cron gate (cron-validator) all pass them, and the docs document monthly scheduling.
However, the rule-mode policy editor only offers daily and weekly cadences. A user who wants a monthly schedule must drop to YAML mode. This was a deliberate scoping decision when the schedule rule builder was first added (see merge request !95192 and issue 359886: "limit users to only specific schedules, allowing a user to use YAML mode to do anything more complicated"). The equivalent pipeline execution schedule policy editor was later built with first-class monthly support, so scan execution policies are now inconsistent.
There is also a latent correctness gap: a monthly cron opened in rule mode is currently mis-classified as daily, and editing silently rewrites and narrows the schedule.
Proposal
Add Monthly as a selectable cadence in the scan execution policy rule-mode schedule builder, mirroring the pipeline execution schedule policy UI:
- Add
monthlyto the cadence/period dropdown. - When monthly is selected, show a multi-select Days of month dropdown (1-31), generating cadences like
0 9 1,15 * *. - Reuse the day-of-month selection pattern from the pipeline execution schedule policy editor.
Because the builder represents schedules as a fixed cron shape, also close the round-trip gap: any cadence the builder cannot represent exactly (ranges, steps, L, minute offsets, arbitrary cron) should fall back to YAML mode rather than being silently coerced.
Implementation plan
- Frontend only — no backend, GraphQL, database, or feature-flag changes (the backend already supports monthly cadences).
- Add a
monthlyperiod key and label to the scan execution constants. - Extend the cron helpers to build and parse a day-of-month field, and add a 3-way (daily/weekly/monthly) period detector. Fix the existing mis-classification where a monthly cron reads as daily.
- Update the schedule rule component to render the monthly period option and a multi-select days-of-month dropdown, with time preserved across period switches.
- Extract the shared
getMonthlyDayOptionshelper so both scan execution and pipeline execution schedule policies use one source. - Guard rule-mode entry so non-representable cadences route to YAML mode (disable the rule section) instead of silently rewriting.
- Update the scan execution policy documentation cadence section.
Acceptance criteria
- A user can select Monthly in the scan execution policy rule-mode schedule builder.
- Selecting monthly reveals a multi-select days-of-month control (1-31); the generated cadence uses the day-of-month field (for example
0 9 1,15 * *). - An existing monthly policy opened in rule mode displays its correct cadence (no longer mis-shown as daily) and edits without data loss.
- Selecting the time or days does not reset the previously selected hour when switching cadence period.
- A cadence that rule mode cannot represent exactly (ranges, steps,
L, minute offsets) disables the rule section and can still be edited in YAML mode. - Jest coverage for the cron helpers (build/parse round-trip, period detection, representability) and the schedule rule component (monthly selection, day sorting, parse-on-load).
- Documentation updated to reflect monthly as a rule-mode option.
Verification steps
- Upload a GitLab Ultimate license.
- Go to a project, then Secure > Policies > New policy > Scan execution policy.
- Add a schedule rule and select the Monthly cadence.
- Select one or more days of the month and a time; confirm the YAML shows the expected cadence (for example
0 9 1,15 * *). - Switch to YAML, enter a cadence with a range (for example
0 0 1-5 * *), and confirm rule mode is disabled and directs you to YAML.
References
- Original schedule rule builder: merge request !95192, issue 359886
- Epic: Allow users to edit rule-mode scan execution policies in the policy UI (&5363)
- Scan execution policy docs:
doc/user/application_security/policies/scan_execution_policies.md