feat: allow to release any version on a branch if up to date with next branch
This commit is contained in:
		
							parent
							
								
									534c0dbc89
								
							
						
					
					
						commit
						916c2685c5
					
				| @ -100,7 +100,7 @@ For example the configuration `['master', {name: 'pre/rc', prerelease: '${name.r | |||||||
| 
 | 
 | ||||||
| ### Release branches | ### Release branches | ||||||
| 
 | 
 | ||||||
| A release branch is the base type of branch used by **semantic-release** that allows to publish releases with a [semantic version](https://semver.org), optionally on a specific distribution channel. Distribution channels (for example [npm dist-tags](https://docs.npmjs.com/cli/dist-tag) or [Chrome release channels](https://www.chromium.org/getting-involved/dev-channel)) are a way to distribute new releases only to a subset of users in order to get early feedback. Later on those releases can be added to the general distribution channel to be made available to all users. | A release branch is the base type of branch used by **semantic-release** that allows to publish releases with a [semantic version](https://semver.org), optionally on a specific distribution channel. Distribution channels (for example [npm dist-tags](https://docs.npmjs.com/cli/dist-tag) or [Chrome release channels](https://www.chromium.org/getting-involved/dev-channel)) are a way to distribute new releases only to a subset of users in order to get early feedback. Later on, those releases can be added to the general distribution channel to be made available to all users. | ||||||
| 
 | 
 | ||||||
| **semantic-release** will automatically add releases to the corresponding distribution channel when code is [merged from a release branch to another](#merging-into-a-release-branch). | **semantic-release** will automatically add releases to the corresponding distribution channel when code is [merged from a release branch to another](#merging-into-a-release-branch). | ||||||
| 
 | 
 | ||||||
| @ -112,20 +112,17 @@ See [publishing on distribution channels recipe](../recipes/distribution-channel | |||||||
| 
 | 
 | ||||||
| #### Pushing to a release branch | #### Pushing to a release branch | ||||||
| 
 | 
 | ||||||
| With the configuration `"branches": ["master", "next"]`, if the last release published from `master` is `1.0.0` then: | With the configuration `"branches": ["master", "next"]`, if the last release published from `master` is `1.0.0` and the last one from `next` is `2.0.0` then: | ||||||
| - Only versions in range `1.x.x` can be published from `master`, so only `fix` and `feat` commits can be pushed to `master` | - Only versions in range `1.x.x` can be published from `master`, so only `fix` and `feat` commits can be pushed to `master` | ||||||
| - Only versions in range `>=2.0.0` release can be published from `next`, so a `BREAKING CHANGE` commit must be pushed first on `next` and can be followed by any type of commits | - Once `next` get merged into `master` the release `2.0.0` will be made available on the channel associated with `master` and both `master` and `next` will accept any commit type | ||||||
| 
 | 
 | ||||||
| With the configuration `"branches": ["master", "next", "next-major"]`, if the last release published from `master` is `1.0.0` then: | This verification prevent scenario such as: | ||||||
| - Only versions in range `1.0.x` can be published from `master`, so only `fix` commits can be pushed to `master` | 1. Create a `feat` commit on `next` which triggers the release of version `1.0.0` on the `next` channel | ||||||
| - Only versions in range `>=1.1.0` can be published from `next`, so a `feat` commit must be pushed first on `next` and can be followed by `fix` and `feat` commits |  | ||||||
| - Only versions in range `>=2.0.0` release can be published from `next`, so a `BREAKING CHANGE` commit must be pushed first on `next-major` and can be followed by any type of commits |  | ||||||
| 
 |  | ||||||
| Those verifications prevent situations such as: |  | ||||||
| 1. Create a `feat` commit on `next` which triggers the release of version `1.0.0` on channel `next` |  | ||||||
| 2. Merge `next` into `master` which adds `1.0.0` on the default channel | 2. Merge `next` into `master` which adds `1.0.0` on the default channel | ||||||
| 3. Push a `fix` commit to `master` which triggers the release of version `1.0.1` on the default channel | 3. Create a `feat` commit on `next` which triggers the release of version `1.1.0` on the `next` channel | ||||||
| 4. Push a `fix` commit to `next` which would attempt to release the version `1.0.1` on channel `next` and fails as this version already exists | 4. Create a `feat` commit on `master` which would attempt to release the version `1.1.0` on the default channel | ||||||
|  | 
 | ||||||
|  | In step 4 **semantic-release** will throw an `EINVALIDNEXTVERSION` error to prevent the attempt at releasing version `1.1.0` which was already released on step 3 with a different codebase. The error will indicate that the commit should be created on `next` instead. Alternatively if the `next` branch is merged into `master`, the version `1.1.0` will be made available on the default channel and the `feat` commit would be allowed on `master` to release `1.2.0`. | ||||||
| 
 | 
 | ||||||
| #### Merging into a release branch | #### Merging into a release branch | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| const {sortBy, isNil} = require('lodash'); | const {sortBy, isNil} = require('lodash'); | ||||||
| const semver = require('semver'); |  | ||||||
| const semverDiff = require('semver-diff'); | const semverDiff = require('semver-diff'); | ||||||
| const {FIRST_RELEASE, RELEASE_TYPE} = require('../definitions/constants'); | const {FIRST_RELEASE, RELEASE_TYPE} = require('../definitions/constants'); | ||||||
| const { | const { | ||||||
| @ -61,35 +60,29 @@ function release({release}) { | |||||||
|     return release; |     return release; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const breakpoints = release.length > 2 ? ['minor', 'major'] : ['major']; |   // The intial lastVersion is the last release from the base branch of `FIRST_RELEASE` (1.0.0)
 | ||||||
| 
 |   let lastVersion = getLatestVersion(tagsToVersions(release[0].tags)) || FIRST_RELEASE; | ||||||
|   // The intial bound is the last release from the base branch of `FIRST_RELEASE` (1.0.0)
 |  | ||||||
|   let bound = getLatestVersion(tagsToVersions(release[0].tags)) || FIRST_RELEASE; |  | ||||||
| 
 | 
 | ||||||
|   return release.map(({name, tags, channel, ...rest}, idx) => { |   return release.map(({name, tags, channel, ...rest}, idx) => { | ||||||
|     const versions = tagsToVersions(tags); |     const versions = tagsToVersions(tags); | ||||||
|     // The lower bound is the highest version between the current branch last release and the previous branch upper bound (`bound`)
 |     // The new lastVersion is the highest version between the current branch last release and the previous branch lastVersion
 | ||||||
|     const min = highest(getLatestVersion(versions), bound); |     lastVersion = highest(getLatestVersion(versions), lastVersion); | ||||||
|     if (release.length - 1 === idx) { |     // The upper bound is:
 | ||||||
|       // If the current branch is the last one of the release branch, there is no upper bound
 |     //  - None if the current branch is the last one of the release branches
 | ||||||
|       bound = undefined; |     //  - Otherwise, The upper bound is the lowest version that is present on the current branch but none of the previous ones
 | ||||||
|     } else { |     const bound = | ||||||
|       // The default upper bound is the lower bound increment with the release type of the current branch position
 |       release.length - 1 === idx | ||||||
|       const upperBound = semver.inc(min, breakpoints[idx]); |         ? undefined | ||||||
|       // Find the lowest version that is present on the current branch but none of the previous ones
 |         : getFirstVersion(tagsToVersions(release[idx + 1].tags), release.slice(0, idx + 1)); | ||||||
|       const nextFirstVersion = getFirstVersion(tagsToVersions(release[idx + 1].tags), release.slice(0, idx + 1)); |  | ||||||
|       // The upper bound is the lowest version between `nextFirstVersion` and the default upper bound
 |  | ||||||
|       bound = lowest(nextFirstVersion, upperBound); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     const diff = bound ? semverDiff(min, bound) : null; |     const diff = bound ? semverDiff(lastVersion, bound) : null; | ||||||
|     return { |     return { | ||||||
|       ...rest, |       ...rest, | ||||||
|       channel: idx === 0 ? channel : isNil(channel) ? name : channel, |       channel: idx === 0 ? channel : isNil(channel) ? name : channel, | ||||||
|       tags, |       tags, | ||||||
|       type: 'release', |       type: 'release', | ||||||
|       name, |       name, | ||||||
|       range: getRange(min, bound), |       range: getRange(lastVersion, bound), | ||||||
|       accept: bound ? RELEASE_TYPE.slice(0, RELEASE_TYPE.indexOf(diff)) : RELEASE_TYPE, |       accept: bound ? RELEASE_TYPE.slice(0, RELEASE_TYPE.indexOf(diff)) : RELEASE_TYPE, | ||||||
|       main: idx === 0, |       main: idx === 0, | ||||||
|     }; |     }; | ||||||
|  | |||||||
| @ -30,9 +30,9 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, '1.0.x').range, '>=1.0.0 <1.0.0', 'Cannot release on 1.0.x before a releasing on master'); |   t.is(getBranch(result, '1.0.x').range, '>=1.0.0 <1.0.0', 'Cannot release on 1.0.x before a releasing on master'); | ||||||
|   t.is(getBranch(result, '1.x').range, '>=1.1.0 <1.0.0', 'Cannot release on 1.x before a releasing on master'); |   t.is(getBranch(result, '1.x').range, '>=1.1.0 <1.0.0', 'Cannot release on 1.x before a releasing on master'); | ||||||
|   t.is(getBranch(result, 'master').range, '>=1.0.0 <1.1.0', 'Can release only patch on master'); |   t.is(getBranch(result, 'master').range, '>=1.0.0'); | ||||||
|   t.is(getBranch(result, 'next').range, '>=1.1.0 <2.0.0', 'Can release only minor on next'); |   t.is(getBranch(result, 'next').range, '>=1.0.0'); | ||||||
|   t.is(getBranch(result, 'next-major').range, '>=2.0.0', 'Can release only major on next-major'); |   t.is(getBranch(result, 'next-major').range, '>=1.0.0'); | ||||||
| 
 | 
 | ||||||
|   release(branches, 'master', '1.0.0'); |   release(branches, 'master', '1.0.0'); | ||||||
|   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ |   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ | ||||||
| @ -41,14 +41,18 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, '1.0.x').range, '>=1.0.0 <1.0.0', 'Cannot release on 1.0.x before a releasing on master'); |   t.is(getBranch(result, '1.0.x').range, '>=1.0.0 <1.0.0', 'Cannot release on 1.0.x before a releasing on master'); | ||||||
|   t.is(getBranch(result, '1.x').range, '>=1.1.0 <1.0.0', 'Cannot release on 1.x before a releasing on master'); |   t.is(getBranch(result, '1.x').range, '>=1.1.0 <1.0.0', 'Cannot release on 1.x before a releasing on master'); | ||||||
|   t.is(getBranch(result, 'master').range, '>=1.0.0 <1.1.0', 'Can release only patch on master'); |   t.is(getBranch(result, 'master').range, '>=1.0.0'); | ||||||
|  |   t.is(getBranch(result, 'next').range, '>=1.0.0'); | ||||||
|  |   t.is(getBranch(result, 'next-major').range, '>=1.0.0'); | ||||||
| 
 | 
 | ||||||
|   release(branches, 'master', '1.0.1'); |   release(branches, 'master', '1.0.1'); | ||||||
|   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ |   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ | ||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'master').range, '>=1.0.1 <1.1.0', 'Can release only patch, > than 1.0.1 on master'); |   t.is(getBranch(result, 'master').range, '>=1.0.1', 'Can release only > than 1.0.1 on master'); | ||||||
|  |   t.is(getBranch(result, 'next').range, '>=1.0.1', 'Can release only > than 1.0.1 on next'); | ||||||
|  |   t.is(getBranch(result, 'next-major').range, '>=1.0.1', 'Can release only > than 1.0.1 on next-major'); | ||||||
| 
 | 
 | ||||||
|   merge(branches, 'master', 'next'); |   merge(branches, 'master', 'next'); | ||||||
|   merge(branches, 'master', 'next-major'); |   merge(branches, 'master', 'next-major'); | ||||||
| @ -56,9 +60,9 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'master').range, '>=1.0.1 <1.1.0', 'Can release only patch, > than 1.0.1 on master'); |   t.is(getBranch(result, 'master').range, '>=1.0.1', 'Can release only > than 1.0.1 on master'); | ||||||
|   t.is(getBranch(result, 'next').range, '>=1.1.0 <2.0.0', 'Can release only minor on next'); |   t.is(getBranch(result, 'next').range, '>=1.0.1', 'Can release only > than 1.0.1 on next'); | ||||||
|   t.is(getBranch(result, 'next-major').range, '>=2.0.0', 'Can release only major on next-major'); |   t.is(getBranch(result, 'next-major').range, '>=1.0.1', 'Can release only > than 1.0.1 on next-major'); | ||||||
| 
 | 
 | ||||||
|   release(branches, 'next', '1.1.0'); |   release(branches, 'next', '1.1.0'); | ||||||
|   release(branches, 'next', '1.1.1'); |   release(branches, 'next', '1.1.1'); | ||||||
| @ -66,7 +70,9 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'next').range, '>=1.1.1 <2.0.0', 'Can release only patch or minor, > than 1.1.0 on next'); |   t.is(getBranch(result, 'master').range, '>=1.0.1 <1.1.0', 'Can release only patch, > than 1.0.1 on master'); | ||||||
|  |   t.is(getBranch(result, 'next').range, '>=1.1.1', 'Can release only > than 1.1.1 on next'); | ||||||
|  |   t.is(getBranch(result, 'next-major').range, '>=1.1.1', 'Can release > than 1.1.1 on next-major'); | ||||||
| 
 | 
 | ||||||
|   release(branches, 'next-major', '2.0.0'); |   release(branches, 'next-major', '2.0.0'); | ||||||
|   release(branches, 'next-major', '2.0.1'); |   release(branches, 'next-major', '2.0.1'); | ||||||
| @ -74,6 +80,8 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|  |   t.is(getBranch(result, 'master').range, '>=1.0.1 <1.1.0', 'Can release only patch, > than 1.0.1 on master'); | ||||||
|  |   t.is(getBranch(result, 'next').range, '>=1.1.1 <2.0.0', 'Can release only patch or minor, > than 1.1.0 on next'); | ||||||
|   t.is(getBranch(result, 'next-major').range, '>=2.0.1', 'Can release any version, > than 2.0.1 on next-major'); |   t.is(getBranch(result, 'next-major').range, '>=2.0.1', 'Can release any version, > than 2.0.1 on next-major'); | ||||||
| 
 | 
 | ||||||
|   merge(branches, 'next-major', 'beta'); |   merge(branches, 'next-major', 'beta'); | ||||||
| @ -88,7 +96,6 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
| 
 | 
 | ||||||
|   merge(branches, 'master', '1.0.x'); |   merge(branches, 'master', '1.0.x'); | ||||||
|   merge(branches, 'master', '1.x'); |   merge(branches, 'master', '1.x'); | ||||||
|   release(branches, 'master', '1.0.1'); |  | ||||||
|   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ |   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ | ||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
| @ -121,8 +128,9 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'master').range, '>=1.1.1 <1.2.0', 'Can release only patch, > than 1.1.1 on master'); | 
 | ||||||
|   t.is(getBranch(result, 'next').range, '>=1.2.0 <2.0.0', 'Can release only patch or minor, > than 1.2.0 on next'); |   t.is(getBranch(result, 'master').range, '>=1.1.1', 'Can release only > than 1.1.1 on master'); | ||||||
|  |   t.is(getBranch(result, 'next').range, '>=1.1.1 <2.0.0', 'Can release only patch or minor, > than 1.1.1 on next'); | ||||||
|   t.is(getBranch(result, 'next-major').range, '>=2.0.1', 'Can release any version, > than 2.0.1 on next-major'); |   t.is(getBranch(result, 'next-major').range, '>=2.0.1', 'Can release any version, > than 2.0.1 on next-major'); | ||||||
|   t.is( |   t.is( | ||||||
|     getBranch(result, '1.0.x').range, |     getBranch(result, '1.0.x').range, | ||||||
| @ -136,7 +144,7 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'master').range, '>=1.1.1 <1.2.0', 'Can release only patch, > than 1.1.1 on master'); |   t.is(getBranch(result, 'master').range, '>=1.1.1', 'Can release only > than 1.1.1 on master'); | ||||||
|   t.is(getBranch(result, '1.0.x').range, '>=1.0.4 <1.1.0', 'Can release on 1.0.x only within range'); |   t.is(getBranch(result, '1.0.x').range, '>=1.0.4 <1.1.0', 'Can release on 1.0.x only within range'); | ||||||
|   t.is(getBranch(result, '1.x').range, '>=1.1.0 <1.1.0', 'Cannot release on 1.x before >= 2.0.0 is released on master'); |   t.is(getBranch(result, '1.x').range, '>=1.1.0 <1.1.0', 'Cannot release on 1.x before >= 2.0.0 is released on master'); | ||||||
| 
 | 
 | ||||||
| @ -145,7 +153,7 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'master').range, '>=1.1.1 <1.2.0', 'Can release only patch, > than 1.1.1 on master'); |   t.is(getBranch(result, 'master').range, '>=1.1.1', 'Can release only > than 1.1.1 on master'); | ||||||
|   t.is(getBranch(result, '1.0.x').range, '>=1.0.4 <1.1.0', 'Can release on 1.0.x only within range'); |   t.is(getBranch(result, '1.0.x').range, '>=1.0.4 <1.1.0', 'Can release on 1.0.x only within range'); | ||||||
|   t.is(getBranch(result, '1.x').range, '>=1.1.1 <1.1.1', 'Cannot release on 1.x before >= 2.0.0 is released on master'); |   t.is(getBranch(result, '1.x').range, '>=1.1.1 <1.1.1', 'Cannot release on 1.x before >= 2.0.0 is released on master'); | ||||||
| 
 | 
 | ||||||
| @ -155,19 +163,20 @@ test('Enforce ranges with branching release workflow', async t => { | |||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'master').range, '>=2.0.1 <2.1.0', 'Can release only patch, > than 2.0.1 on master'); |   t.is(getBranch(result, 'master').range, '>=2.0.1', 'Can release only > than 2.0.1 on master'); | ||||||
|   t.is(getBranch(result, 'next').range, '>=2.1.0 <3.0.0', 'Can release only minor on next'); |   t.is(getBranch(result, 'next').range, '>=2.0.1', 'Can release only > than 2.0.1 on next'); | ||||||
|   t.is(getBranch(result, 'next-major').range, '>=3.0.0', 'Can release only major on next-major'); |   t.is(getBranch(result, 'next-major').range, '>=2.0.1', 'Can release only > than 2.0.1 on next-major'); | ||||||
|   t.is(getBranch(result, '1.x').range, '>=1.1.1 <2.0.0', 'Can release on 1.x only within range'); |   t.is(getBranch(result, '1.x').range, '>=1.1.1 <2.0.0', 'Can release on 1.x only within range'); | ||||||
| 
 | 
 | ||||||
|   merge(branches, 'beta', 'master'); |   merge(branches, 'beta', 'master'); | ||||||
|  |   release(branches, 'master', '3.0.0'); | ||||||
|   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ |   result = (await getBranches('repositoryUrl', 'master', {options: {branches}})).map(({name, range}) => ({ | ||||||
|     name, |     name, | ||||||
|     range, |     range, | ||||||
|   })); |   })); | ||||||
|   t.is(getBranch(result, 'master').range, '>=2.0.1 <2.1.0', 'Can release only patch, > than 2.0.1 on master'); |   t.is(getBranch(result, 'master').range, '>=3.0.0', 'Can release only > than 3.0.0 on master'); | ||||||
|   t.is(getBranch(result, 'next').range, '>=2.1.0 <3.0.0', 'Can release only minor on next'); |   t.is(getBranch(result, 'next').range, '>=3.0.0', 'Can release only > than 3.0.0 on next'); | ||||||
|   t.is(getBranch(result, 'next-major').range, '>=3.0.0', 'Can release only major on next-major'); |   t.is(getBranch(result, 'next-major').range, '>=3.0.0', 'Can release only > than 3.0.0 on next-major'); | ||||||
| 
 | 
 | ||||||
|   branches.push({name: '1.1.x', tags: []}); |   branches.push({name: '1.1.x', tags: []}); | ||||||
|   merge(branches, '1.x', '1.1.x'); |   merge(branches, '1.x', '1.1.x'); | ||||||
|  | |||||||
| @ -159,19 +159,26 @@ test('Release branches - initial state', t => { | |||||||
|       .release({release}) |       .release({release}) | ||||||
|       .map(({type, name, range, accept, channel, main}) => ({type, name, range, accept, channel, main})), |       .map(({type, name, range, accept, channel, main}) => ({type, name, range, accept, channel, main})), | ||||||
|     [ |     [ | ||||||
|       {type: 'release', name: 'master', range: '>=1.0.0 <1.1.0', accept: ['patch'], channel: undefined, main: true}, |       { | ||||||
|  |         type: 'release', | ||||||
|  |         name: 'master', | ||||||
|  |         range: '>=1.0.0', | ||||||
|  |         accept: ['patch', 'minor', 'major'], | ||||||
|  |         channel: undefined, | ||||||
|  |         main: true, | ||||||
|  |       }, | ||||||
|       { |       { | ||||||
|         type: 'release', |         type: 'release', | ||||||
|         name: 'next', |         name: 'next', | ||||||
|         range: '>=1.1.0 <2.0.0', |         range: '>=1.0.0', | ||||||
|         accept: ['patch', 'minor'], |         accept: ['patch', 'minor', 'major'], | ||||||
|         channel: 'next', |         channel: 'next', | ||||||
|         main: false, |         main: false, | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         type: 'release', |         type: 'release', | ||||||
|         name: 'next-major', |         name: 'next-major', | ||||||
|         range: '>=2.0.0', |         range: '>=1.0.0', | ||||||
|         accept: ['patch', 'minor', 'major'], |         accept: ['patch', 'minor', 'major'], | ||||||
|         channel: 'next-major', |         channel: 'next-major', | ||||||
|         main: false, |         main: false, | ||||||
| @ -293,15 +300,15 @@ test('Release branches - Handle missing previous tags in branch history', t => { | |||||||
|       { |       { | ||||||
|         type: 'release', |         type: 'release', | ||||||
|         name: 'master', |         name: 'master', | ||||||
|         range: '>=2.0.0 <3.0.0', |         range: '>=2.0.0', | ||||||
|         accept: ['patch', 'minor'], |         accept: ['patch', 'minor', 'major'], | ||||||
|         channel: undefined, |         channel: undefined, | ||||||
|         main: true, |         main: true, | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         type: 'release', |         type: 'release', | ||||||
|         name: 'next', |         name: 'next', | ||||||
|         range: '>=3.0.0', |         range: '>=2.0.0', | ||||||
|         accept: ['patch', 'minor', 'major'], |         accept: ['patch', 'minor', 'major'], | ||||||
|         channel: 'next', |         channel: 'next', | ||||||
|         main: false, |         main: false, | ||||||
| @ -310,40 +317,7 @@ test('Release branches - Handle missing previous tags in branch history', t => { | |||||||
|   ); |   ); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test('Release branches - enforce release gaps after downstream merge', t => { | test('Release branches - limit releases on 2nd and 3rd branch based on 1st branch last release', t => { | ||||||
|   const release = [ |  | ||||||
|     {name: 'master', tags: toTags(['1.0.0', '1.1.0', '2.0.0'])}, |  | ||||||
|     {name: 'next', tags: toTags(['1.0.0', '1.1.0', '2.0.0'])}, |  | ||||||
|     {name: 'next-major', tags: toTags(['1.0.0', '1.1.0', '2.0.0'])}, |  | ||||||
|   ]; |  | ||||||
| 
 |  | ||||||
|   t.deepEqual( |  | ||||||
|     normalize |  | ||||||
|       .release({release}) |  | ||||||
|       .map(({type, name, range, accept, channel, main}) => ({type, name, range, accept, channel, main})), |  | ||||||
|     [ |  | ||||||
|       {type: 'release', name: 'master', range: '>=2.0.0 <2.1.0', accept: ['patch'], channel: undefined, main: true}, |  | ||||||
|       { |  | ||||||
|         type: 'release', |  | ||||||
|         name: 'next', |  | ||||||
|         range: '>=2.1.0 <3.0.0', |  | ||||||
|         accept: ['patch', 'minor'], |  | ||||||
|         channel: 'next', |  | ||||||
|         main: false, |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         type: 'release', |  | ||||||
|         name: 'next-major', |  | ||||||
|         range: '>=3.0.0', |  | ||||||
|         accept: ['patch', 'minor', 'major'], |  | ||||||
|         channel: 'next-major', |  | ||||||
|         main: false, |  | ||||||
|       }, |  | ||||||
|     ] |  | ||||||
|   ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test('Release branches - limit releases on 2nd and 3rd branche based on 1st branch last release', t => { |  | ||||||
|   const release = [ |   const release = [ | ||||||
|     {name: 'master', tags: toTags(['1.0.0', '1.1.0', '2.0.0', '3.0.0'])}, |     {name: 'master', tags: toTags(['1.0.0', '1.1.0', '2.0.0', '3.0.0'])}, | ||||||
|     {name: 'next', tags: toTags(['1.0.0', '1.1.0'])}, |     {name: 'next', tags: toTags(['1.0.0', '1.1.0'])}, | ||||||
| @ -355,19 +329,26 @@ test('Release branches - limit releases on 2nd and 3rd branche based on 1st bran | |||||||
|       .release({release}) |       .release({release}) | ||||||
|       .map(({type, name, range, accept, channel, main}) => ({type, name, range, accept, channel, main})), |       .map(({type, name, range, accept, channel, main}) => ({type, name, range, accept, channel, main})), | ||||||
|     [ |     [ | ||||||
|       {type: 'release', name: 'master', range: '>=3.0.0 <3.1.0', accept: ['patch'], channel: undefined, main: true}, |       { | ||||||
|  |         type: 'release', | ||||||
|  |         name: 'master', | ||||||
|  |         range: '>=3.0.0', | ||||||
|  |         accept: ['patch', 'minor', 'major'], | ||||||
|  |         channel: undefined, | ||||||
|  |         main: true, | ||||||
|  |       }, | ||||||
|       { |       { | ||||||
|         type: 'release', |         type: 'release', | ||||||
|         name: 'next', |         name: 'next', | ||||||
|         range: '>=3.1.0 <4.0.0', |         range: '>=3.0.0', | ||||||
|         accept: ['patch', 'minor'], |         accept: ['patch', 'minor', 'major'], | ||||||
|         channel: 'next', |         channel: 'next', | ||||||
|         main: false, |         main: false, | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         type: 'release', |         type: 'release', | ||||||
|         name: 'next-major', |         name: 'next-major', | ||||||
|         range: '>=4.0.0', |         range: '>=3.0.0', | ||||||
|         accept: ['patch', 'minor', 'major'], |         accept: ['patch', 'minor', 'major'], | ||||||
|         channel: 'next-major', |         channel: 'next-major', | ||||||
|         main: false, |         main: false, | ||||||
|  | |||||||
| @ -97,8 +97,8 @@ test('Plugins are called with expected values', async t => { | |||||||
|     { |     { | ||||||
|       channel: undefined, |       channel: undefined, | ||||||
|       name: 'master', |       name: 'master', | ||||||
|       range: '>=1.0.0 <2.0.0', |       range: '>=1.0.0', | ||||||
|       accept: ['patch', 'minor'], |       accept: ['patch', 'minor', 'major'], | ||||||
|       tags: [{channels: ['next'], gitTag: 'v1.0.0', version: '1.0.0'}], |       tags: [{channels: ['next'], gitTag: 'v1.0.0', version: '1.0.0'}], | ||||||
|       type: 'release', |       type: 'release', | ||||||
|       main: true, |       main: true, | ||||||
| @ -106,7 +106,7 @@ test('Plugins are called with expected values', async t => { | |||||||
|     { |     { | ||||||
|       channel: 'next', |       channel: 'next', | ||||||
|       name: 'next', |       name: 'next', | ||||||
|       range: '>=2.0.0', |       range: '>=1.0.0', | ||||||
|       accept: ['patch', 'minor', 'major'], |       accept: ['patch', 'minor', 'major'], | ||||||
|       tags: [{channels: ['next'], gitTag: 'v1.0.0', version: '1.0.0'}], |       tags: [{channels: ['next'], gitTag: 'v1.0.0', version: '1.0.0'}], | ||||||
|       type: 'release', |       type: 'release', | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user