1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
---
stage: Package
group: Package Registry
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Publish npm packages to the GitLab package registry using semantic-release
DETAILS:
**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](../../user/packages/npm_registry/index.md) by using [semantic-release](https://github.com/semantic-release/semantic-release).
You can also view or fork the complete [example source](https://gitlab.com/gitlab-examples/semantic-release-npm).
## Initialize the module
1. Open a terminal and go to the project's repository.
1. Run `npm init`. Name the module according to [the package registry's naming conventions](../../user/packages/npm_registry/index.md#naming-convention). For example, if the project's path is `gitlab-examples/semantic-release-npm`, name the module `@gitlab-examples/semantic-release-npm`.
1. Install the following npm packages:
```shell
npm install semantic-release @semantic-release/git @semantic-release/gitlab @semantic-release/npm --save-dev
```
1. Add the following properties to the module's `package.json`:
```json
{
"scripts": {
"semantic-release": "semantic-release"
},
"publishConfig": {
"access": "public"
},
"files": [ <path(s) to files here> ]
}
```
1. 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](https://docs.npmjs.com/cli/v6/configuring-npm/package-json/#files).
1. Add a `.gitignore` file to the project to avoid committing `node_modules`:
```plaintext
node_modules
```
## Configure the pipeline
Create a `.gitlab-ci.yml` with the following content:
```yaml
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:
<!-- markdownlint-disable MD044 -->
1. On the left sidebar, select your avatar.
1. Select **Preferences > Access tokens**.
1. In the **Token name** box, enter a token name.
1. Under **select scopes**, select the **api** checkbox.
1. Select **Create project access token**.
1. Copy the value.
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Settings > CI/CD**.
1. Expand **Variables**.
1. Select **Add variable**.
1. In the **Key** box, enter `GITLAB_TOKEN`.
1. In the **Value** box, paste the token.
1. Select the **Mask variable** checkbox.
1. Select **Add variable**.
<!-- markdownlint-enable MD044 -->
## 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:
```json
{
"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:
```plaintext
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:
```plaintext
feat: testing minor releases
```
Or, for a breaking change:
```plaintext
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](https://github.com/semantic-release/semantic-release#how-does-it-work).
## 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](https://gitlab.com/gitlab-examples/semantic-release-npm)'s module:
```plaintext
@gitlab-examples:registry=https://gitlab.com/api/v4/packages/npm/
```
Then, install the module:
```shell
npm install --save @gitlab-examples/semantic-release-npm
```
## Troubleshooting
### Deleted Git tags reappear
A [Git tag](../../user/project/repository/tags/index.md) 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:
- Configure the runner with [`GIT_STRATEGY: clone`](../runners/configure_runners.md#git-strategy).
- Include the [`git fetch --prune-tags` command](https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt---prune-tags)
in your CI/CD script.
|