Add background jobs for group and project secret rotation reminders
What does this MR do and why?
Adds separate background workers and services for processing project and group secret rotation reminders, as part of #577344 (closed).
With GroupSecretRotationInfo records now being created and surfaced through the services in !225562 (merged) and !225935 (merged), this MR wires up the notification side so that group secret owners receive rotation reminder emails when secrets are due — mirroring the existing project secret rotation reminder job.
Rather than extending the existing SecretRotationBatchReminderService to process both types in a single pass (which would break the worker's loop-exit logic since a full project batch would mask pending group records), this MR introduces separate workers and services for each resource type so they run independently and can be scaled or tuned separately.
Implementation details
Services:
-
BaseSecretRotationBatchReminderService— new abstract base class (renamed fromSecretRotationBatchReminderService) holding all shared batch processing logic:pending_remindersquery, orphan detection via polymorphic#resourceon each rotation info model, and logging; notification dispatch is delegated to subclasses via the abstractsend_rotation_remindermethod -
ProjectSecretRotationBatchReminderService— thin subclass definingrotation_info_class = ProjectSecretRotationInfoandsend_rotation_remindercallingnotification_service.secret_rotation_reminder_for_project -
GroupSecretRotationBatchReminderService— thin subclass definingrotation_info_class = GroupSecretRotationInfoandsend_rotation_remindercallingnotification_service.secret_rotation_reminder_for_group -
SecretRotationBatchReminderService— deprecated no-op (replaced by the above two; removed from cron, kept for safe in-flight job handling per GitLab worker deprecation guidelines)
Models — adds #resource to each rotation info model so the base service needs no is_a? checks:
-
ProjectSecretRotationInfo#resource— returnsproject -
GroupSecretRotationInfo#resource— returnsgroup
Workers:
-
BaseSecretRotationReminderBatchWorker— new abstract base worker with sharedperformloop logic (runtime limiter, batch counting, metadata logging); loop exits whenprocessed_count + skipped_count < BATCH_SIZE; subclasses defineservice_class -
ProjectSecretRotationReminderBatchWorker— thin subclass -
GroupSecretRotationReminderBatchWorker— thin subclass -
SecretRotationReminderBatchWorker— deprecated no-op per GitLab worker deprecation guidelines; removed from cron schedule
Notifications:
- Renamed
NotificationService#secret_rotation_reminder→secret_rotation_reminder_for_project(project-specific, no type dispatch) - Added
NotificationService#secret_rotation_reminder_for_group— sends rotation reminder emails to group owners - Renamed
secret_rotation_reminder_emailmailer method →project_secret_rotation_reminder_emailfor naming symmetry - Added
group_secret_rotation_reminder_emailmailer method with HTML/text templates - Added preview methods for both in
notify_preview.rb
Cron schedule (1_settings.rb):
- Removed
secret_rotation_reminder_batch_worker(no-op worker no longer needs scheduling) - Added
project_secret_rotation_reminder_batch_worker(* * * * *) - Added
group_secret_rotation_reminder_batch_worker(* * * * *)
Worker deprecation (per GitLab guidelines):
- M (this MR):
SecretRotationReminderBatchWorker#performreplaced with no-op; removed from cron; new workers added - M+1: migration using
sidekiq_remove_jobsto drain any in-flight jobs - M+2: delete the worker class file
Specs:
-
secret_rotation_batch_reminder_service_examples.rb— shared examples ('a batch reminder service processing secrets') covering: no secrets needing reminders, batch size limiting, eligible secrets processing, version-mismatch orphan cleanup, and general orphaned record cleanup; both project and group specs are now thin wrappers around this shared example -
project_secret_rotation_batch_reminder_service_spec.rb— thin spec using shared examples -
group_secret_rotation_batch_reminder_service_spec.rb— thin spec using shared examples -
secret_rotation_reminder_batch_worker_examples.rb— shared examples ('a secret rotation reminder batch worker') covering: loop/batch/runtime unit tests + idempotent worker integration test -
project_secret_rotation_reminder_batch_worker_spec.rb— thin spec using shared examples -
group_secret_rotation_reminder_batch_worker_spec.rb— thin spec using shared examples -
secret_rotation_reminder_batch_worker_spec.rb— reduced to no-op test
Series overview
Part of a series for #577344 (closed):
| # | MR | Description |
|---|---|---|
| 1 | !225247 (merged) | DB migration + GroupSecretRotationInfo model + BaseSecretRotationInfo base class |
| 2 | !225338 (merged) | Rename SecretRotationInfo → ProjectSecretRotationInfo for naming consistency |
| 3 | !225562 (merged) | CreateService + UpdateService + GraphQL mutations (add rotation_interval_days param) |
| 4 | !225935 (merged) | List/Read services + GroupSecretType GraphQL type (add rotation info loading/field) |
| 5 |
|
Background jobs for group and project secret rotation reminders |
References
- Resolves #577345 (closed)
- Depends on !225935 (merged)
- Related epic: &17904
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.