Skip to content

Remove the pipelines field from the package versions connection

🛁 Context

In GraphQL, we have mainly 2 types that are used to present a package model:

flowchart BT
    Types::Packages::PackageDetailsType --> Types::Packages::PackageType

Basically, Types::Packages::PackageType is the type when returning a set of packages (such as a listing) and Types::Packages::PackageDetailsType is used when we return a single package. Types::Packages::PackageDetailsType contains all the fields of Types::Packages::PackageType.

Packages can be accessed:

  • using the group or the project. This returns a list of packages, so Types::Packages::PackageType.
  • using the package global id. This returns a single package, so Types::Packages::PackageDetailsType.

The problem we have is that Types::Packages::PackageDetailsType has a field versions that return a list of packages (namely all the other versions of this package within the project). This field returns a Types::Packages::PackageType.

The problem is that Types::Packages::PackageType has a field pipelines which can return the pipelines of the package.

Returning the pipelines field for the package objects that are in the versions field is not necessary. Users can always get the package global id and get the package details of that package. The pipelines can be queried in when getting the details of a single package.

We're thus removing this field for the type used in the versions field.

Note that in !82496 (merged), we improved the performance of the pipelines. Still, this pipelines field in the versions connection type is really not necessary.

The version field is not read that often source(internal). The main user of that field should be the frontend and the frontend doesn't need the pipelines field for the versions objects.

Solution design

Because we re-use a type for the versions field, we will need to split the needs of:

  1. returning a list of packages.
  2. returning packages for the versions field.

(1.) needs to have the pipelines field but not (2.)

Because of the above, we're going to shuffle the type hierarchy a bit:

flowchart BT
    Types::Packages::PackageBaseType --> Types::Packages::PackageType
    Types::Packages::PackageDetailsType --> Types::Packages::PackageType
  • Types::Packages::PackageBaseType - Type that encapsulates all common fields.
    • This is what versions will return.
  • Types::Packages::PackageType - Type that returns all common fields + pipelines.
    • This is going to be used when returning a list of packages (as it is currently).
  • Types::Packages::PackageDetailsType - Type that returns all common fields + pipelines + fields for a "detailed" view.
    • This is returned by the single package query (as it is currently).

🔬 What does this MR do and why?

  • Add the Types::Packages::PackageBaseType.
  • Update the Types::Packages::PackageType to inherit from Types::Packages::PackageBaseType. Keep the pipelines field here.
  • Update the Types::Packages::PackageDetailsType versions field so that a connection on Types::Packages::PackageBaseType is returned.
  • Update the related specs.

One word on the deprecation notice. It was there on the pipelines field of Types::Packages::PackageType but !82496 (merged) removed it because it solve the performance issue we had with Types::Packages::PackageType.

📸 Screenshots or screen recordings

n / a

How to set up and validate locally

  1. Create a project

  2. In a rails console, create multiple packages with the same name

    def fixture_file_upload(*args, **kwargs)
      Rack::Test::UploadedFile.new(*args, **kwargs)
    end
    name = 'test_package'
    
    5.times do
      pkg = FactoryBot.create(:npm_package, name: name, project: Project.find(<project_id>))
    
      # creates 5 pipelines
      3.times { Packages::BuildInfo.create!(package_id: pkg.id, pipeline_id: FactoryBot.create(:ci_pipeline, project: project).id) }
    end
  3. Note the gid of one of the packages with:

    Packages::Package.last.to_global_id.to_s
  4. Access the package details with this GraphQL query:

    Query
    {
      package(id: <package_gid>) {
        id
        name
        version
        pipelines {
          nodes {
            id
          }
        }
        versions {
          nodes {
            id
            name
            version
          }
        }
      }
    }

Note that within the versions field, we don't have the pipelines field

🚥 MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by David Fernandez

Merge request reports