diff --git a/README.md b/README.md index b3f62c21..6410a885 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/lib/git.js b/lib/git.js index ccb41ea2..925b6dcf 100644 --- a/lib/git.js +++ b/lib/git.js @@ -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. * @@ -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}; diff --git a/lib/prepare.js b/lib/prepare.js index 684f90c6..2500238b 100644 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -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'; @@ -18,8 +18,6 @@ const SKW_JSON = 'npm-shrinkwrap.json'; * @param {Object} pluginConfig The plugin configuration. * @param {String|Array} [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. @@ -27,7 +25,7 @@ const SKW_JSON = 'npm-shrinkwrap.json'; * @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(); @@ -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 diff --git a/lib/resolve-config.js b/lib/resolve-config.js index 547bcd75..b2bc66b7 100644 --- a/lib/resolve-config.js +++ b/lib/resolve-config.js @@ -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}); diff --git a/package.json b/package.json index 654c2c52..e3a6b4c4 100644 --- a/package.json +++ b/package.json @@ -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, diff --git a/test/git.test.js b/test/git.test.js index 8a3e8eb6..78ee4a70 100644 --- a/test/git.test.js +++ b/test/git.test.js @@ -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(); @@ -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(); diff --git a/test/helpers/git-utils.js b/test/helpers/git-utils.js index ef46345d..db75886c 100644 --- a/test/helpers/git-utils.js +++ b/test/helpers/git-utils.js @@ -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} Array of staged files path. */ diff --git a/test/integration.test.js b/test/integration.test.js index cbb6b8b6..77b0cb28 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -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('..'); @@ -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'}"); @@ -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 => { diff --git a/test/prepare.test.js b/test/prepare.test.js index 03c4ec64..99a21acb 100644 --- a/test/prepare.test.js +++ b/test/prepare.test.js @@ -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}; @@ -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']); @@ -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 = {}; diff --git a/test/verify.test.js b/test/verify.test.js index 31e0837a..02cb4c46 100644 --- a/test/verify.test.js +++ b/test/verify.test.js @@ -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};