Publish npm packages to the GitLab package registry using semantic-release

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

This guide demonstrates how to automatically publish npm packages to the GitLab package registry by using semantic-release.

You can also view or fork the complete example source.

Initialize the module

  1. Open a terminal and go to the project’s repository.
  2. Run npm init. Name the module according to the package registry’s naming conventions. For example, if the project’s path is gitlab-examples/semantic-release-npm, name the module @gitlab-examples/semantic-release-npm.

  3. Install the following npm packages:

    npm install semantic-release @semantic-release/git @semantic-release/gitlab @semantic-release/npm --save-dev
    
  4. Add the following properties to the module’s package.json:

    {
      "scripts": {
        "semantic-release": "semantic-release"
      },
      "publishConfig": {
        "access": "public"
      },
      "files": [ <path(s) to files here> ]
    }
    
  5. Update the files key with glob patterns that selects all files that should be included in the published module. More information about files can be found in the npm documentation.

  6. Add a .gitignore file to the project to avoid committing node_modules:

    node_modules
    

Configure the pipeline

Create a .gitlab-ci.yml with the following content:

default:
  image: node:latest
  before_script:
    - npm ci --cache .npm --prefer-offline
    - |
      {
        echo "@${CI_PROJECT_ROOT_NAMESPACE}:registry=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/"
        echo "${CI_API_V4_URL#https?}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=\${CI_JOB_TOKEN}"
      } | tee -a .npmrc
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .npm/

workflow:
  rules:
    - if: $CI_COMMIT_BRANCH

variables:
  NPM_TOKEN: ${CI_JOB_TOKEN}

stages:
  - release

publish:
  stage: release
  script:
    - npm run semantic-release
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

This example configures the pipeline with a single job, publish, which runs semantic-release. The semantic-release library publishes new versions of the npm package and creates new GitLab releases (if necessary).

The default before_script generates a temporary .npmrc that is used to authenticate to the package registry during the publish job.

Set up CI/CD variables

As part of publishing a package, semantic-release increases the version number in package.json. For semantic-release to commit this change and push it back to GitLab, the pipeline requires a custom CI/CD variable named GITLAB_TOKEN. To create this variable:

  1. On the left sidebar, select your avatar.
  2. Select Preferences > Access tokens.
  3. In the Token name box, enter a token name.
  4. Under select scopes, select the api checkbox.
  5. Select Create project access token.
  6. Copy the value.
  7. On the left sidebar, select Search or go to and find your project.
  8. Select Settings > CI/CD.
  9. Expand Variables.
  10. Select Add variable.
  11. In the Key box, enter GITLAB_TOKEN.
  12. In the Value box, paste the token.
  13. Select the Mask variable checkbox.
  14. Select Add variable.

Configure semantic-release

semantic-release pulls its configuration information from a .releaserc.json file in the project. Create a .releaserc.json at the root of the repository:

{
  "branches": ["master"],
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/gitlab",
    "@semantic-release/npm",
    [
      "@semantic-release/git",
      {
        "assets": ["package.json"],
        "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
      }
    ]
  ]
}

Begin publishing releases

Test the pipeline by creating a commit with a message like:

fix: testing patch releases

Push the commit to the default branch. The pipeline should create a new release (v1.0.0) on the project’s Releases page and publish a new version of the package to the project’s Package Registry page.

To create a minor release, use a commit message like:

feat: testing minor releases

Or, for a breaking change:

feat: testing major releases

BREAKING CHANGE: This is a breaking change.

More information about how commit messages are mapped to releases can be found in semantic-releases’s documentation.

Use the module in a project

To use the published module, add an .npmrc file to the project that depends on the module. For example, to use the example project’s module:

@gitlab-examples:registry=https://gitlab.com/api/v4/packages/npm/

Then, install the module:

npm install --save @gitlab-examples/semantic-release-npm

Troubleshooting

Deleted Git tags reappear

A Git tag deleted from the repository can sometimes be recreated by semantic-release when GitLab runners use a cached version of the repository. If the job runs on a runner with a cached repository that still has the tag, semantic-release recreates the tag in the main repository.

To avoid this behavior, you can either: