gitlab-release

Performs a release of a git project hosted in GitLab

Usage no npm install needed!

<script type="module">
  import gitlabRelease from 'https://cdn.skypack.dev/gitlab-release';
</script>

README

gitlab-release NPM version NPM downloads NPM license

Performs a release of a git project hosted in GitLab

Installation

$ npm install -g gitlab-release          # For the binary
$ npm install --save-dev gitlab-release  # For the library

Usage

Make sure you have the GITLAB_API_TOKEN exported in your environment so that the module can access your GitLab API.

As a Binary

gitlab-release [major|minor|patch] --pre-command <cmd> --post-command <cmd> --file-path <path> --patterns <globs>

This will:

  • Fire up ${EDITOR} to enter a MarkDown release description
  • Run the pre-command if specified
  • Add the patterns
  • Bump the version in the file-path JSON file
  • Tag the project
  • Remove the patterns
  • Create a GitLab release note

For example, releasing polymer projects can be done as so:

gitlab-release [major|minor|patch] --pre-command 'polymer build' --file-path bower.json --patterns 'build/**/*,build/**/.*'

Rather than specifying the commands each time, it is possible to specify a .grrc file to define the optional arguments for a project. The above command is equivalent to the following .grrc file:

{
  "filePath": "bower.json",
  "preCommand": ["polymer", "build"],
  "patterns": ["build/**/*", "build/**/.*"]
}

As a Library

For npm Projects

There are two functions preversion and postversion that provide the following:

  • preversion:
    • Retrieve all issues that have been closed since the last version
    • Retrieve all the resolved merge requests since the last version
    • Ask the user with their editor to describe the release. A list of the issues and MRs are added for convienience
    • Update the changelog using the issues and merge requests
  • postversion:
    • Create a GitLab release note that is attached to the npm created version tag

Here is an example for integrating these scripts with gulp:

import process from 'process';
import * as release from 'gitlab-release';

const releaseDataJson = '.release-data.json';

gulp.task('preversion', () => {
  const argv = JSON.parse(process.env.npm_config_argv);
  const type = argv.remain[0];
  return release.preversion({type})
    .then(data => release.writeJson(releaseDataJson, data));
});

gulp.task('postversion', () => {
  return release.readJson(releaseDataJson)
    .then(data => release.postversion({notes: data.description}))
    .then(() => release.unlink(releaseDataJson));
});

Those gulp tasks can be ran by npm by adding the following scripts to package.json:

{
  "scripts": {
    "preversion": "gulp preversion",
    "postversion": "gulp postversion"
  }
}

Then just use your normal npm version and npm publish workflow to create versions of your npm module with changelog history and version release notes:

$ npm version patch
$ npm publish

Ideally the publish should be done when a tag gets pushed to the repository on the GitLab CI. Make sure your runner has permissions to publish your package with npm owner add <gitlab-runner-npm-account>, then use the following task in .gitlab-ci.yml:

Publish:
  only:
    - tags
  cache:
    paths:
      - node_modules/
  script:
    - npm install
    - npm test
    - npm publish

For other package managers

Some JavaScript package managers (notably bower) require that the dist folder is present in the git repository. This is due to the package manager using the git repository as the backend for the package manager. The dist script in the gitlab-release module provides an easy way to release a project for one of these package managers. It adds the dist folder as part of the version tag and then removes it for continued development. The following steps are performed:

  • retrieves release data from GitLab for the release such as issues closed and resolved merge requests
  • asks the user for the release description
  • adds the ignored dist folder
  • bumps the package version
  • updates the changelog using the release description and the GitLab data
  • commits the changed files
  • creates a version tag for the project
  • removes the dist folder
  • pushes the commits and tag
  • creates GitLab release notes to accompany the new git tag

To integrate the script into gulp:

import yargs from 'yargs';
import * as release from 'gitlab-release';

// Release task
gulp.task('release', ['build'], (done) => {
  const args = yargs
    .usage('Usage: gulp release [options]')
    .option('type', {choices: ['major', 'minor', 'patch'], describe: 'The type of release', demand: true})
    .option('description', {type: 'string', describe: 'The markdown description of the release'})
    .option('token', {type: 'string', describe: 'The GitLab API token', default: process.env.GITLAB_API_TOKEN})
    .argv;

  if (typeof(args.description) === 'string') {
    args.description = args.description.trimRight();
    if (!args.description) {
      throw new Error('Must provide a non-empty release description');
    }
  }

  if (!args.token) {
    throw new Error('Must provide a GitLab API token. Provide either --token or GITLAB_API_TOKEN');
  }

  release.dist({type: args.type, notes: args.description, token: args.token})
    .then((version) => {
      $.util.log(`Successfully released ${version}`);
      done();
    })
    .catch(done);
});

Then to do a release just run gulp release. You will want to ignore the dist folder in your .gitignore.

Custom Release Script

If the above two prepackaged scripts don't do what you need then you can roll your own release script! This module provides all the necessary promised based APIs that you should need to create a fully fledged release script. Check out the source code for the dist, preversion and postversion functions to see how the various APIs are pulled together.

License

MIT © VCA Technology