- 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`.
196 lines
7.3 KiB
JavaScript
196 lines
7.3 KiB
JavaScript
import test from 'ava';
|
|
import {writeFile, writeJson} from 'fs-extra';
|
|
import proxyquire from 'proxyquire';
|
|
import {stub} from 'sinon';
|
|
import yaml from 'js-yaml';
|
|
import {gitRepo, gitCommits, gitShallowClone, gitAddConfig} from './helpers/git-utils';
|
|
|
|
test.beforeEach(t => {
|
|
// Save the current process.env
|
|
t.context.env = Object.assign({}, process.env);
|
|
// Save the current working diretory
|
|
t.context.cwd = process.cwd();
|
|
t.context.plugins = stub().returns({});
|
|
t.context.getConfig = proxyquire('../lib/get-config', {'./plugins': t.context.plugins});
|
|
});
|
|
|
|
test.afterEach.always(t => {
|
|
// Restore the current working directory
|
|
process.chdir(t.context.cwd);
|
|
// Restore process.env
|
|
process.env = Object.assign({}, t.context.env);
|
|
});
|
|
|
|
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 {options} = await t.context.getConfig();
|
|
|
|
// Verify the default options are set
|
|
t.is(options.branch, 'master');
|
|
t.is(options.repositoryUrl, pkg.repository);
|
|
});
|
|
|
|
test.serial('Read options from package.json', async t => {
|
|
const release = {
|
|
analyzeCommits: 'analyzeCommits',
|
|
generateNotes: 'generateNotes',
|
|
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('./package.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.yml', 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.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'},
|
|
branch: 'branch_cli',
|
|
repositoryUrl: 'http://cli-url.com/owner/package',
|
|
};
|
|
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
|
|
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, options);
|
|
// Verify the plugins module is called with the plugin options from cli
|
|
t.deepEqual(t.context.plugins.firstCall.args[0], options);
|
|
});
|