for #2543 BREAKING CHANGE: semantic-release is now ESM-only. since it is used through its own executable, the impact on consuming projects should be minimal BREAKING CHANGE: references to plugin files in configs need to include the file extension because of executing in an ESM context
591 lines
23 KiB
JavaScript
591 lines
23 KiB
JavaScript
import path from 'node:path';
|
|
import {format} from 'node:util';
|
|
import test from 'ava';
|
|
import fsExtra from 'fs-extra';
|
|
import {omit} from 'lodash-es';
|
|
import * as td from 'testdouble';
|
|
import yaml from 'js-yaml';
|
|
import {gitAddConfig, gitCommits, gitRepo, gitShallowClone, gitTagVersion} from './helpers/git-utils.js';
|
|
|
|
const {outputJson, writeFile} = fsExtra;
|
|
const pluginsConfig = {foo: 'bar', baz: 'qux'};
|
|
let plugins;
|
|
|
|
const DEFAULT_PLUGINS = [
|
|
'@semantic-release/commit-analyzer',
|
|
'@semantic-release/release-notes-generator',
|
|
'@semantic-release/npm',
|
|
'@semantic-release/github',
|
|
];
|
|
|
|
test.beforeEach(async (t) => {
|
|
plugins = (await td.replaceEsm('../lib/plugins/index.js')).default;
|
|
t.context.getConfig = (await import('../lib/get-config.js')).default;
|
|
});
|
|
|
|
test.afterEach.always((t) => {
|
|
td.reset();
|
|
});
|
|
|
|
test('Default values, reading repositoryUrl from package.json', async (t) => {
|
|
const pkg = {repository: 'https://host.null/owner/package.git'};
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo(true);
|
|
await gitCommits(['First'], {cwd});
|
|
await gitTagVersion('v1.0.0', undefined, {cwd});
|
|
await gitTagVersion('v1.1.0', undefined, {cwd});
|
|
// Add remote.origin.url config
|
|
await gitAddConfig('remote.origin.url', 'git@host.null:owner/repo.git', {cwd});
|
|
// Create package.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), pkg);
|
|
|
|
const {options: result} = await t.context.getConfig({cwd});
|
|
|
|
// Verify the default options are set
|
|
t.deepEqual(result.branches, [
|
|
'+([0-9])?(.{+([0-9]),x}).x',
|
|
'master',
|
|
'next',
|
|
'next-major',
|
|
{name: 'beta', prerelease: true},
|
|
{name: 'alpha', prerelease: true},
|
|
]);
|
|
t.is(result.repositoryUrl, 'https://host.null/owner/package.git');
|
|
t.is(result.tagFormat, `v\${version}`);
|
|
});
|
|
|
|
test('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
|
|
const {cwd} = await gitRepo(true);
|
|
// Add remote.origin.url config
|
|
await gitAddConfig('remote.origin.url', 'https://host.null/owner/module.git', {cwd});
|
|
|
|
const {options: result} = await t.context.getConfig({cwd});
|
|
|
|
// Verify the default options are set
|
|
t.deepEqual(result.branches, [
|
|
'+([0-9])?(.{+([0-9]),x}).x',
|
|
'master',
|
|
'next',
|
|
'next-major',
|
|
{name: 'beta', prerelease: true},
|
|
{name: 'alpha', prerelease: true},
|
|
]);
|
|
t.is(result.repositoryUrl, 'https://host.null/owner/module.git');
|
|
t.is(result.tagFormat, `v\${version}`);
|
|
});
|
|
|
|
test('Default values, reading repositoryUrl (http url) from package.json if not set in repo', async (t) => {
|
|
const pkg = {repository: 'https://host.null/owner/module.git'};
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
// Create package.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), pkg);
|
|
|
|
const {options: result} = await t.context.getConfig({cwd});
|
|
|
|
// Verify the default options are set
|
|
t.deepEqual(result.branches, [
|
|
'+([0-9])?(.{+([0-9]),x}).x',
|
|
'master',
|
|
'next',
|
|
'next-major',
|
|
{name: 'beta', prerelease: true},
|
|
{name: 'alpha', prerelease: true},
|
|
]);
|
|
t.is(result.repositoryUrl, 'https://host.null/owner/module.git');
|
|
t.is(result.tagFormat, `v\${version}`);
|
|
});
|
|
|
|
test('Convert "ci" option to "noCi"', async (t) => {
|
|
const pkg = {repository: 'https://host.null/owner/module.git', release: {ci: false}};
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
// Create package.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), pkg);
|
|
|
|
const {options: result} = await t.context.getConfig({cwd});
|
|
|
|
t.is(result.noCi, true);
|
|
});
|
|
|
|
test.serial('Read options from package.json', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
generateNotes: 'generateNotes',
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Verify the plugins module is called with the plugin options from package.json
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
// Create package.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: options});
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from package.json
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read options from .releaserc.yml', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json in repository root
|
|
await writeFile(path.resolve(cwd, '.releaserc.yml'), yaml.dump(options));
|
|
// Verify the plugins module is called with the plugin options from package.json
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from package.json
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read options from .releaserc.json', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json in repository root
|
|
await outputJson(path.resolve(cwd, '.releaserc.json'), options);
|
|
// Verify the plugins module is called with the plugin options from package.json
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from package.json
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read options from .releaserc.js', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json in repository root
|
|
await writeFile(path.resolve(cwd, '.releaserc.js'), `module.exports = ${JSON.stringify(options)}`);
|
|
// Verify the plugins module is called with the plugin options from package.json
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from package.json
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read options from .releaserc.cjs', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create .releaserc.cjs in repository root
|
|
await writeFile(path.resolve(cwd, '.releaserc.cjs'), `module.exports = ${JSON.stringify(options)}`);
|
|
// Verify the plugins module is called with the plugin options from .releaserc.cjs
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from .releaserc.cjs
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read options from release.config.js', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json in repository root
|
|
await writeFile(path.resolve(cwd, 'release.config.js'), `module.exports = ${JSON.stringify(options)}`);
|
|
// Verify the plugins module is called with the plugin options from package.json
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from package.json
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read options from release.config.cjs', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Verify the plugins module is called with the plugin options from release.config.cjs
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
// Create release.config.cjs in repository root
|
|
await writeFile(path.resolve(cwd, 'release.config.cjs'), `module.exports = ${JSON.stringify(options)}`);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from release.config.cjs
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Prioritise CLI/API parameters over file configuration and git repo', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
let {cwd, repositoryUrl} = await gitRepo();
|
|
await gitCommits(['First'], {cwd});
|
|
// Create a clone
|
|
cwd = await gitShallowClone(repositoryUrl);
|
|
const pkgOptions = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_pkg'},
|
|
branches: ['branch_pkg'],
|
|
};
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_cli'},
|
|
branches: ['branch_cli'],
|
|
repositoryUrl: 'http://cli-url.com/owner/package',
|
|
tagFormat: `cli\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Verify the plugins module is called with the plugin options from CLI/API
|
|
td.when(plugins({cwd, options}, {})).thenResolve(pluginsConfig);
|
|
const pkg = {release: pkgOptions, repository: 'git@host.null:owner/module.git'};
|
|
// Create package.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), pkg);
|
|
|
|
const result = await t.context.getConfig({cwd}, options);
|
|
|
|
// Verify the options contains the plugin config from CLI/API
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read configuration from file path in "extends"', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {extends: './shareable.json'};
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
generateNotes: 'generateNotes',
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: ['plugin-1', ['plugin-2', {plugin2Opt: 'value'}]],
|
|
};
|
|
// Create package.json and shareable.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'shareable.json'), options);
|
|
// Verify the plugins module is called with the plugin options from shareable.json
|
|
td.when(plugins(
|
|
{cwd, options},
|
|
{
|
|
analyzeCommits: './shareable.json',
|
|
generateNotes: './shareable.json',
|
|
'plugin-1': './shareable.json',
|
|
'plugin-2': './shareable.json',
|
|
}
|
|
)).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from shareable.json
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read configuration from module path in "extends"', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {extends: 'shareable'};
|
|
const options = {
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
generateNotes: 'generateNotes',
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json and shareable.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'node_modules/shareable/index.json'), options);
|
|
// Verify the plugins module is called with the plugin options from shareable.json
|
|
td.when(plugins(
|
|
{cwd, options},
|
|
{analyzeCommits: 'shareable', generateNotes: 'shareable'}
|
|
)).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from shareable.json
|
|
t.deepEqual(result, {options, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Read configuration from an array of paths in "extends"', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {extends: ['./shareable1.json', './shareable2.json']};
|
|
const options1 = {
|
|
verifyRelease: 'verifyRelease1',
|
|
analyzeCommits: {path: 'analyzeCommits1', param: 'analyzeCommits_param1'},
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
};
|
|
const options2 = {
|
|
verifyRelease: 'verifyRelease2',
|
|
generateNotes: 'generateNotes2',
|
|
analyzeCommits: {path: 'analyzeCommits2', param: 'analyzeCommits_param2'},
|
|
branches: ['test_branch'],
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json and shareable.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'shareable1.json'), options1);
|
|
await outputJson(path.resolve(cwd, 'shareable2.json'), options2);
|
|
const expectedOptions = {...options1, ...options2, branches: ['test_branch']};
|
|
// Verify the plugins module is called with the plugin options from shareable1.json and shareable2.json
|
|
td.when(plugins(
|
|
{options: expectedOptions, cwd},
|
|
{
|
|
verifyRelease1: './shareable1.json',
|
|
verifyRelease2: './shareable2.json',
|
|
generateNotes2: './shareable2.json',
|
|
analyzeCommits1: './shareable1.json',
|
|
analyzeCommits2: './shareable2.json',
|
|
}
|
|
)).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from shareable1.json and shareable2.json
|
|
t.deepEqual(result, {options: expectedOptions, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Prioritize configuration from config file over "extends"', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {
|
|
extends: './shareable.json',
|
|
branches: ['test_pkg'],
|
|
generateNotes: 'generateNotes',
|
|
publish: [{path: 'publishPkg', param: 'publishPkg_param'}],
|
|
};
|
|
const options1 = {
|
|
analyzeCommits: 'analyzeCommits',
|
|
generateNotes: 'generateNotesShareable',
|
|
publish: [{path: 'publishShareable', param: 'publishShareable_param'}],
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json and shareable.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'shareable.json'), options1);
|
|
const expectedOptions = omit({...options1, ...pkgOptions, branches: ['test_pkg']}, 'extends');
|
|
// Verify the plugins module is called with the plugin options from package.json and shareable.json
|
|
td.when(plugins(
|
|
{cwd, options: expectedOptions},
|
|
{
|
|
analyzeCommits: './shareable.json',
|
|
generateNotesShareable: './shareable.json',
|
|
publishShareable: './shareable.json',
|
|
}
|
|
)).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from package.json and shareable.json
|
|
t.deepEqual(result, {options: expectedOptions, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Prioritize configuration from cli/API options over "extends"', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const cliOptions = {
|
|
extends: './shareable2.json',
|
|
branches: ['branch_opts'],
|
|
publish: [{path: 'publishOpts', param: 'publishOpts_param'}],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
};
|
|
const pkgOptions = {
|
|
extends: './shareable1.json',
|
|
branches: ['branch_pkg'],
|
|
generateNotes: 'generateNotes',
|
|
publish: [{path: 'publishPkg', param: 'publishPkg_param'}],
|
|
};
|
|
const options1 = {
|
|
analyzeCommits: 'analyzeCommits1',
|
|
generateNotes: 'generateNotesShareable1',
|
|
publish: [{path: 'publishShareable', param: 'publishShareable_param1'}],
|
|
branches: ['test_branch1'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
};
|
|
const options2 = {
|
|
analyzeCommits: 'analyzeCommits2',
|
|
publish: [{path: 'publishShareable', param: 'publishShareable_param2'}],
|
|
branches: ['test_branch2'],
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create package.json, shareable1.json and shareable2.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'shareable1.json'), options1);
|
|
await outputJson(path.resolve(cwd, 'shareable2.json'), options2);
|
|
const expectedOptions = omit({...options2, ...pkgOptions, ...cliOptions, branches: ['branch_opts']}, 'extends');
|
|
// Verify the plugins module is called with the plugin options from package.json and shareable2.json
|
|
td.when(plugins(
|
|
{cwd, options: expectedOptions},
|
|
{analyzeCommits2: './shareable2.json', publishShareable: './shareable2.json'}
|
|
)).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd}, cliOptions);
|
|
|
|
// Verify the options contains the plugin config from package.json and shareable2.json
|
|
t.deepEqual(result, {options: expectedOptions, plugins: pluginsConfig});
|
|
});
|
|
|
|
test.serial('Allow to unset properties defined in shareable config with "null"', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {
|
|
extends: './shareable.json',
|
|
analyzeCommits: null,
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
plugins: null,
|
|
};
|
|
const options1 = {
|
|
generateNotes: 'generateNotes',
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
tagFormat: `v\${version}`,
|
|
plugins: ['test-plugin'],
|
|
};
|
|
// Create package.json and shareable.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'shareable.json'), options1);
|
|
// Verify the plugins module is called with the plugin options from shareable.json and the default `plugins`
|
|
td.when(plugins(
|
|
{
|
|
options: {
|
|
...omit(options1, 'analyzeCommits'),
|
|
...omit(pkgOptions, ['extends', 'analyzeCommits']),
|
|
plugins: DEFAULT_PLUGINS,
|
|
},
|
|
cwd,
|
|
},
|
|
{
|
|
generateNotes: './shareable.json',
|
|
analyzeCommits: './shareable.json',
|
|
'test-plugin': './shareable.json',
|
|
}
|
|
)).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from shareable.json and the default `plugins`
|
|
t.deepEqual(
|
|
result,
|
|
{
|
|
options: {
|
|
...omit(options1, ['analyzeCommits']),
|
|
...omit(pkgOptions, ['extends', 'analyzeCommits']),
|
|
plugins: DEFAULT_PLUGINS,
|
|
},
|
|
plugins: pluginsConfig
|
|
}
|
|
);
|
|
});
|
|
|
|
test.serial('Allow to unset properties defined in shareable config with "undefined"', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {
|
|
extends: './shareable.json',
|
|
analyzeCommits: undefined,
|
|
branches: ['test_branch'],
|
|
repositoryUrl: 'https://host.null/owner/module.git',
|
|
};
|
|
const options1 = {
|
|
generateNotes: 'generateNotes',
|
|
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'},
|
|
tagFormat: `v\${version}`,
|
|
plugins: false,
|
|
};
|
|
// Create release.config.js and shareable.json in repository root
|
|
await writeFile(path.resolve(cwd, 'release.config.js'), `module.exports = ${format(pkgOptions)}`);
|
|
await outputJson(path.resolve(cwd, 'shareable.json'), options1);
|
|
const expectedOptions = {
|
|
...omit(options1, 'analyzeCommits'),
|
|
...omit(pkgOptions, ['extends', 'analyzeCommits']),
|
|
branches: ['test_branch'],
|
|
};
|
|
// Verify the plugins module is called with the plugin options from shareable.json
|
|
td.when(plugins(
|
|
{options: expectedOptions, cwd},
|
|
{generateNotes: './shareable.json', analyzeCommits: './shareable.json'}
|
|
)).thenResolve(pluginsConfig);
|
|
|
|
const result = await t.context.getConfig({cwd});
|
|
|
|
// Verify the options contains the plugin config from shareable.json
|
|
t.deepEqual(result, {options: expectedOptions, plugins: pluginsConfig});
|
|
});
|
|
|
|
test('Throw an Error if one of the shareable config cannot be found', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {extends: ['./shareable1.json', 'non-existing-path']};
|
|
const options1 = {analyzeCommits: 'analyzeCommits'};
|
|
// Create package.json and shareable.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'shareable1.json'), options1);
|
|
|
|
await t.throwsAsync(t.context.getConfig({cwd}), {
|
|
message: /Cannot find module 'non-existing-path'/,
|
|
code: 'MODULE_NOT_FOUND',
|
|
});
|
|
});
|
|
|
|
test('Convert "ci" option to "noCi" when set from extended config', async (t) => {
|
|
// Create a git repository, set the current working directory at the root of the repo
|
|
const {cwd} = await gitRepo();
|
|
const pkgOptions = {extends: './no-ci.json'};
|
|
const options = {
|
|
ci: false,
|
|
};
|
|
// Create package.json and shareable.json in repository root
|
|
await outputJson(path.resolve(cwd, 'package.json'), {release: pkgOptions});
|
|
await outputJson(path.resolve(cwd, 'no-ci.json'), options);
|
|
|
|
const {options: result} = await t.context.getConfig({cwd});
|
|
|
|
t.is(result.ci, false);
|
|
t.is(result.noCi, true);
|
|
});
|