Skip to content

Fail TransferService only if there are namespaced npm packages

Kate Grechishkina requested to merge fix-transfer-projects-issue-370834 into master

What does this MR do and why?

This MR fixes issue #370834 (closed).

The initial approach was to update project.has_packages? method. For it to no longer take into account packages that have status: "pending_destruction".

The current approach is to instead fail the Groups::TransferService.transfer and Projects::TransferService.transfer only if there are npm packages that are not pending_destruction and have the scope of the namespace path.

This MR also cleans up duplicated specs related to this project.has_packages? method.

Screenshots or screen recordings

For database review

We are adding a with_npm_scope scope on Package model which is going to be used to search for npm Packages with specific names.

scope :with_npm_scope, ->(scope) { npm.where("name ILIKE :package_name", package_name: "@#{sanitize_sql_like(scope)}/%") }

We are using this scope twice. When searching for packages with specific name on a project:

SELECT
    1 AS one
FROM
    "packages_packages"
WHERE
    "packages_packages"."project_id" = 278964
    AND "packages_packages"."package_type" = 2
    AND (name ILIKE '@gitlab-org/%')
    AND "packages_packages"."status" != 4
LIMIT 1;

Query plan: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/17562/commands/58638

When searching for packages with specific name on a group:

SELECT
    "packages_packages".*
FROM
    "packages_packages"
WHERE
    "packages_packages"."project_id" IN (
        SELECT
            "projects"."id"
        FROM
            "projects"
        LEFT JOIN project_features ON projects.id = project_features.project_id
    WHERE
        "projects"."namespace_id" IN (
            SELECT
                "namespaces"."id"
            FROM
                "namespaces"
            WHERE
                "namespaces"."type" = 'Group'
                AND (traversal_ids @> ('{9970}')))
            AND (EXISTS (
                    SELECT
                        1
                    FROM
                        "project_authorizations"
                    WHERE
                        "project_authorizations"."user_id" = 1614863
                        AND (project_authorizations.project_id = projects.id))
                    OR projects.visibility_level IN (0, 10, 20))
                AND ("project_features"."repository_access_level" > 0
                    OR "project_features"."repository_access_level" IS NULL))
        AND "packages_packages"."version" IS NOT NULL
        AND "packages_packages"."package_type" = 2
        AND "packages_packages"."status" IN (0, 3)
    AND "packages_packages"."package_type" = 2
    AND (name ILIKE '@gitlab-org/%')
ORDER BY
    "packages_packages"."created_at";

Query plan: https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/17562/commands/58639

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

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 Kate Grechishkina

Merge request reports