GitLab Releaser
GitLab Releaser takes a JSON file with release details, including defaults and
release specific overrides, and generates a JSON file for a particular release
that can be passed to GitLab's
release-cli application to create
the release. Special handling is provided to pull some values from the project
CHANGELOG and for environment variables.
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 (defaults
) and overrides for multiple specific releases denoted
by release name (releases
), 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 override any defaults
for that
release. The resulting file is saved as .gitlab/release.json
.
The complete list of release properties is shown below (all are optional
except where otherwise noted):
name
: Name of the release.description
: Description of the release.tag_name
: The tag to associate the release with.released_at
: The time of release.ref
: The commit ref to associate the release with.milestones
: An array of milestone names to associate the release with (for
example ['v1.0.0', 'v2.0.0']
).assets
: An object with the following properties:
links
(required if assets
is specified): An array of asset links with
the following properties:
name
(required): The displayed name of the link.url
(required): The URL of the link.type
: The type of link, one of:
package
: A link to a package.image
: A link to an image.archive
: A link to an archive.other
: A link to another type of asset (default).
direct_asset_path
: The path to the asset file.
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
.gitlab/release.json
file. Note some property have slightly different names
to match the release-cli
file schema (for example tag-name
, assets-link
).
The release property names in the preceding section have been found to be more
intuitive, even though different.
{
"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\"}"
],
"milestones": ["1.0.0"]
}
The full GitLab Releaser file JSON schema is available
here.
An example release-cli
file with all properties is available
here.
Note that although release-cli
accept a YAML file, GitLab Releaser generates
the equivalent JSON file (YAML being a superset of JSON, so a JSON file is
valid YAML).
Pulling data from changelog
The release name
and description
can optionally be pulled dynamically from
the CHANGELOG. This is done if the value specified in the Release or GitLab
Releaser file is "$$CHANGELOG
," for example:
{
"name": "$$CHANGELOG",
"description": "$$CHANGELOG",
"tag_name": "1.0.0"
}
The releaselog
package is used to
locate the CHANGELOG file, and by default looks in the current working
directory and has logic to locate the CHANGELOG or determine which to use if
multiple are found. A different CHANGELOG directory, or a specific file path,
can alternatively be specified via the CLI. The
releaselog
package is also used
to pull data from the CHANGELOG 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 and
either the CHANGELOG can't be found or the release data can't be found in the
CHANGELOG the job reports the error and fail.
Also, if the description
retrieved from the CHANGELOG is empty the job
reports the error and fail. This is almost always a CHANGELOG formatting or
content issue, but there is a CLI option to allow an empty description if
required (--allow-empty-changelog-desc
).
Environment variables
GitLab Releaser tries to expand any environment variables in release properties
that match either the format ${VARIABLE}
or $VARIABLE
. If the given
variable has a value it is expanded, for example if the tag_name
property is
set to v${CI_COMMIT_TAG}
, and the CI_COMMIT_TAG
environment variable has
the value 1.0.0
, the resulting property is v1.0.0
. Variables are expanded
before CHANGELOG data is pulled, so variables in the CHANGELOG are not
expanded.
If the variable doesn't have a value, the job reports the error and fails.
There is a CLI option to allow empty variables if desired
(--allow-empty-variables
), and in this case the variables aren't expanded.
Usage
Command line usage
The gitlab-releaser
command line interface is detailed below:
Usage: gitlab-releaser [options]
Options:
-V, --version output the version number
-r, --release <release> the reference used to retrieve release data
(default: "$CI_COMMIT_TAG")
-c, --changelog <changelog> the path to the CHANGELOG to check if the
release pulls data from the CHANGELOG
(default: ".")
-a, --allow-empty-changelog-desc allow an empty description when pulled from
the CHANGELOG (default: false)
-v, --allow-empty-variables allow environment variables that are empty
and are not expanded (default: false)
-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.
prepare_release:
image: node:lts-alpine
needs: []
before_script:
- npm install -g gitlab-releaser
script:
- gitlab-releaser
rules:
- if: $CI_COMMIT_TAG
artifacts:
paths:
- '.gitlab/release.json'
create_release:
image: registry.gitlab.com/gitlab-org/release-cli:latest
needs:
- prepare_release
script:
- release-cli create-from-file -file .gitlab/release.json
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 JSON file for the release, saved as
.gitlab/release.json
. The create_release
job then uses GitLab's
release-cli
container image (registry.gitlab.com/gitlab-org/release-cli
)
to run release-cli
, pulling values from the file .gitlab/release.json
.
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 is only used if the project doesn't have
it's own gitlab-releaser.json
file.
prepare_release:
image: node:lts-alpine
needs: []
variables:
RELEASE:
value: '{"defaults":{"name":"$$CHANGELOG","description":"$$CHANGELOG"}}'
expand: false
before_script:
- npm install -g gitlab-releaser
- |
if [ ! -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.json'
The default release configuration can then 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:
value: '{"defaults":{"name":"${CI_COMMIT_TAG}","description":"$$CHANGELOG"}}'
expand: false