Add profile_based_update_service for analyzer statuses updates

What does this MR do and why?

Fix profile-based analyzer status updates not taking effect for SAST and DS.

Previously, attaching or detaching new type of security scan profile (SAST, dependency scanning) had no effect on Security::AnalyzerProjectStatus, causing the statuses not to update.

This MR introduces ProfileBasedUpdateService to handle the profile-based types. It sets changes status only if no existing pipeline result exists (build_id: nil) to preserve existing result.

Shared basic logic is extracted into BaseUpdateService to eliminate duplication between ProfileBasedUpdateService and SettingsBasedUpdateService.

Changelog: added
EE: true

How to set up and validate locally

  1. Create a root group root and subgroup g with project p.
  2. Ensure no SAST scan profile is attached to project p.
  3. Verify their analyzer status is absent or :not_configured via:
    project.analyzer_statuses.sast
  4. In the UI, go to root security inventory and make sure the SAST status is also not_configured.
  5. Enable SAST scan profile FF:
     ::Feature.disable(:security_scan_profiles_sast)
  6. Attach default SAST scan profile to one of the projects from the UI.
  7. Verify the project's SAST analyzer status is now :success with no build_id in the UI or using:
    project.analyzer_statuses.sast.first
  8. Detach the profile and make sure the status changes back to not_configured.
  9. To verify pipeline results are not overridden, manually set to success with build_id on an analyzer status:
    project.analyzer_statuses.sast.first.update(status: "success", build: Ci::Build.last)
  10. Attach and detach the profile to make sure the status doesn't change.

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.

Related to #591256 (closed)

Merge request reports

Loading
Loading