Skip to content

Commit

Permalink
Add support for required branch(es)
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Feb 20, 2020
1 parent 2d07da3 commit a791799
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 2 deletions.
1 change: 1 addition & 0 deletions conf/release-it.json
Expand Up @@ -3,6 +3,7 @@
"git": {
"changelog": "git log --pretty=format:\"* %s (%h)\" ${latestTag}...HEAD",
"requireCleanWorkingDir": true,
"requireBranch": false,
"requireUpstream": true,
"requireCommits": false,
"addUntrackedFiles": false,
Expand Down
14 changes: 14 additions & 0 deletions docs/prerequisites.md
Expand Up @@ -5,6 +5,20 @@ ways you can change release-it's behavior.

## Git

### Required branch

By default this is disabled, but release-it can exit the process when the current branch is not as configured:

```json
{
"git": {
"requireBranch": "master"
}
}
```

Use an array to allow releases from more branch names.

### Clean working directory

The working directory should be clean (i.e. `git status` should say something like this:
Expand Down
7 changes: 7 additions & 0 deletions lib/errors.js
Expand Up @@ -31,6 +31,12 @@ class GitRemoteUrlError extends ReleaseItError {
}
}

class GitRequiredBranchError extends ReleaseItError {
constructor(requiredBranches) {
super(`Must be on branch ${requiredBranches}`);
}
}

class GitCleanWorkingDirError extends ReleaseItError {
constructor() {
super(
Expand Down Expand Up @@ -98,6 +104,7 @@ module.exports = {
InvalidVersionError,
InvalidConfigurationError,
GitRemoteUrlError,
GitRequiredBranchError,
GitCleanWorkingDirError,
GitUpstreamError,
GitNoCommitsError,
Expand Down
17 changes: 16 additions & 1 deletion lib/plugin/git/Git.js
Expand Up @@ -3,7 +3,13 @@ const findUp = require('find-up');
const { quote } = require('shell-quote');
const { format } = require('../../util');
const GitBase = require('../GitBase');
const { GitCleanWorkingDirError, GitUpstreamError, GitNoCommitsError, GitCommitError } = require('../../errors');
const {
GitRequiredBranchError,
GitCleanWorkingDirError,
GitUpstreamError,
GitNoCommitsError,
GitCommitError
} = require('../../errors');
const prompts = require('./prompts');

const noop = Promise.resolve();
Expand All @@ -21,6 +27,9 @@ class Git extends GitBase {
}

async init() {
if (this.options.requireBranch && !(await this.isRequiredBranch(this.options.requireBranch))) {
throw new GitRequiredBranchError(this.options.requireBranch);
}
if (this.options.requireCleanWorkingDir && !(await this.isWorkingDirClean())) {
throw new GitCleanWorkingDirError();
}
Expand Down Expand Up @@ -53,6 +62,12 @@ class Git extends GitBase {
await this.step({ enabled: push, task: () => this.push(), label: 'Git push', prompt: 'push' });
}

async isRequiredBranch() {
const branch = await this.getBranchName();
const requiredBranches = _.castArray(this.options.requireBranch);
return requiredBranches.includes(branch);
}

hasUpstreamBranch() {
return this.exec('git symbolic-ref HEAD', { options })
.then(refs => this.exec(`git for-each-ref --format="%(upstream:short)" ${refs}`, { options }).then(Boolean))
Expand Down
16 changes: 15 additions & 1 deletion test/git.init.js
Expand Up @@ -4,7 +4,13 @@ const Shell = require('../lib/shell');
const Log = require('../lib/log');
const Git = require('../lib/plugin/git/Git');
const { git } = require('../conf/release-it.json');
const { GitRemoteUrlError, GitCleanWorkingDirError, GitUpstreamError, GitNoCommitsError } = require('../lib/errors');
const {
GitRequiredBranchError,
GitRemoteUrlError,
GitCleanWorkingDirError,
GitUpstreamError,
GitNoCommitsError
} = require('../lib/errors');
const { factory } = require('./util');
const { mkTmpDir, gitAdd } = require('./util/helpers');

Expand All @@ -20,6 +26,14 @@ test.serial.beforeEach(t => {
t.context = { gitClient, bare, target };
});

test.serial('should throw if on wrong branch', async t => {
const options = { git: { requireBranch: 'dev' } };
const gitClient = factory(Git, { options });
sh.exec('git remote remove origin');
const expected = { instanceOf: GitRequiredBranchError, message: /Must be on branch dev/ };
await t.throwsAsync(gitClient.init(), expected);
});

test.serial('should throw if there is no remote Git url', async t => {
const { gitClient } = t.context;
sh.exec('git remote remove origin');
Expand Down

0 comments on commit a791799

Please sign in to comment.