Sort recommended scan profiles first

What does this MR do and why?

Sort recommended scan profiles first

Order the profiles ScanProfilesResolver returns so gitlab-recommended
ones come first, then by name.

Sort after concatenating the persisted profiles with the applicable
defaults, because an unpersisted recommended profile exists only in the
defaults and ordering the query alone would still leave it last. Break
ties on name, since sort_by is unstable and the defaults have no id yet.
The profile dropdowns render this list in the order they receive it, and
the enable-scanners wizard takes the first entry as its default.

Related to https://gitlab.com/gitlab-org/gitlab/-/issues/624190
Changelog: fixed
EE: true

context: So far, we've only ever shown one profile per scan type in dropdowns: the default gitlab-recommended enablement-only profile. We're now adding support for custom profiles starting with custom secret detection profiles, which means there will be more than one profile in dropdowns, so we need to make sure that the gitlab-recommended enablement-only profile remains first in the list so that it is selected by default. We've decided there will be only one gitlab-recommended profile per scan type, so ordering the list with gitlab-recommended profiles first should be enough.

References

Screenshots or screen recordings

Before After
no particular order
Screenshot_2026-09-01_at_16.24.05
default profiles sort first
Screenshot_2026-09-01_at_16.26.11

How to set up and validate locally

git checkout 624190-sort-recommended-scan-profiles-first
  1. have a GitLab Ultimate licence

  2. create a brand new top-level group with one project in it, so no scan profiles exist for it yet

    • you need Maintainer, Owner or Security Manager on that group
  3. create a custom secret detection profile in the new group, named so it sorts alphabetically before Secret Detection (default)

    • open GraphiQL at /-/graphql-explorer
    • run the mutation below, using the new group's gid://gitlab/Group/<group_id>
    expand for the create mutation
    mutation {
      securityScanProfileCreate(
        input: {
          namespaceId: "gid://gitlab/Group/<group_id>"
          scanType: SECRET_DETECTION
          name: "A custom profile"
          description: "profile for testing sort order"
          triggers: [{ triggerType: MERGE_REQUEST_PIPELINE }]
        }
      ) {
        scanProfile {
          id
          name
        }
        errors
      }
    }

while the default profile is not yet stored

  1. in GraphiQL, query the new group for availableSecurityScanProfiles { id name gitlabRecommended } and check that:

    • Secret Detection (default) comes back before A custom profile
    • every gitlabRecommended profile appears ahead of every custom one
    • within each of those two blocks, profiles are ordered by name

    On master the default profile is appended after the stored ones, so it comes back last here.

after the default profile is stored

  1. go to the project in the new group => Secure => Security configuration
  2. on the secret detection row, select Apply default profile
    • this is what actually creates the default profile as a stored record, so it is now stored after the custom one
  3. repeat the GraphiQL query from step 4 and check that Secret Detection (default) is still first

verify in the ui

  1. reload the project => Secure => Security configuration and open the profile dropdown on the secret detection row
  2. check that Secret Detection (default) is listed above A custom profile
  3. go to the new group => Secure => Security configuration => Scanners and select Enable scanners
  4. on Select scanners, check that the secret detection row's profile dropdown:
    • pre-selects Secret Detection (default)
    • lists Secret Detection (default) first when opened
  5. continue to Review configuration and check that the Profile column for secret detection shows Secret Detection (default)

to prove it was broken before

  1. git checkout master, reload, and repeat steps 7 to 11
    • A custom profile now sorts ahead of Secret Detection (default), and the wizard pre-selects it

to run tests

bundle exec rspec ee/spec/graphql/resolvers/security/scan_profiles_resolver_spec.rb

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 #624190 (closed)

Edited by Miranda Fluharty

Merge request reports

Loading
Loading