Link to SBOM generation jobs from License Compliance page

Problem to solve

In the License Compliance page, latest successful scan always links to the latest CI job that uploaded License Scanning artifacts. However, it should link to the jobs that uploaded the SBOMs when the License Scanning SBOM Scanner is used.

Further details

LicensesController#index fetches the latest_build_for_default_branch from the SCA::LicenseCompliance object, and then passes on to the serializer.

See code

See https://gitlab.com/gitlab-org/gitlab/-/blob/2d96d6b20fd044532eb80254c608d1bde7277a73/ee/app/controllers/projects/licenses_controller.rb#L25

        format.json do
          ::Gitlab::UsageDataCounters::LicensesList.count(:views)

          license_compliance = project.license_compliance
          render json: serializer.represent(
            pageable(matching_policies_from(license_compliance)),
            build: license_compliance.latest_build_for_default_branch,
            project: project
          )
        end

#latest_build_for_default_branch returns the latest job that has License Scanning artifacts. See https://gitlab.com/gitlab-org/gitlab/-/blob/352f6d27474b04966192c44b5b1e63e844a52b59/ee/app/models/sca/license_compliance.rb#L35

    def latest_build_for_default_branch
      return if pipeline.blank?

      strong_memoize(:latest_build_for_default_branch) do
        pipeline.builds.latest.license_scan.last
      end
    end

See https://gitlab.com/gitlab-org/gitlab/-/blob/352f6d27474b04966192c44b5b1e63e844a52b59/ee/app/models/ee/ci/build.rb#L44

        scope :license_scan, -> { joins(:job_artifacts).merge(::Ci::JobArtifact.of_report_type(:license_scanning)) }

Proposal

When the SBOM Scanner is used, link to the latest SBOM generation job used as an input.

  • Pro: The UX doesn't change.
  • Pro: The frontend and API don't change. This is not a multi-step migration.
  • Con: This is not accurate since the input of the License Scanning SBOM Scanner might come from multiple jobs.
  • Con: There's some backend work to return one of the jobs that uploaded a SBOM.
See other proposals
  • Link to the latest pipeline that has license scanning data. The latest pipeline can be found by calling the #latest_pipeline method on a class that inherits from ::Gitlab::LicenseScanning::BaseScanner.
    • Pro: It supports the case where SBOM generators run as separate jobs.
    • Con: It doesn't support the case where SBOMs are cached, and might come from different pipelines.
  • Link to all the jobs that provided the input of License Scanning. This could either be a single License Scanning job that uploaded a License Scanning artifact, or multiple SBOM generation jobs.
    • Con: This is a larger change.
    • Con: This might require UX work.
  • Remove the link.
    • Con: The UX changes.

Implementation plan

  • Add a new #latest_build_for_default_branch to LicenseScanning::BaseScanner.
  • Implement in LicenseScanning::ArtifactScanner (call pipeline.builds.latest.license_scan.last).
  • Implement in LicenseScanning::SbomScanner.
  • Update SCA::LicenseCompliance#latest_build_for_default_branch, and make it delegate to #scanner, the License Scanning scanner.

The LicensesController and the frontend code using it doesn't need to change.

Verification steps

  1. Create a project w/ dependency files supported by Dependency Scanning and the License DB.
  2. Enable the feature flag introduced by Implement License Scanning SBOM scanner (#384932 - closed) for the specified project.
  3. Run a pipeline for the default branch with Dependency Scanning and License Scanning.
  4. Go to the License Compliance page, and check that the latest successful scan links to the latest Dependency Scanning job.
  5. Disable the feature flag introduced by Implement License Scanning SBOM scanner (#384932 - closed) for the specified project.
  6. Go to the License Compliance page, and check that the latest successful scan links to the latest License Scanning job.

Relevant links/issues

/cc @fcatteau @sam.white

Edited by Oscar Tovar