summaryrefslogtreecommitdiff
path: root/doc/ci/examples/semantic-release.md
blob: 1fa526e787aa3ee0d3f0958a554bd0d2495269c7 (plain)
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
---
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)**

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 npm's 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 top bar, on the top right, select your avatar.
1. On the left sidebar, select **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 top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, 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
```