Skip to content
Snippets Groups Projects
README.md 8.9 KiB
Newer Older
Pierre Smeyers's avatar
Pierre Smeyers committed
# GitLab CI template for semantic-release

This project implements a generic GitLab CI template for [semantic-release](https://github.com/semantic-release/semantic-release).

It provides several features, usable in different modes (by configuration).

This template makes use of [semantic-release](https://semantic-release.gitbook.io/) to **automate your release process** 
from your pipeline, supporting one or several of the following features:

* determine the next release version number,
* generate the changelog,
* commit any changed resource to the Git repository,
* create and push the Git tag,
* publish the packages (in [GitLab](https://docs.gitlab.com/ee/user/project/releases/index.html) or any other package repository of your choice),
* any additional custom behavior you are able to script, triggered on the [release steps](https://semantic-release.gitbook.io/semantic-release/#release-steps).

Pierre Smeyers's avatar
Pierre Smeyers committed
## Usage

In order to include this template in your project, add the following to your `gitlab-ci.yml`:

```yaml
include:
Pierre Smeyers's avatar
Pierre Smeyers committed
  - project: 'to-be-continuous/semantic-release'
    ref: '3.0.0'
Pierre Smeyers's avatar
Pierre Smeyers committed
    file: '/templates/gitlab-ci-semrel.yml'
```

## Global configuration

The semantic-release template uses some global configuration used throughout all jobs.

| Name                  | description                                   | default value     |
| --------------------- | --------------------------------------------- | ----------------- |
| `SEMREL_IMAGE`        | The Docker image used to run semantic-release | `node:lts` |
| :lock: `GITLAB_TOKEN` | A GitLab [project access token](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html) or [personal access token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html) with `api`, `read_repository` and `write repository` scopes. :warning: This variable is **mandatory** and [defined by `semantic-release`](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/ci-configuration.md#push-access-to-the-remote-repository) itself. | _none_ |
| `SEMREL_CONFIG_DIR`        |  directory containing your [semantic-release configuration](https://semantic-release.gitbook.io/semantic-release/usage/configuration#configuration-file) | `.` |
| `SEMREL_REQUIRED_PLUGINS_FILE`        | An optional file for additional npm packages to install | `semrel-required-plugins.txt` |

Jobs will extract required plugin packages from discovered configuration. If your configuration needs additional packages, add them, one per line, to `SEMREL_REQUIRED_PLUGINS_FILE` file. Each line must be a valid `npm install` package argument.
Pierre Smeyers's avatar
Pierre Smeyers committed

## Jobs

### `semantic-release` job

This job runs `semantic-release` in `ci` mode.

:warning: This template supports all [semantic-release configuration files](https://semantic-release.gitbook.io/semantic-release/usage/configuration#configuration-file) __except for__ `release.config.js` and custom CLI arguments.

If no configuration is found, the template will generate one with the following options:

* `debug`: `true` if the `$TRACE` variable is set, `false` otherwise
* `dryRun`: `true` if the `$SEMREL_DRY_RUN` variable is set, `false` otherwise
* `tagFormat`: see `$SEMREL_TAG_FORMAT` variable
* `plugins`:
    * [@semantic-release/commit-analyzer](https://github.com/semantic-release/commit-analyzer)
    * [@semantic-release/release-notes-generator](https://github.com/semantic-release/release-notes-generator)
    * [@semantic-release/gitlab](https://github.com/semantic-release/gitlab)
    * [@semantic-release/git](https://github.com/semantic-release/git)
    * optional [@semantic-release/changelog](https://github.com/semantic-release/changelog) if `SEMREL_CHANGELOG_ENABLED` is set to `true`
    * optional [@semantic-release/exec](https://github.com/semantic-release/exec) if any hook script is found (see [hook scripts](#hook_scripts))
Pierre Smeyers's avatar
Pierre Smeyers committed
* `branches`: `master`

#### Variables

As specified in the previous chapter, these variables are only used to generated a `.releaserc` when no configuration is found in the repository.

| Name                          | description                                            | default value |
| ------------------------------| ------------------------------------------------------ | ------------- |
| `SEMREL_CHANGELOG_ENABLED`    | Add the [@semantic-release/changelog](https://github.com/semantic-release/changelog) plugin which will commit a changelog file in the repository if set to `true`. | _none_ |
Pierre Smeyers's avatar
Pierre Smeyers committed
| `SEMREL_CHANGELOG_FILE`    | [changelogFile @semantic-release/changelog option](https://github.com/semantic-release/changelog#options). | _none_ (use the plugin default value which is `CHANGELOG.md`). |
| `SEMREL_CHANGELOG_TITLE`   | [changelogTitle @semantic-release/changelog option](https://github.com/semantic-release/changelog#options). You might want to use markdown format (for example `# MyApp Changelog`). | _none_ |
| `SEMREL_DRY_RUN`              | Activate the [dryRun semantic-release option](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#dryrun) if present. | _none_ |
| `SEMREL_AUTO_RELEASE_ENABLED` | When set to `true` the job start automatically. When not set (default), the job is manual. | _none_ |
Pierre Smeyers's avatar
Pierre Smeyers committed
| `SEMREL_TAG_FORMAT`           | [tagFormat semantic-release option](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#tagformat). :warning: don't forget to double the `$` character so it is not interpreted by GitLab.                   | `$${version}` |
| `SEMREL_HOOKS_DIR`             | [Hook scripts](#hook_scripts) folder. | `.` |
| `SEMREL_RELEASE_DISABLED`      | Disable this job. | _none_ |

#### Hook scripts

The generated `.releaserc` will include the [@semantic-release/exec](https://github.com/semantic-release/exec) plugin if any of the following scripts is found in the `$SEMREL_HOOKS_DIR` folder:

##### verify-conditions.sh

See [exec verifyConditionsCmd](https://github.com/semantic-release/exec#verifyconditionscmd).

Parameters: _none_

##### verify-release.sh

See [exec verifyReleaseCmd](https://github.com/semantic-release/exec#verifyreleasecmd).

Parameters:

1. Last release version
2. next release version
3. next release type

##### prepare.sh

See [exec prepareCmd](https://github.com/semantic-release/exec#preparecmd).

Parameters:

1. Last release version
2. next release version
3. next release type

##### publish.sh

See [exec publishCmd](https://github.com/semantic-release/exec#publishcmd).

Parameters:

1. Last release version
2. next release version
3. release branch
4. commits count
5. current date

##### success.sh

See [exec successCmd](https://github.com/semantic-release/exec#successcmd).

Parameters:

1. Last release version
2. next release version

##### fail.sh

See [exec failcmd](https://github.com/semantic-release/exec#failcmd).

Parameters:

1. Last release version
2. next release version

### `semantic-release-info` job

This job (disabled by default) runs `semantic-release` with `dry-run` mode in `.pre` stage to save the following variables as [dotenv artifact](https://docs.gitlab.com/ee/ci/pipelines/job_artifacts.html#artifactsreportsdotenv) making them available for the next pipeline stages:

* `SEMREL_INFO_LAST_VERSION`: latest released version
* `SEMREL_INFO_NEXT_VERSION`: next release version (based on actual commits and comments)
* `SEMREL_INFO_NEXT_VERSION_TYPE`: next release type (`major`|`minor`|`patch`)

:warning: `SEMREL_INFO_NEXT_VERSION` and `SEMREL_INFO_NEXT_VERSION_TYPE` **wont** be available when semantic-release commits analysis determine that no release will be performed.

This job can be enabled by defining the `SEMREL_INFO_ON` variable:

* `prod` to enable on production branch only (`master` by default)
* `protected` to enable on protected references
* `all` to enable on all Git references. :warning: Beware that this job requires the `GITLAB_TOKEN` variable so you must unprotect it (this will make privilege escalation possible from developer to maintainer).

## Secrets management

Here are some advices about your **secrets** (variables marked with a :lock:):

1. Manage them as [project or group CI/CD variables](https://docs.gitlab.com/ee/ci/variables/#create-a-custom-variable-in-the-ui):
    * [**masked**](https://docs.gitlab.com/ee/ci/variables/#mask-a-custom-variable) to prevent them from being inadvertently
      displayed in your job logs,
    * [**protected**](https://docs.gitlab.com/ee/ci/variables/#protect-a-custom-variable) if you want to secure some secrets
      you don't want everyone in the project to have access to (for instance production secrets).
2. In case a secret contains [characters that prevent it from being masked](https://docs.gitlab.com/ee/ci/variables/#masked-variable-requirements),
  simply define its value as the [Base64](https://en.wikipedia.org/wiki/Base64) encoded value prefixed with `@b64@`:
  it will then be possible to mask it and the template will automatically decode it prior to using it.
3. Don't forget to escape special characters (ex: `$` -> `$$`).