release-it
Advanced tools
Comparing version 14.13.1 to 14.14.0
@@ -52,2 +52,3 @@ { | ||
"releaseNotes": null, | ||
"milestones": [], | ||
"tokenRef": "GITLAB_TOKEN", | ||
@@ -54,0 +55,0 @@ "tokenHeader": "Private-Token", |
@@ -110,2 +110,62 @@ const fs = require('fs'); | ||
async beforeRelease() { | ||
await super.beforeRelease(); | ||
await this.checkReleaseMilestones(); | ||
} | ||
async checkReleaseMilestones() { | ||
if (this.options.skipChecks) return; | ||
const releaseMilestones = this.getReleaseMilestones(); | ||
if (releaseMilestones.length < 1) { | ||
return; | ||
} | ||
this.log.exec(`gitlab releases#checkReleaseMilestones`); | ||
const { id } = this.getContext(); | ||
const endpoint = `projects/${id}/milestones`; | ||
const requests = releaseMilestones.map(milestone => { | ||
const options = { | ||
method: 'GET', | ||
searchParams: { | ||
title: milestone, | ||
include_parent_milestones: true | ||
} | ||
}; | ||
return this.request(endpoint, options).then(response => { | ||
if (!Array.isArray(response)) { | ||
const { baseUrl } = this.getContext(); | ||
throw new Error( | ||
`Unexpected response from ${baseUrl}/${endpoint}. Expected an array but got: ${JSON.stringify(response)}` | ||
); | ||
} | ||
if (response.length === 0) { | ||
const error = new Error(`Milestone '${milestone}' does not exist.`); | ||
this.log.warn(error.message); | ||
throw error; | ||
} | ||
this.log.verbose(`gitlab releases#checkReleaseMilestones: milestone '${milestone}' exists`); | ||
}); | ||
}); | ||
try { | ||
await Promise.allSettled(requests).then(results => { | ||
for (const result of results) { | ||
if (result.status === 'rejected') { | ||
throw e('Missing one or more milestones in GitLab. Creating a GitLab release will fail.', docs); | ||
} | ||
} | ||
}); | ||
} catch (err) { | ||
this.debug(err); | ||
throw err; | ||
} | ||
this.log.verbose('gitlab releases#checkReleaseMilestones: done'); | ||
} | ||
getReleaseMilestones() { | ||
const { milestones } = this.options; | ||
return (milestones || []).map(milestone => format(milestone, this.config.getContext())); | ||
} | ||
async release() { | ||
@@ -142,2 +202,3 @@ const glRelease = () => this.createRelease(); | ||
const releaseUrl = `${origin}/${repo.repository}/-/releases`; | ||
const releaseMilestones = this.getReleaseMilestones(); | ||
@@ -166,2 +227,6 @@ this.log.exec(`gitlab releases#createRelease "${name}" (${tagName})`, { isDryRun }); | ||
if (releaseMilestones.length) { | ||
options.json.milestones = releaseMilestones; | ||
} | ||
try { | ||
@@ -168,0 +233,0 @@ await this.request(endpoint, options); |
{ | ||
"name": "release-it", | ||
"version": "14.13.1", | ||
"version": "14.14.0", | ||
"description": "Generic CLI tool to automate versioning and package publishing related tasks.", | ||
@@ -63,3 +63,3 @@ "keywords": [ | ||
"cosmiconfig": "7.0.1", | ||
"debug": "4.3.3", | ||
"debug": "4.3.4", | ||
"execa": "5.1.1", | ||
@@ -71,6 +71,6 @@ "form-data": "4.0.0", | ||
"import-cwd": "3.0.0", | ||
"inquirer": "8.2.0", | ||
"inquirer": "8.2.2", | ||
"is-ci": "3.0.1", | ||
"lodash": "4.17.21", | ||
"mime-types": "2.1.34", | ||
"mime-types": "2.1.35", | ||
"new-github-release-url": "1.0.0", | ||
@@ -93,4 +93,4 @@ "open": "7.4.2", | ||
"ava": "3.15.0", | ||
"eslint": "8.7.0", | ||
"eslint-config-prettier": "8.3.0", | ||
"eslint": "8.12.0", | ||
"eslint-config-prettier": "8.5.0", | ||
"eslint-plugin-ava": "13.2.0", | ||
@@ -102,7 +102,7 @@ "eslint-plugin-import": "2.25.4", | ||
"mock-stdio": "1.0.3", | ||
"nock": "13.2.2", | ||
"nock": "13.2.4", | ||
"node-fetch": "2.6.7", | ||
"prettier": "2.5.1", | ||
"prettier": "2.6.1", | ||
"proxyquire": "2.1.3", | ||
"sinon": "12.0.1", | ||
"sinon": "13.0.1", | ||
"strip-ansi": "6.0.0" | ||
@@ -109,0 +109,0 @@ }, |
@@ -217,3 +217,3 @@ const test = require('ava'); | ||
test('should release to alternative host and proxy', async t => { | ||
const remote = { api: 'https://my-custom-host.org/api/v3', host: 'my-custom-host.org' }; | ||
const remote = { api: 'https://custom.example.org/api/v3', host: 'custom.example.org' }; | ||
interceptAuthentication(remote); | ||
@@ -226,4 +226,4 @@ interceptCollaborator(remote); | ||
tokenRef, | ||
pushRepo: `git://my-custom-host.org:user/repo`, | ||
host: 'my-custom-host.org', | ||
pushRepo: `git://custom.example.org:user/repo`, | ||
host: 'custom.example.org', | ||
proxy: 'http://proxy:8080' | ||
@@ -240,3 +240,3 @@ } | ||
t.true(isReleased); | ||
t.is(releaseUrl, `https://my-custom-host.org/user/repo/releases/tag/1.0.1`); | ||
t.is(releaseUrl, `https://custom.example.org/user/repo/releases/tag/1.0.1`); | ||
exec.restore(); | ||
@@ -246,3 +246,3 @@ }); | ||
test('should release to git.pushRepo', async t => { | ||
const remote = { api: 'https://my-custom-host.org/api/v3', host: 'my-custom-host.org' }; | ||
const remote = { api: 'https://custom.example.org/api/v3', host: 'custom.example.org' }; | ||
interceptCreate(Object.assign({ body: { tag_name: '1.0.1' } }, remote)); | ||
@@ -253,3 +253,3 @@ const options = { git: { pushRepo: 'upstream', changelog: '' }, github: { tokenRef, skipChecks: true } }; | ||
exec.withArgs('git describe --tags --match=* --abbrev=0').resolves('1.0.0'); | ||
exec.withArgs('git remote get-url upstream').resolves('https://my-custom-host.org/user/repo'); | ||
exec.withArgs('git remote get-url upstream').resolves('https://custom.example.org/user/repo'); | ||
@@ -260,3 +260,3 @@ await runTasks(github); | ||
t.true(isReleased); | ||
t.is(releaseUrl, 'https://my-custom-host.org/user/repo/releases/tag/1.0.1'); | ||
t.is(releaseUrl, 'https://custom.example.org/user/repo/releases/tag/1.0.1'); | ||
exec.restore(); | ||
@@ -394,6 +394,6 @@ }); | ||
github: { | ||
pushRepo: 'git://my-custom-host.org:user/repo', | ||
pushRepo: 'git://custom.example.org:user/repo', | ||
release: true, | ||
web: true, | ||
host: 'my-custom-host.org', | ||
host: 'custom.example.org', | ||
releaseName: 'The Launch', | ||
@@ -413,5 +413,5 @@ releaseNotes: 'echo It happened' | ||
releaseUrl, | ||
'https://my-custom-host.org/user/repo/releases/new?tag=2.0.2&title=The+Launch&body=It+happened&prerelease=false' | ||
'https://custom.example.org/user/repo/releases/new?tag=2.0.2&title=The+Launch&body=It+happened&prerelease=false' | ||
); | ||
exec.restore(); | ||
}); |
@@ -10,3 +10,4 @@ const test = require('ava'); | ||
interceptPublish, | ||
interceptAsset | ||
interceptAsset, | ||
interceptMilestones | ||
} = require('./stub/gitlab'); | ||
@@ -59,3 +60,4 @@ const { factory, runTasks } = require('./util'); | ||
releaseNotes: 'echo Custom notes', | ||
assets: 'test/resources/file-v${version}.txt' | ||
assets: 'test/resources/file-v${version}.txt', | ||
milestones: ['${version}', '${latestVersion} UAT'] | ||
} | ||
@@ -68,2 +70,22 @@ }; | ||
interceptCollaborator(); | ||
interceptMilestones({ | ||
query: { title: '2.0.1' }, | ||
milestones: [ | ||
{ | ||
id: 17, | ||
iid: 3, | ||
title: '2.0.1' | ||
} | ||
] | ||
}); | ||
interceptMilestones({ | ||
query: { title: '2.0.0 UAT' }, | ||
milestones: [ | ||
{ | ||
id: 42, | ||
iid: 4, | ||
title: '2.0.0 UAT' | ||
} | ||
] | ||
}); | ||
interceptAsset(); | ||
@@ -82,3 +104,4 @@ interceptPublish({ | ||
] | ||
} | ||
}, | ||
milestones: ['2.0.1', '2.0.0 UAT'] | ||
} | ||
@@ -95,2 +118,37 @@ }); | ||
test.serial('should throw when release milestone is missing', async t => { | ||
const pushRepo = 'https://gitlab.com/user/repo'; | ||
const options = { | ||
git: { pushRepo }, | ||
gitlab: { | ||
tokenRef, | ||
release: true, | ||
milestones: ['${version}', '${latestVersion} UAT'] | ||
} | ||
}; | ||
const gitlab = factory(GitLab, { options }); | ||
sinon.stub(gitlab, 'getLatestVersion').resolves('2.0.0'); | ||
interceptUser(); | ||
interceptCollaborator(); | ||
interceptMilestones({ | ||
query: { title: '2.0.1' }, | ||
milestones: [ | ||
{ | ||
id: 17, | ||
iid: 3, | ||
title: '2.0.1' | ||
} | ||
] | ||
}); | ||
interceptMilestones({ | ||
query: { title: '2.0.0 UAT' }, | ||
milestones: [] | ||
}); | ||
await t.throwsAsync(runTasks(gitlab), { | ||
message: /^Missing one or more milestones in GitLab. Creating a GitLab release will fail./ | ||
}); | ||
}); | ||
test.serial('should release to self-managed host', async t => { | ||
@@ -203,5 +261,12 @@ const host = 'https://gitlab.example.org'; | ||
test('should skip checks', async t => { | ||
const options = { gitlab: { tokenRef, skipChecks: true } }; | ||
const options = { gitlab: { tokenRef, skipChecks: true, release: true, milestones: ['v1.0.0'] } }; | ||
const gitlab = factory(GitLab, { options }); | ||
const spy = sinon.spy(gitlab, 'client', ['get']); | ||
await t.notThrowsAsync(gitlab.init()); | ||
await t.notThrowsAsync(gitlab.beforeRelease()); | ||
t.is(spy.get.callCount, 0); | ||
t.is(gitlab.log.exec.args.filter(entry => /checkReleaseMilestones/.test(entry[0])).length, 0); | ||
}); |
@@ -16,5 +16,5 @@ const path = require('path'); | ||
test('should return npm package url (custom registry)', t => { | ||
const options = { npm: { name: 'my-cool-package', publishConfig: { registry: 'https://my-registry.com/' } } }; | ||
const options = { npm: { name: 'my-cool-package', publishConfig: { registry: 'https://registry.example.org/' } } }; | ||
const npmClient = factory(npm, { options }); | ||
t.is(npmClient.getPackageUrl(), 'https://my-registry.com/package/my-cool-package'); | ||
t.is(npmClient.getPackageUrl(), 'https://registry.example.org/package/my-cool-package'); | ||
}); | ||
@@ -21,0 +21,0 @@ |
@@ -22,2 +22,18 @@ const nock = require('nock'); | ||
module.exports.interceptMilestones = ( | ||
{ host = 'https://gitlab.com', owner = 'user', project = 'repo', query = {}, milestones = [] } = {}, | ||
options | ||
) => | ||
nock(host, options) | ||
.get(`/api/v4/projects/${owner}%2F${project}/milestones`) | ||
.query( | ||
Object.assign( | ||
{ | ||
include_parent_milestones: true | ||
}, | ||
query | ||
) | ||
) | ||
.reply(200, JSON.stringify(milestones)); | ||
module.exports.interceptPublish = ( | ||
@@ -24,0 +40,0 @@ { host = 'https://gitlab.com', owner = 'user', project = 'repo', body } = {}, |
@@ -361,3 +361,3 @@ const path = require('path'); | ||
const pkgName = path.basename(target); | ||
const registry = 'https://my-registry.com'; | ||
const registry = 'https://my-registry.example.org'; | ||
@@ -364,0 +364,0 @@ gitAdd( |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
215276
5175
+ Addeddebug@4.3.4(transitive)
+ Addedinquirer@8.2.2(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
- Removeddebug@4.3.3(transitive)
- Removedinquirer@8.2.0(transitive)
- Removedmime-db@1.51.0(transitive)
- Removedmime-types@2.1.34(transitive)
Updateddebug@4.3.4
Updatedinquirer@8.2.2
Updatedmime-types@2.1.35