Fix compressed time_window for initial SPEP schedule creation

What does this MR do and why?

Fixes compressed time_window distribution when a Scheduled Pipeline Execution Policy is created shortly before its first cron trigger.

Problem

A customer observed that a weekly SPEP with a 60-hour time_window created 2-3 hours before the scheduled start did not distribute runs across the configured window. Instead, all ~10,000 project scans completed within ~2.5 hours, risking runner exhaustion.

Root cause

effective_time_window caps the random delay to prevent overlap with the next scheduled run. For newly created schedules, this capped against the upcoming trigger — so creating a policy 2 hours before Friday 19:00 compressed a 60-hour window down to 2 hours.

Solution

For initial schedule creation (detected via new_record?), cap against the second cron occurrence instead of the first. This allows the full time_window to be used for the first run while still preventing overlap on subsequent runs.

Before: min(time_window, seconds_until_first_trigger) After (new records): min(time_window, seconds_until_second_trigger)

References

Closes #630055

Screenshots or screen recordings

Not applicable — backend-only change.

How to set up and validate locally

  1. Create a weekly SPEP with a large time_window (e.g., 60 hours)
  2. Save it shortly before the scheduled trigger time
  3. Verify next_run_applied_delay uses the full window, not capped to the time remaining until trigger

Or run the new spec:

bundle exec rspec ee/spec/models/security/pipeline_execution_project_schedule_spec.rb \
  -e "first run time_window distribution"

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.

Edited by Andy Schoenen

Merge request reports

Loading
Loading