Add support to sort-by-license to GraphQL endpoint

What does this MR do and why?

Add LICENSE_ASC and LICENSE_DESC fields to DependencyInterface GraphQL Type.

References

Screenshots or screen recordings

Group Level

ASC DESC
Screenshot_2025-04-25_at_17.51.46 Screenshot_2025-04-25_at_17.26.12

Project Level

ASC DESC
Screenshot_2025-04-25_at_17.52.52 Screenshot_2025-04-25_at_17.53.17

How to set up and validate locally

For the validation of this MR you'll need to clone this project in your gdk.

Group Level

  1. Do not check out this branch yet. Go to your GraphQL playground and run the following query. It should fail since the feature isn't implemented yet:
{
  group(fullPath: "gitlab-org") {
    id
    name
    dependencyAggregations(sort: LICENSE_ASC) {
      nodes {
        id
        name
        licenses {
          name
          spdxIdentifier
        }
      }
    }
  }
}
  1. Check out the branch CK-527254-add-license-field-graphql.

We’re going to reduce the number of dependencies for easier validation. If you've imported the dependency test project I shared, you probably have >2000 dependencies, which makes sorting in ASC and DESC harder to verify.

  1. Let’s reduce it to the first 5 dependencies only. Open your rails console, run the following:
occurrences = Sbom::Occurrence.where(project_id: 23)
occurrences.count # should return >2073

ids_to_keep = occurrences.order(:id).limit(5).pluck(:id)
occurrences.where.not(id: ids_to_keep).delete_all

occurrences.count # should now return 5
  1. Now, let's update the licenses for three dependencies:
License 1
updated_license_1 = { "name" => "MIT", "spdx_identifier" => "MIT" }
occurrence_1 = occurrences.find(72)
occurrence_1.licenses = [updated_license_1]
occurrence_1.save!
License 2
updated_license_2 = { "name" => "Apache License 2.0", "spdx_identifier" => "Apache-2.0" }
occurrence_2 = occurrences.find(74)
occurrence_2.licenses = [updated_license_2]
occurrence_2.save!
License 3
updated_license_3 = { "name" => "Apache", "spdx_identifier" => "MPL-2.0" }
occurrence_3 = occurrences.find(71)
occurrence_3.licenses = [updated_license_3]
occurrence_3.save!

Note: sorting is based on the spdx_identifier, not name. That’s why the dependency with the name Apache License 2.0 comes before the one with name Apache, because Apache-2.0 comes before MPL-2.0 alphabetically. That's why we give the third license a name that doesn't really match with the spdx_identifier. We do this only because we want to make sure the sorting is done well.

  1. Go back to your graphql explorer and run the the same query again. You should now see that the first dependency has license Apache-2.0. The second one is MIT. The third one is MPL-2.0.
{
  group(fullPath: "gitlab-org") {
    dependencyAggregations(sort: LICENSE_ASC) {
      nodes {
        id
        name
        licenses {
          spdxIdentifier
        }
      }
    }
  }
}
  1. Change LICENSE_ASC to LICENSE_DESC in your query. Now, the license with where the spdx_identifier is Apache-2.0 should appear at the bottom.

Project Level

  1. Run the following query in your GraphQL explorer:
{
  project(fullPath: "gitlab-org/sec-rep") {
    name
    dependencies(sort: LICENSE_ASC) {
      nodes {
        id
        name
        licenses {
          name
          spdxIdentifier
        }
      }
    }
  }
}
  1. Change LICENSE_ASC to LICENSE_DESC in your query.

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 Charlie Kroon

Merge request reports

Loading