feat: support multiple branches and distribution channels

- Allow to configure multiple branches to release from
- Allow to define a distribution channel associated with each branch
- Manage the availability on distribution channels based on git merges
- Support regular releases, maintenance releases and pre-releases
- Add the `addChannel` plugin step to make an existing release available on a different distribution channel

BREAKING CHANGE: the `branch` option has been removed in favor of `branches`

The new `branches` option expect either an Array or a single branch definition. To migrate your configuration:
- If you want to publish package from multiple branches, please the configuration documentation
- If you use the default configuration and want to publish only from `master`: nothing to change
- If you use the `branch` configuration and want to publish only from one branch: replace `branch` by `branches` (`"branch": "my-release-branch"` => `"branches": "my-release-branch"`)
This commit is contained in:
Pierre Vanduynslager
2018-11-29 14:13:03 -05:00
parent 7a9922a492
commit 7b4052470b
50 changed files with 4069 additions and 516 deletions
+70 -2
View File
@@ -1,4 +1,5 @@
const {isFunction} = require('lodash');
const {isFunction, union, template} = require('lodash');
const semver = require('semver');
const hideSensitive = require('./hide-sensitive');
function extractErrors(err) {
@@ -17,4 +18,71 @@ function hideSensitiveValues(env, objs) {
});
}
module.exports = {extractErrors, hideSensitiveValues};
function tagsToVersions(tags) {
return tags.map(({version}) => version);
}
function isMajorRange(range) {
return /^\d\.x(?:\.x)?$/i.test(range);
}
function isMaintenanceRange(range) {
return /^\d\.[\dx](?:\.x)?$/i.test(range);
}
function getUpperBound(range) {
return semver.valid(range) ? range : ((semver.validRange(range) || '').match(/<(\d\.\d\.\d)$/) || [])[1];
}
function getLowerBound(range) {
return ((semver.validRange(range) || '').match(/(\d\.\d\.\d)/) || [])[1];
}
function highest(version1, version2) {
return version1 && version2 ? (semver.gt(version1, version2) ? version1 : version2) : version1 || version2;
}
function lowest(version1, version2) {
return version1 && version2 ? (semver.lt(version1, version2) ? version1 : version2) : version1 || version2;
}
function getLatestVersion(versions, {withPrerelease} = {}) {
return versions.filter(version => withPrerelease || !semver.prerelease(version)).sort(semver.rcompare)[0];
}
function getEarliestVersion(versions, {withPrerelease} = {}) {
return versions.filter(version => withPrerelease || !semver.prerelease(version)).sort(semver.compare)[0];
}
function getFirstVersion(versions, lowerBranches) {
const lowerVersion = union(...lowerBranches.map(({tags}) => tagsToVersions(tags))).sort(semver.rcompare);
if (lowerVersion[0]) {
return versions.sort(semver.compare).find(version => semver.gt(version, lowerVersion[0]));
}
return getEarliestVersion(versions);
}
function getRange(min, max) {
return `>=${min}${max ? ` <${max}` : ''}`;
}
function makeTag(tagFormat, version, channel) {
return template(tagFormat)({version: `${version}${channel ? `@${channel}` : ''}`});
}
module.exports = {
extractErrors,
hideSensitiveValues,
tagsToVersions,
isMajorRange,
isMaintenanceRange,
getUpperBound,
getLowerBound,
highest,
lowest,
getLatestVersion,
getEarliestVersion,
getFirstVersion,
getRange,
makeTag,
};