feat: Make semantic-release language agnostic
- Do not rely on `package.json` anymore - Use `cosmiconfig` to load the configation. `semantic-release` can be configured: - via CLI options (including plugin names but not plugin options) - in the `release` property of `package.json` (as before) - in a `.releaserc.yml` or `.releaserc.js` or `.releaserc.js` or `release.config.js` file - in a `.releaserc` file containing `json`, `yaml` or `javascript` module - Add the `repositoryUrl` options (used across `semantic-release` and plugins). The value is determined from CLi option, or option configuration, or package.json or the git remote url - Verifies that `semantic-release` runs from a git repository - `pkg` and `env` are not passed to plugin anymore - `semantic-release` can be run both locally and globally. If ran globally with non default plugins, the plugins can be installed both globally or locally. BREAKING CHANGE: `pkg` and `env` are not passed to plugin anymore. Plugins relying on a `package.json` must verify the presence of a valid `package.json` and load it. Plugins can use `process.env` instead of `env`.
This commit is contained in:
+136
-46
@@ -1,9 +1,9 @@
|
||||
import test from 'ava';
|
||||
import {writeJson} from 'fs-extra';
|
||||
import {writeFile, writeJson} from 'fs-extra';
|
||||
import proxyquire from 'proxyquire';
|
||||
import {stub} from 'sinon';
|
||||
import normalizeData from 'normalize-package-data';
|
||||
import {gitRepo} from './helpers/git-utils';
|
||||
import yaml from 'js-yaml';
|
||||
import {gitRepo, gitCommits, gitShallowClone, gitAddConfig} from './helpers/git-utils';
|
||||
|
||||
test.beforeEach(t => {
|
||||
// Save the current process.env
|
||||
@@ -21,85 +21,175 @@ test.afterEach.always(t => {
|
||||
process.env = Object.assign({}, t.context.env);
|
||||
});
|
||||
|
||||
test.serial('Default values', async t => {
|
||||
const pkg = {name: 'package_name', release: {}};
|
||||
test.serial('Default values, reading repositoryUrl from package.json', async t => {
|
||||
const pkg = {repository: 'git@package.com:owner/module.git'};
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
await gitCommits(['First']);
|
||||
// Add remote.origin.url config
|
||||
await gitAddConfig('remote.origin.url', 'git@repo.com:owner/module.git');
|
||||
// Create package.json in repository root
|
||||
await writeJson('./package.json', pkg);
|
||||
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the default options are set
|
||||
t.is(options.branch, 'master');
|
||||
t.is(options.repositoryUrl, 'git@package.com:owner/module.git');
|
||||
});
|
||||
|
||||
test.serial('Default values, reading repositoryUrl from repo if not set in package.json', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Add remote.origin.url config
|
||||
await gitAddConfig('remote.origin.url', 'git@repo.com:owner/module.git');
|
||||
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the default options are set
|
||||
t.is(options.branch, 'master');
|
||||
t.is(options.repositoryUrl, 'git@repo.com:owner/module.git');
|
||||
});
|
||||
|
||||
test.serial('Default values, reading repositoryUrl (http url) from package.json if not set in repo', async t => {
|
||||
const pkg = {repository: 'git+https://hostname.com/owner/module.git'};
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Create package.json in repository root
|
||||
await writeJson('./package.json', pkg);
|
||||
|
||||
const result = await t.context.getConfig();
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the normalized package is returned
|
||||
normalizeData(pkg);
|
||||
t.deepEqual(result.pkg, pkg);
|
||||
// Verify the default options are set
|
||||
t.is(result.options.branch, 'master');
|
||||
t.is(options.branch, 'master');
|
||||
t.is(options.repositoryUrl, pkg.repository);
|
||||
});
|
||||
|
||||
test.serial('Read package.json configuration', async t => {
|
||||
test.serial('Read options from package.json', async t => {
|
||||
const release = {
|
||||
analyzeCommits: 'analyzeCommits',
|
||||
generateNotes: 'generateNotes',
|
||||
getLastRelease: {
|
||||
path: 'getLastRelease',
|
||||
param: 'getLastRelease_param',
|
||||
},
|
||||
getLastRelease: {path: 'getLastRelease', param: 'getLastRelease_param'},
|
||||
branch: 'test_branch',
|
||||
repositoryUrl: 'git+https://hostname.com/owner/module.git',
|
||||
};
|
||||
const pkg = {name: 'package_name', release};
|
||||
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Create package.json in repository root
|
||||
await writeJson('./package.json', pkg);
|
||||
await writeJson('./package.json', {release});
|
||||
|
||||
const result = await t.context.getConfig();
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the options contains the plugin config from package.json
|
||||
t.is(result.options.analyzeCommits, release.analyzeCommits);
|
||||
t.is(result.options.generateNotes, release.generateNotes);
|
||||
t.deepEqual(result.options.getLastRelease, release.getLastRelease);
|
||||
t.is(result.options.branch, release.branch);
|
||||
|
||||
t.deepEqual(options, release);
|
||||
// Verify the plugins module is called with the plugin options from package.json
|
||||
t.is(t.context.plugins.firstCall.args[0].analyzeCommits, release.analyzeCommits);
|
||||
t.is(t.context.plugins.firstCall.args[0].generateNotes, release.generateNotes);
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0].getLastRelease, release.getLastRelease);
|
||||
t.is(t.context.plugins.firstCall.args[0].branch, release.branch);
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0], release);
|
||||
});
|
||||
|
||||
test.serial('Prioritise cli parameters over package.json configuration', async t => {
|
||||
test.serial('Read options from .releaserc.yml', async t => {
|
||||
const release = {
|
||||
analyzeCommits: 'analyzeCommits',
|
||||
generateNotes: 'generateNotes',
|
||||
getLastRelease: {
|
||||
path: 'getLastRelease',
|
||||
param: 'getLastRelease_pkg',
|
||||
},
|
||||
getLastRelease: {path: 'getLastRelease', param: 'getLastRelease_param'},
|
||||
branch: 'test_branch',
|
||||
repositoryUrl: 'git+https://hostname.com/owner/module.git',
|
||||
};
|
||||
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Create package.json in repository root
|
||||
await writeFile('.releaserc.yml', yaml.safeDump(release));
|
||||
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the options contains the plugin config from package.json
|
||||
t.deepEqual(options, release);
|
||||
// Verify the plugins module is called with the plugin options from package.json
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0], release);
|
||||
});
|
||||
|
||||
test.serial('Read options from .releaserc.json', async t => {
|
||||
const release = {
|
||||
getLastRelease: {path: 'getLastRelease', param: 'getLastRelease_param'},
|
||||
branch: 'test_branch',
|
||||
repositoryUrl: 'git+https://hostname.com/owner/module.git',
|
||||
};
|
||||
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Create package.json in repository root
|
||||
await writeJson('.releaserc.json', release);
|
||||
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the options contains the plugin config from package.json
|
||||
t.deepEqual(options, release);
|
||||
// Verify the plugins module is called with the plugin options from package.json
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0], release);
|
||||
});
|
||||
|
||||
test.serial('Read options from .releaserc.js', async t => {
|
||||
const release = {
|
||||
getLastRelease: {path: 'getLastRelease', param: 'getLastRelease_param'},
|
||||
branch: 'test_branch',
|
||||
repositoryUrl: 'git+https://hostname.com/owner/module.git',
|
||||
};
|
||||
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Create package.json in repository root
|
||||
await writeFile('.releaserc.js', `module.exports = ${JSON.stringify(release)}`);
|
||||
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the options contains the plugin config from package.json
|
||||
t.deepEqual(options, release);
|
||||
// Verify the plugins module is called with the plugin options from package.json
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0], release);
|
||||
});
|
||||
|
||||
test.serial('Read options from release.config.js', async t => {
|
||||
const release = {
|
||||
getLastRelease: {path: 'getLastRelease', param: 'getLastRelease_param'},
|
||||
branch: 'test_branch',
|
||||
repositoryUrl: 'git+https://hostname.com/owner/module.git',
|
||||
};
|
||||
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Create package.json in repository root
|
||||
await writeFile('release.config.js', `module.exports = ${JSON.stringify(release)}`);
|
||||
|
||||
const {options} = await t.context.getConfig();
|
||||
|
||||
// Verify the options contains the plugin config from package.json
|
||||
t.deepEqual(options, release);
|
||||
// Verify the plugins module is called with the plugin options from package.json
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0], release);
|
||||
});
|
||||
|
||||
test.serial('Prioritise cli parameters over file configuration and git repo', async t => {
|
||||
const release = {
|
||||
getLastRelease: {path: 'getLastRelease', param: 'getLastRelease_pkg'},
|
||||
branch: 'branch_pkg',
|
||||
};
|
||||
const options = {
|
||||
getLastRelease: {
|
||||
path: 'getLastRelease',
|
||||
param: 'getLastRelease_cli',
|
||||
},
|
||||
getLastRelease: {path: 'getLastRelease', param: 'getLastRelease_cli'},
|
||||
branch: 'branch_cli',
|
||||
repositoryUrl: 'http://cli-url.com/owner/package',
|
||||
};
|
||||
const pkg = {name: 'package_name', release};
|
||||
|
||||
const pkg = {release, repository: 'git@hostname.com:owner/module.git'};
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
const repo = await gitRepo();
|
||||
await gitCommits(['First']);
|
||||
// Create a clone
|
||||
await gitShallowClone(repo);
|
||||
// Create package.json in repository root
|
||||
await writeJson('./package.json', pkg);
|
||||
|
||||
const result = await t.context.getConfig(options);
|
||||
|
||||
// Verify the options contains the plugin config from cli
|
||||
t.deepEqual(result.options.getLastRelease, options.getLastRelease);
|
||||
t.is(result.options.branch, options.branch);
|
||||
|
||||
t.deepEqual(result.options, options);
|
||||
// Verify the plugins module is called with the plugin options from cli
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0].getLastRelease, options.getLastRelease);
|
||||
t.is(t.context.plugins.firstCall.args[0].branch, options.branch);
|
||||
t.deepEqual(t.context.plugins.firstCall.args[0], options);
|
||||
});
|
||||
|
||||
+37
-2
@@ -1,6 +1,15 @@
|
||||
import test from 'ava';
|
||||
import {gitTagHead, gitCommitTag, isCommitInHistory, unshallow, gitHead} from '../lib/git';
|
||||
import {gitRepo, gitCommits, gitCheckout, gitTagVersion, gitShallowClone, gitLog} from './helpers/git-utils';
|
||||
import fileUrl from 'file-url';
|
||||
import {gitTagHead, gitCommitTag, isCommitInHistory, unshallow, gitHead, repoUrl} from '../lib/git';
|
||||
import {
|
||||
gitRepo,
|
||||
gitCommits,
|
||||
gitCheckout,
|
||||
gitTagVersion,
|
||||
gitShallowClone,
|
||||
gitLog,
|
||||
gitAddConfig,
|
||||
} from './helpers/git-utils';
|
||||
|
||||
test.beforeEach(t => {
|
||||
// Save the current working diretory
|
||||
@@ -93,3 +102,29 @@ test.serial('Get the commit sha for a given tag or "null" if the tag does not ex
|
||||
t.is((await gitTagHead('v1.0.0')).substring(0, 7), commits[0].hash);
|
||||
t.falsy(await gitTagHead('missing_tag'));
|
||||
});
|
||||
|
||||
test.serial('Return git remote repository url from config', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
// Add remote.origin.url config
|
||||
await gitAddConfig('remote.origin.url', 'git@hostname.com:owner/package.git');
|
||||
|
||||
t.is(await repoUrl(), 'git@hostname.com:owner/package.git');
|
||||
});
|
||||
|
||||
test.serial('Return git remote repository url set while cloning', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
const repo = await gitRepo();
|
||||
await gitCommits(['First']);
|
||||
// Create a clone
|
||||
await gitShallowClone(repo);
|
||||
|
||||
t.is(await repoUrl(), fileUrl(repo));
|
||||
});
|
||||
|
||||
test.serial('Return "null" if git repository url is not set', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
|
||||
t.is(await repoUrl(), null);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import tempy from 'tempy';
|
||||
import execa from 'execa';
|
||||
import pMapSeries from 'p-map-series';
|
||||
import fileUrl from 'file-url';
|
||||
import pReduce from 'p-reduce';
|
||||
|
||||
/**
|
||||
* Commit message informations.
|
||||
@@ -33,11 +34,16 @@ export async function gitRepo() {
|
||||
* @returns {Array<Commit>} The created commits, in reverse order (to match `git log` order).
|
||||
*/
|
||||
export async function gitCommits(messages) {
|
||||
return (await pMapSeries(messages, async msg => {
|
||||
const {stdout} = await execa('git', ['commit', '-m', msg, '--allow-empty', '--no-gpg-sign']);
|
||||
const [, branch, hash, message] = /^\[(\w+)\(?.*?\)?(\w+)\] (.+)$/.exec(stdout);
|
||||
return {branch, hash, message};
|
||||
})).reverse();
|
||||
return (await pReduce(
|
||||
messages,
|
||||
async (commits, msg) => {
|
||||
const {stdout} = await execa('git', ['commit', '-m', msg, '--allow-empty', '--no-gpg-sign']);
|
||||
const [, branch, hash, message] = /^\[(\w+)\(?.*?\)?(\w+)\] (.+)$/.exec(stdout);
|
||||
commits.push({branch, hash, message});
|
||||
return commits;
|
||||
},
|
||||
[]
|
||||
)).reverse();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +115,7 @@ export async function gitShallowClone(origin, branch = 'master', depth = 1) {
|
||||
const dir = tempy.directory();
|
||||
|
||||
process.chdir(dir);
|
||||
await execa('git', ['clone', '--no-hardlinks', '--no-tags', '-b', branch, '--depth', depth, `file://${origin}`, dir]);
|
||||
await execa('git', ['clone', '--no-hardlinks', '--no-tags', '-b', branch, '--depth', depth, fileUrl(origin), dir]);
|
||||
return dir;
|
||||
}
|
||||
|
||||
@@ -137,3 +143,13 @@ export async function gitDetachedHead(origin, head) {
|
||||
export async function gitPackRefs() {
|
||||
await execa('git', ['pack-refs', '--all']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Git configuration.
|
||||
*
|
||||
* @param {string} name Config name.
|
||||
* @param {string} value Config value.
|
||||
*/
|
||||
export async function gitAddConfig(name, value) {
|
||||
await execa('git', ['config', '--add', name, value]);
|
||||
}
|
||||
|
||||
+30
-24
@@ -1,8 +1,8 @@
|
||||
import test from 'ava';
|
||||
import {writeJson} from 'fs-extra';
|
||||
import proxyquire from 'proxyquire';
|
||||
import {stub} from 'sinon';
|
||||
import normalizeData from 'normalize-package-data';
|
||||
import tempy from 'tempy';
|
||||
import SemanticReleaseError from '@semantic-release/error';
|
||||
import {gitHead as getGitHead} from '../lib/git';
|
||||
import {gitRepo, gitCommits, gitTagVersion} from './helpers/git-utils';
|
||||
|
||||
@@ -41,11 +41,9 @@ test.serial('Plugins are called with expected values', async t => {
|
||||
// Add new commits to the master branch
|
||||
commits = (await gitCommits(['Second'])).concat(commits);
|
||||
|
||||
const name = 'package-name';
|
||||
const lastRelease = {version: '1.0.0', gitHead: commits[commits.length - 1].hash, gitTag: 'v1.0.0'};
|
||||
const nextRelease = {type: 'major', version: '2.0.0', gitHead: await getGitHead(), gitTag: 'v2.0.0'};
|
||||
const notes = 'Release notes';
|
||||
|
||||
const verifyConditions1 = stub().resolves();
|
||||
const verifyConditions2 = stub().resolves();
|
||||
const getLastRelease = stub().resolves(lastRelease);
|
||||
@@ -56,6 +54,7 @@ test.serial('Plugins are called with expected values', async t => {
|
||||
|
||||
const options = {
|
||||
branch: 'master',
|
||||
repositoryUrl: 'git@hostname.com:owner/module.git',
|
||||
verifyConditions: [verifyConditions1, verifyConditions2],
|
||||
getLastRelease,
|
||||
analyzeCommits,
|
||||
@@ -63,34 +62,26 @@ test.serial('Plugins are called with expected values', async t => {
|
||||
generateNotes,
|
||||
publish,
|
||||
};
|
||||
const pkg = {name, version: '0.0.0-dev'};
|
||||
normalizeData(pkg);
|
||||
|
||||
await writeJson('./package.json', pkg);
|
||||
|
||||
await t.context.semanticRelease(options);
|
||||
|
||||
t.true(verifyConditions1.calledOnce);
|
||||
t.deepEqual(verifyConditions1.firstCall.args[1], {env: process.env, options, pkg, logger: t.context.logger});
|
||||
t.deepEqual(verifyConditions1.firstCall.args[1], {options, logger: t.context.logger});
|
||||
t.true(verifyConditions2.calledOnce);
|
||||
t.deepEqual(verifyConditions2.firstCall.args[1], {env: process.env, options, pkg, logger: t.context.logger});
|
||||
t.deepEqual(verifyConditions2.firstCall.args[1], {options, logger: t.context.logger});
|
||||
|
||||
t.true(getLastRelease.calledOnce);
|
||||
t.deepEqual(getLastRelease.firstCall.args[1], {env: process.env, options, pkg, logger: t.context.logger});
|
||||
t.deepEqual(getLastRelease.firstCall.args[1], {options, logger: t.context.logger});
|
||||
|
||||
t.true(analyzeCommits.calledOnce);
|
||||
t.deepEqual(analyzeCommits.firstCall.args[1].env, process.env);
|
||||
t.deepEqual(analyzeCommits.firstCall.args[1].options, options);
|
||||
t.deepEqual(analyzeCommits.firstCall.args[1].pkg, pkg);
|
||||
t.deepEqual(analyzeCommits.firstCall.args[1].logger, t.context.logger);
|
||||
t.deepEqual(analyzeCommits.firstCall.args[1].lastRelease, lastRelease);
|
||||
t.deepEqual(analyzeCommits.firstCall.args[1].commits[0].hash.substring(0, 7), commits[0].hash);
|
||||
t.deepEqual(analyzeCommits.firstCall.args[1].commits[0].message, commits[0].message);
|
||||
|
||||
t.true(verifyRelease.calledOnce);
|
||||
t.deepEqual(verifyRelease.firstCall.args[1].env, process.env);
|
||||
t.deepEqual(verifyRelease.firstCall.args[1].options, options);
|
||||
t.deepEqual(verifyRelease.firstCall.args[1].pkg, pkg);
|
||||
t.deepEqual(verifyRelease.firstCall.args[1].logger, t.context.logger);
|
||||
t.deepEqual(verifyRelease.firstCall.args[1].lastRelease, lastRelease);
|
||||
t.deepEqual(verifyRelease.firstCall.args[1].commits[0].hash.substring(0, 7), commits[0].hash);
|
||||
@@ -98,9 +89,7 @@ test.serial('Plugins are called with expected values', async t => {
|
||||
t.deepEqual(verifyRelease.firstCall.args[1].nextRelease, nextRelease);
|
||||
|
||||
t.true(generateNotes.calledOnce);
|
||||
t.deepEqual(generateNotes.firstCall.args[1].env, process.env);
|
||||
t.deepEqual(generateNotes.firstCall.args[1].options, options);
|
||||
t.deepEqual(generateNotes.firstCall.args[1].pkg, pkg);
|
||||
t.deepEqual(generateNotes.firstCall.args[1].logger, t.context.logger);
|
||||
t.deepEqual(generateNotes.firstCall.args[1].lastRelease, lastRelease);
|
||||
t.deepEqual(generateNotes.firstCall.args[1].commits[0].hash.substring(0, 7), commits[0].hash);
|
||||
@@ -109,7 +98,6 @@ test.serial('Plugins are called with expected values', async t => {
|
||||
|
||||
t.true(publish.calledOnce);
|
||||
t.deepEqual(publish.firstCall.args[1].options, options);
|
||||
t.deepEqual(publish.firstCall.args[1].pkg, pkg);
|
||||
t.deepEqual(publish.firstCall.args[1].logger, t.context.logger);
|
||||
t.deepEqual(publish.firstCall.args[1].lastRelease, lastRelease);
|
||||
t.deepEqual(publish.firstCall.args[1].commits[0].hash.substring(0, 7), commits[0].hash);
|
||||
@@ -139,6 +127,7 @@ test.serial('Use new gitHead, and recreate release notes if a publish plugin cre
|
||||
|
||||
const options = {
|
||||
branch: 'master',
|
||||
repositoryUrl: 'git@hostname.com:owner/module.git',
|
||||
verifyConditions: stub().resolves(),
|
||||
getLastRelease: stub().resolves(lastRelease),
|
||||
analyzeCommits: stub().resolves(nextRelease.type),
|
||||
@@ -147,7 +136,6 @@ test.serial('Use new gitHead, and recreate release notes if a publish plugin cre
|
||||
publish: [publish1, publish2],
|
||||
};
|
||||
|
||||
await writeJson('./package.json', {});
|
||||
await t.context.semanticRelease(options);
|
||||
|
||||
t.true(generateNotes.calledTwice);
|
||||
@@ -172,7 +160,6 @@ test.serial('Dry-run skips verifyConditions and publish', async t => {
|
||||
// Add new commits to the master branch
|
||||
commits = (await gitCommits(['Second'])).concat(commits);
|
||||
|
||||
const name = 'package-name';
|
||||
const lastRelease = {version: '1.0.0', gitHead: commits[commits.length - 1].hash, gitTag: 'v1.0.0'};
|
||||
const nextRelease = {type: 'major', version: '2.0.0', gitHead: await getGitHead(), gitTag: 'v2.0.0'};
|
||||
const notes = 'Release notes';
|
||||
@@ -187,6 +174,7 @@ test.serial('Dry-run skips verifyConditions and publish', async t => {
|
||||
const options = {
|
||||
dryRun: true,
|
||||
branch: 'master',
|
||||
repositoryUrl: 'git@hostname.com:owner/module.git',
|
||||
verifyConditions,
|
||||
getLastRelease,
|
||||
analyzeCommits,
|
||||
@@ -194,10 +182,6 @@ test.serial('Dry-run skips verifyConditions and publish', async t => {
|
||||
generateNotes,
|
||||
publish,
|
||||
};
|
||||
const pkg = {name, version: '0.0.0-dev'};
|
||||
normalizeData(pkg);
|
||||
|
||||
await writeJson('./package.json', pkg);
|
||||
|
||||
await t.context.semanticRelease(options);
|
||||
|
||||
@@ -208,3 +192,25 @@ test.serial('Dry-run skips verifyConditions and publish', async t => {
|
||||
t.true(generateNotes.calledOnce);
|
||||
t.true(publish.notCalled);
|
||||
});
|
||||
|
||||
test.serial('Throw SemanticReleaseError if not running from a git repository', async t => {
|
||||
// Set the current working directory to a temp directory
|
||||
process.chdir(tempy.directory());
|
||||
|
||||
const error = await t.throws(t.context.semanticRelease());
|
||||
|
||||
// Verify error code and type
|
||||
t.is(error.code, 'ENOGITREPO');
|
||||
t.true(error instanceof SemanticReleaseError);
|
||||
});
|
||||
|
||||
test.serial('Throw SemanticReleaseError if repositoryUrl is not set and canot be found', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
|
||||
const error = await t.throws(t.context.semanticRelease());
|
||||
|
||||
// Verify error code and type
|
||||
t.is(error.code, 'ENOREPOURL');
|
||||
t.true(error instanceof SemanticReleaseError);
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ import registry from './helpers/registry';
|
||||
import mockServer from './helpers/mockserver';
|
||||
import semanticRelease from '..';
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
/* eslint camelcase: ["error", {properties: "never"}] */
|
||||
|
||||
// Environment variables used with cli
|
||||
const env = {
|
||||
|
||||
Reference in New Issue
Block a user