Skip to content

Sync npm metadata cache when package is marked for destruction

What does this MR do and why?

When a package needs to be deleted it'll be first marked for destruction. This also happens when a package gets deleted via REST or GraphQL API. Now when the npm package is deleted via REST API, we trigger the background job to synchronize a metadata cache, but we do it when the npm package is deleted via GraphQL API.

This MR adds the logic to synchronize npm metadata cache when a package is marked for destruction, whether through the API or otherwise.

Additionally I open a new issue to delete npm metadata cache completely when a package doesn't exist anymore Delete npm metadata cache when a package does n... (#432982)

Screenshots or screen recordings

No.

How to set up and validate locally

Make sure that sidekiq is up and running.
Execute the following commands in the Rails console.

  1. Create two npm packages and metadata cache entry.

    # stub file upload
    def fixture_file_upload(*args, **kwargs)
      Rack::Test::UploadedFile.new(*args, **kwargs)
    end
    
    # Choose any project
    project = Project.first
    
    5.times do |i|
      FactoryBot.create(:npm_package, project: project, name: 'npm-package-test', version: "#{i}.0.0")
    end
    
    Packages::Npm::CreateMetadataCacheService.new(project, 'npm-package-test').execute
  2. Check npm metadata cache entry: it should contain all 5 packages

    JSON.parse(Packages::Npm::MetadataCache.find_by(package_name: 'npm-package-test').file.read)
  3. Create a request to destroy the "npm-package-test" version 1.0.0 with REST API

    package_id = Packages::Package.select(:id).find_by(name: 'npm-package-test', version: '1.0.0')
    curl --header "PRIVATE-TOKEN: <PAT>" -X DELETE "http://gdk.test:3000/api/v4/projects/<project_id>/packages/<package_id>"
  4. Check npm metadata cache entry: it should contain packages versions except 1.0.0

    JSON.parse(Packages::Npm::MetadataCache.find_by(package_name: 'npm-package-test').file.read)
  5. Create a request to destroy the "npm-package-test" version 2.0.0 with GraphQL API

    package_id = Packages::Package.select(:id).find_by(name: 'npm-package-test', version: '2.0.0')
    mutation destroyPackage {
      destroyPackage(input: { id: "gid://gitlab/Packages::Package/<package_id>" }) {
        errors
      }
    }
  6. Check npm metadata cache entry: it should contain packages versions except 1.0.0 and 2.0.0

    JSON.parse(Packages::Npm::MetadataCache.find_by(package_name: 'npm-package-test').file.read)
  7. Create a request to bulk destroy the "npm-package-test" version 3.0.0 and 4.0.0 with GraphQL API

    package_ids = Packages::Package.select(:id).find_by(name: 'npm-package-test').where.not(version: '5.0.0')
    mutation destroyPackages {
      destroyPackages(input: { ids: ["gid://gitlab/Packages::Package/<package_1_id>", "gid://gitlab/Packages::Package/<package_2_id>"] }) {
        errors
      }
    }
  8. Check npm metadata cache entry: it should contain only 5.0.0 version

    JSON.parse(Packages::Npm::MetadataCache.find_by(package_name: 'npm-package-test').file.read)

MR acceptance checklist

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

Related to #432405 (closed)

Edited by Dzmitry Meshcharakou

Merge request reports