Skip to content

Commit

Permalink
feat: set name/email of commit author and committer via Git env var
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the `GIT_USERNAME` and `GIT_EMAIL` environment variables are replaced by the [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing) `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_NAME` and `GIT_COMMITTER_EMAIL`.

Co-authored-by: Sergey Bekrin <sergey@bekrin.me>
  • Loading branch information
2 people authored and gr2m committed May 8, 2018
1 parent 8fcb054 commit a58c357
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 65 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ Create a release commit, including configurable files.

## Configuration

### Environment variables

| Variable | Description | Default |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| `GIT_USERNAME` | [Git username](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup#_your_identity) associated with the release commit. | @semantic-release-bot. |
| `GIT_EMAIL` | [Git email address](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup#_your_identity) associated with the release commit. | @semantic-release-bot email address. |
## Environment variables

| Variable | Description | Default |
|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|
| `GIT_AUTHOR_NAME` | The author name associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
| `GIT_AUTHOR_EMAIL` | The author email associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot email address. |
| `GIT_COMMITTER_NAME` | The committer name associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
| `GIT_COMMITTER_EMAIL` | The committer email associated with the release commit. See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot email address. |

### Options

Expand Down
12 changes: 1 addition & 11 deletions lib/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ async function add(files) {
debug('add file to git index', shell);
}

/**
* Set Git configuration.
*
* @param {String} name Config name.
* @param {String} value Config value.
*/
async function config(name, value) {
await execa('git', ['config', name, value]);
}

/**
* Commit to the local repository.
*
Expand Down Expand Up @@ -62,4 +52,4 @@ async function gitHead() {
return execa.stdout('git', ['rev-parse', 'HEAD']);
}

module.exports = {getModifiedFiles, add, config, gitHead, commit, push};
module.exports = {getModifiedFiles, add, gitHead, commit, push};
8 changes: 2 additions & 6 deletions lib/prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const dirGlob = require('dir-glob');
const pReduce = require('p-reduce');
const debug = require('debug')('semantic-release:git');
const resolveConfig = require('./resolve-config');
const {getModifiedFiles, add, config, commit, push} = require('./git');
const {getModifiedFiles, add, commit, push} = require('./git');

const CHANGELOG = 'CHANGELOG.md';
const PKG_JSON = 'package.json';
Expand All @@ -18,16 +18,14 @@ const SKW_JSON = 'npm-shrinkwrap.json';
* @param {Object} pluginConfig The plugin configuration.
* @param {String|Array<String>} [pluginConfig.assets] Files to include in the release commit. Can be files path or globs.
* @param {String} [pluginConfig.message] The message for the release commit.
* @param {String} [pluginConfig.gitUserName] The username to use for commiting (git `user.name` config).
* @param {String} [pluginConfig.gitUserEmail] The email to use for commiting (git `user.email` config).
* @param {Object} context semantic-release context.
* @param {Object} context.options `semantic-release` configuration.
* @param {Object} context.lastRelease The last release.
* @param {Object} context.nextRelease The next release.
* @param {Object} logger Global logger.
*/
module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, lastRelease, nextRelease, logger}) => {
const {gitUserEmail, gitUserName, message, assets} = resolveConfig(pluginConfig);
const {message, assets} = resolveConfig(pluginConfig, logger);
const patterns = [];
const modifiedFiles = await getModifiedFiles();

Expand Down Expand Up @@ -76,8 +74,6 @@ module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, lastRel
if (filesToCommit.length > 0) {
logger.log('Found %d file(s) to commit', filesToCommit.length);
await add(filesToCommit);
await config('user.email', gitUserEmail);
await config('user.name', gitUserName);
debug('commited files: %o', filesToCommit);
await commit(
message
Expand Down
7 changes: 1 addition & 6 deletions lib/resolve-config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
const {castArray} = require('lodash');

module.exports = ({message, assets}) => ({
gitUserName: process.env.GIT_USERNAME || 'semantic-release-bot',
gitUserEmail: process.env.GIT_EMAIL || 'semantic-release-bot@martynus.net',
message,
assets: assets ? castArray(assets) : assets,
});
module.exports = ({message, assets}) => ({message, assets: assets ? castArray(assets) : assets});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"all": true
},
"peerDependencies": {
"semantic-release": ">=15.0.0 <16.0.0"
"semantic-release": ">=15.4.0 <16.0.0"
},
"prettier": {
"printWidth": 120,
Expand Down
13 changes: 2 additions & 11 deletions test/git.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava';
import {outputFile, appendFile} from 'fs-extra';
import {add, getModifiedFiles, config, commit, gitHead, push} from '../lib/git';
import {gitRepo, gitCommits, gitGetCommits, gitGetConfig, gitStaged, gitRemoteHead} from './helpers/git-utils';
import {add, getModifiedFiles, commit, gitHead, push} from '../lib/git';
import {gitRepo, gitCommits, gitGetCommits, gitStaged, gitRemoteHead} from './helpers/git-utils';

// Save the current working diretory
const cwd = process.cwd();
Expand Down Expand Up @@ -50,15 +50,6 @@ test.serial('Returns [] if there is no modified files', async t => {
await t.deepEqual(await getModifiedFiles(), []);
});

test.serial('Set git config', async t => {
// Create a git repository, set the current working directory at the root of the repo
await gitRepo();
// Add config
await config('user.name', 'username');

await t.is(await gitGetConfig('user.name'), 'username');
});

test.serial('Commit added files', async t => {
// Create a git repository, set the current working directory at the root of the repo
await gitRepo();
Expand Down
11 changes: 0 additions & 11 deletions test/helpers/git-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,6 @@ export async function gitShallowClone(origin, branch = 'master', depth = 1) {
return dir;
}

/**
* Get Git configuration.
*
* @param {String} name Config name.
*
* @returns {String} The config's value.
*/
export async function gitGetConfig(name) {
return execa.stdout('git', ['config', '--get', name]);
}

/**
* @return {Array<String>} Array of staged files path.
*/
Expand Down
10 changes: 4 additions & 6 deletions test/integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ test.beforeEach(t => {
delete process.env.GH_TOKEN;
delete process.env.GITHUB_TOKEN;
delete process.env.GIT_CREDENTIALS;
delete process.env.GIT_EMAIL;
delete process.env.GIT_USERNAME;
delete process.env.GIT_AUTHOR_NAME;
delete process.env.GIT_AUTHOR_EMAIL;
delete process.env.GIT_COMMITTER_NAME;
delete process.env.GIT_COMMITTER_EMAIL;
// Clear npm cache to refresh the module state
clearModule('..');
t.context.m = require('..');
Expand All @@ -41,8 +43,6 @@ test.afterEach.always(() => {
});

test.serial('Prepare from a shallow clone', async t => {
process.env.GIT_EMAIL = 'user@email.com';
process.env.GIT_USERNAME = 'user';
const branch = 'master';
const repositoryUrl = await gitRepo(true);
await outputFile('package.json', "{name: 'test-package', version: '1.0.0'}");
Expand All @@ -69,8 +69,6 @@ test.serial('Prepare from a shallow clone', async t => {
t.is(commit.subject, `Release version ${nextRelease.version} from branch ${branch}`);
t.is(commit.body, `${nextRelease.notes}\n`);
t.is(commit.gitTags, `(HEAD -> ${branch})`);
t.is(commit.author.name, process.env.GIT_USERNAME);
t.is(commit.author.email, process.env.GIT_EMAIL);
});

test.serial('Prepare from a detached head repository', async t => {
Expand Down
30 changes: 25 additions & 5 deletions test/prepare.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ test.beforeEach(async t => {
delete process.env.GH_TOKEN;
delete process.env.GITHUB_TOKEN;
delete process.env.GIT_CREDENTIALS;
delete process.env.GIT_EMAIL;
delete process.env.GIT_USERNAME;
delete process.env.GIT_AUTHOR_NAME;
delete process.env.GIT_AUTHOR_EMAIL;
delete process.env.GIT_COMMITTER_NAME;
delete process.env.GIT_COMMITTER_EMAIL;
// Stub the logger functions
t.context.log = stub();
t.context.logger = {log: t.context.log};
Expand Down Expand Up @@ -51,9 +53,6 @@ test.serial(
t.is(commit.body, `${nextRelease.notes}\n`);
t.is(commit.gitTags, `(HEAD -> ${t.context.branch})`);

t.is(commit.author.name, 'semantic-release-bot');
t.is(commit.author.email, 'semantic-release-bot@martynus.net');

t.deepEqual(t.context.log.args[0], ['Add %s to the release commit', 'CHANGELOG.md']);
t.deepEqual(t.context.log.args[1], ['Add %s to the release commit', 'package.json']);
t.deepEqual(t.context.log.args[2], ['Add %s to the release commit', 'package-lock.json']);
Expand Down Expand Up @@ -191,6 +190,27 @@ test.serial('Commit files matching the patterns in "assets", including dot files
t.deepEqual(t.context.log.args[0], ['Found %d file(s) to commit', 1]);
});

test.serial('Set the commit author and committer name/email based on environment variables', async t => {
process.env.GIT_AUTHOR_NAME = 'author name';
process.env.GIT_AUTHOR_EMAIL = 'author email';
process.env.GIT_COMMITTER_NAME = 'committer name';
process.env.GIT_COMMITTER_EMAIL = 'committer email';
const lastRelease = {version: 'v1.0.0'};
const nextRelease = {version: '2.0.0', gitTag: 'v2.0.0', notes: 'Test release note'};
await outputFile('CHANGELOG.md', 'Initial CHANGELOG');

await prepare({}, {options: t.context.options, lastRelease, nextRelease, logger: t.context.logger});

// Verify the files that have been commited
t.deepEqual(await gitCommitedFiles(), ['CHANGELOG.md']);
// Verify the commit message contains on the new release notes
const [commit] = await gitGetCommits();
t.is(commit.author.name, 'author name');
t.is(commit.author.email, 'author email');
t.is(commit.committer.name, 'committer name');
t.is(commit.committer.email, 'committer email');
});

test.serial('Skip negated pattern if its alone in its group', async t => {
const pluginConfig = {assets: ['!**/*', 'file.js']};
const lastRelease = {};
Expand Down
6 changes: 4 additions & 2 deletions test/verify.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ test.beforeEach(t => {
delete process.env.GH_TOKEN;
delete process.env.git_TOKEN;
delete process.env.GIT_CREDENTIALS;
delete process.env.GIT_EMAIL;
delete process.env.GIT_USERNAME;
delete process.env.GIT_AUTHOR_NAME;
delete process.env.GIT_AUTHOR_EMAIL;
delete process.env.GIT_COMMITTER_NAME;
delete process.env.GIT_COMMITTER_EMAIL;
// Stub the logger functions
t.context.log = stub();
t.context.logger = {log: t.context.log};
Expand Down

0 comments on commit a58c357

Please sign in to comment.