GitLab Releaser
GitLab Releaser takes a JSON file with details for a release and generates a shell script to leverage GitLab's release-cli application to create the release.
Requirements
GitLab Releaser accepts a JSON file in one of two formats with release details:
- Release file, with a single release
- GitLab Releaser file, with multiple releases
Special handling is provided to pull some values from the project CHANGELOG and for environment variables.
Release File
GitLab Releaser can accept a Release file at .gitlab/release.json
with the details of an individual release, for example:
{
"name": "v1.0.0 (2020-10-28)",
"description": "Another release",
"tag_name": "1.0.0",
"assets": {
"links": [
{
"name": "npm",
"url": "https://www.npmjs.com/package/gitlab-releaser",
"type": "package"
}
]
},
"milestones": ["1.0.0"]
}
The full JSON schema is included here, which is based on the proposed schema that release-cli
may eventually accept.
GitLab Releaser File
GitLab Releaser can accept a GitLab Releaser file at .gitlab/gitlab-releaser.json
which can contain default values applicable to all releases and overrides for multiple specific releases denoted by release name, for example:
{
"defaults": {
"assets": {
"links": [
{
"name": "npm",
"url": "https://www.npmjs.com/package/gitlab-releaser",
"type": "package"
}
]
}
},
"releases": {
"1.0.0": {
"name": "v1.0.0 (2020-10-28)",
"description": "Another release",
"tag_name": "1.0.0",
"milestones": ["1.0.0"]
},
"0.5.0": {
"name": "v0.5.0 (2020-10-10)",
"description": "Initial release",
"tag_name": "0.5.0",
"milestones": ["0.5.0"]
}
}
}
The defaults
and each releases
properties can contain any release properties, and the releases
properties will override any defaults
.
A release name must be specified via the CLI to pull the appropriate release information. For example, --release 1.0.0
would result in the following equivalent release.json
file.
{
"name": "v1.0.0 (2020-10-28)",
"description": "Another release",
"tag_name": "1.0.0",
"assets": {
"links": [
{
"name": "npm",
"url": "https://www.npmjs.com/package/gitlab-releaser",
"type": "package"
}
]
},
"milestones": ["1.0.0"]
}
The full JSON schema is included here.
Pulling Data From Changelog
The release name
and description
can optionally be pulled dynamically from the CHANGELOG. This will be done if the value specified in the Release or GitLab Releaser file is "$$CHANGELOG
", e.g.
{
"name": "$$CHANGELOG",
"description": "$$CHANGELOG",
"tag_name": "1.0.0"
}
The releaselog
module is used to pull this data and has details on CHANGELOG formatting requirements. The data is retrieved by the tag specified via the CLI, if specified, otherwise the value of CI_COMMIT_TAG
is used. Either a release name or the default value must be specified via the CLI if the release uses CHANGELOG data.
If either name
or description
specifies pulling data from the CHANGELOG, but that data cannot be found in the CHANGELOG, the job will report the error and fail.
Environment Variables
By default, release parameters are assumed to be string literal values, and are quoted as such when the shell script is created. Any release properties can include environment variables, but they must be denoted in parameter substitution syntax, e.g. ${CI_COMMIT_TAG}
. Any parameters with variables in this format will be encoded in the generated shell script so that they are expanded. A value with a variable in any other format, e.g. $CI_COMMIT_TAG
, will be treated as a string literal.
For example, the following release.json
file using both notations:
{
"name": "v${CI_COMMIT_TAG} release",
"description": "Fixed handling of $CI_COMMIT_TAG"
}
will result in a command line arguments:
--name 'v'"${CI_COMMIT_TAG}"' release' --description 'Fixed handling of $CI_COMMIT_TAG'
Usage
Command Line Usage
The gitlab-releaser
command line interface is run as detailed below:
Usage: gitlab-releaser [options]
Options:
-V, --version output the version number
-s, --schema <schema> the schema type of the JSON input file (default: "gitlab-releaser")
-r, --release <release> the reference used to retrieve release data, required if schema type is
gitlab-releaser or if release pulls data from a CHANGELOG (default: "$CI_COMMIT_TAG")
-h, --help display help for command
GitLab CI Usage
The following is an example .gitlab-ci.yml
file illustrating preparing and creating a release on every tag pipeline.
stages:
- pre-release
- release
prepare_release:
image: node:lts-alpine
stage: pre-release
before_script:
- npm install -g gitlab-releaser
script:
- gitlab-releaser
rules:
- if: $CI_COMMIT_TAG
artifacts:
paths:
- '.gitlab/release.sh'
create_release:
image: registry.gitlab.com/gitlab-org/release-cli:latest
stage: release
needs:
- prepare_release
script:
- sh .gitlab/release.sh
rules:
- if: $CI_COMMIT_TAG
The process is split into two jobs to avoid having to create a container image that can run this Node.js application to prepare the release and has GitLab's release-cli application to create the release.
The prepare_release
job uses a Node.js container image and installs and runs gitlab-releaser
to generate the shell script to prepare the release, saved as .gitlab/release.sh
. For the example release.json
file above, or the gitlab-releaser.json
for release 1.0.0
, the following shell script will be generated:
#!/bin/sh
release-cli create --name 'v1.0.0 (2020-10-28)' --description 'Another release' --tag-name 1.0.0 --assets-link '{"name":"npm","url":"https://www.npmjs.com/package/gitlab-releaser","type":"package"}' --milestone 1.0.0
The create_release
job then runs the script to create the release using GitLab's release-cli container image (registry.gitlab.com/gitlab-org/release-cli
), which contains the release-cli
executable.
GitLab CI Usage Without Release Files
The example below shows how to setup a GitLab prepare_release
job template with a default release configuration defined in CI job (in the environment variable $RELEASE
, which contains the minified configuration from a gitlab-releaser.json
file), which will only be used if the project does not have a release file of either type (release.json
or gitlab-releaser.json
).
prepare_release:
image: node:lts-alpine
stage: pre-release
variables:
RELEASE: '{"defaults":{"name":"$$$$CHANGELOG","description":"$$$$CHANGELOG"}}'
before_script:
- npm install -g gitlab-releaser
- |
if [ ! -f .gitlab/release.json ] && [ ! -f .gitlab/gitlab-releaser.json ]; then
mkdir -p .gitlab && echo $RELEASE > .gitlab/gitlab-releaser.json
fi
script:
- gitlab-releaser
rules:
- if: $CI_COMMIT_TAG
artifacts:
paths:
- '.gitlab/release.sh'
The default release configuration can also be overridden by including this template, and simply overriding the $RELEASE
variable with the minified configuration from a gitlab-releaser.json
file.
include:
- local: 'gitlab-releaser.gitlab-ci.yml'
prepare_release:
variables:
RELEASE: '{"defaults":{"name":"${CI_COMMIT_TAG}","description":"$$$$CHANGELOG"}}'