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
|
---
stage: Package
group: Package Registry
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Publish npm packages to the GitLab Package Registry using semantic-release **(FREE ALL)**
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 navigate 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.
|