REST API & GraphQL: read entries from packages_composer_packages table

📖 What does this MR do and why?

In Read entries from packages_composer_packages table (!204852 - merged) we've changed the Composer API to read composer packages from the detached packages_composer_packages table. Now, it's time to change Packages REST API and GraphQL API to also read composer packages from the detached packages_composer_packages table. The changes are implemented behind the feature flag.

The MR introduces a new .union method to Packages::Package class that combines two database tables packages_packages and packages_composer_packages with UNION for SQL queries.

Also it changes the three packages finders to use UNION when performing packages look up without knowing its type.

  • Packages::GroupPackagesFinder
  • Packages::PackagesFinder
  • Packages::PackageFinder

And lastly, it modifies the GraphQL PackageBaseType to handle correctly the case when the metadata fields for composer packages present in the same table.

Read entries from packages_composer_packages table (#569886)

🪟 Screenshots or screen recordings

No.

Database analysis

to be added

🛠️ How to set up and validate locally

Prerequisites

Enable the feature flag

Feature.enable(:packages_composer_packages_table)

Create a few packages in different groups and projects.

def fixture_file_upload(*args, **kwargs)
  Rack::Test::UploadedFile.new(*args, **kwargs)
end

g1 = FactoryBot.create(:group, :private)
g2 = FactoryBot.create(:group, :private)

project1 = FactoryBot.create(:project, :private, group: g1)
project2 = FactoryBot.create(:project, :private, group: g2)
project3 = FactoryBot.create(:project, :private, group: g1)

p1 = FactoryBot.create(:composer_package, project: project1)
p2 = FactoryBot.create(:composer_package, project: project2)
p3 = FactoryBot.create(:maven_package, project: project1)
p4 = FactoryBot.create(:composer_package, project: project3)

GraphQL

  1. Visit graphql explorer and execute the next query http://gdk.test:3000/-/graphql-explorer
query {
  group(fullPath: "{g1.full_path}") {
    id
    name
    packages {
      nodes {
        id
        name
      }
    }
  }
}

It should return packages of different type, including composer, from the group g1: p1, p3 and p4.

  1. Now, change the query to get the packages from project
query {
  project(fullPath: "{project1.full_path}") {
    id
    name
    packages {
      nodes {
        id
        name
      }
    }
  }
}

It should return packages of different type, including composer, from the project p1: p1 and p3.

REST API

  1. Create HTTP request to fetch the package's details docs.
$ curl --header "PRIVATE-TOKEN: <your_access_token>" "http://gdk.test:3000/api/v4/groups/{g1.id}/packages?"`

It should return packages of different type, including composer, from the group g1: p1, p3 and p4.

  1. Create HTTP request to fetch the package's details docs.
$ curl --header "PRIVATE-TOKEN: <your_access_token>" "http://gdk.test:3000/api/v4/projects/{project1.id}/packages?"`

It should return packages of different type, including composer, from the group g1: p1 and p3.

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 #569886

Edited by Dzmitry (Dima) Meshcharakou

Merge request reports

Loading