Skip to content

Fix publishing npm package with custom root folder name

Context

In Add worker to upload npm packages async (!146493 - merged), we introduced uploading NPM packages async. After that, some customers reported that whenever they try to upload their NPM packages, they encounter this error: Error publishing · package.json not found.

After looking into it, it turned out that the 🐛 happens when customers try to publish manually packaged archives with a root folder with custom name.

In the codebase, We are expecting that folder to be named package (source). If the root folder is named anything different from package, the package.json not found error will be raised.

This happens if they publish manually packaged archives. The issue is reproducible: example project. This happens if the archive with the bundle has a root folder with custom name, like so.

A fix for this issue was previously introduced in !155842 (merged), but later it caused an incident after merging this security patch. So we reverted it, and we now reintroduce a definitive fix in this MR.

What does this MR do and why?

  • Update how we look for package.json file in the uploaded NPM archive. So instead of looking for package/package.json, we look for a file matches the ^[^/]+/package.json$ regex. The regex also guarantees that we only catch the root package.json which lies in one level directory structure. If we have a nested package.json (in foo/bar/package.json for ex), it will be ignored.
  • Update the related specs.

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

  1. Enable the feature flag:

    Feature.enable(:allow_custom_root_folder_name_in_npm_upload)
  2. Make sure you have a runner up & running within your GDK.

  3. Create a new project and open GitLab web IDE. Add the following three files to the project:

    1. index.js
    2. package-template.json
    3. .gitlab-ci.yml
    npm-registry:
      stage: test
      image: node:lts-slim
      script:
        - apt-get update && apt-get install gettext-base -y
        - export NPM_PACKAGE_SCOPE=$(echo $CI_PROJECT_NAMESPACE | cut -d '/' -f 1)
        - <package-template.json envsubst > package.json
        - echo >>  package.json
        - mkdir gitlab-smoke-tests-bundle
        - mv package.json gitlab-smoke-tests-bundle/package.json
        - tar -zcvf gitlab-smoke-tests.tar.gz gitlab-smoke-tests-bundle
        - npm config set @${CI_PROJECT_ROOT_NAMESPACE}:registry ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/
        - npm config set ${CI_API_V4_URL#http?}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken ${CI_JOB_TOKEN}
        - npm publish --verbose --tag dev gitlab-smoke-tests.tar.gz
  4. After the pipeline is green, navigate to the project's Deploy => Package Registry page. The package should be published successfully.

  5. Switch to master and retry the job and navigate to the Package Registry page, you should see the same package is failed to be published with this error Error publishing · package.json not found

Related to #463327

Edited by Moaz Khalifa

Merge request reports