mirror of
https://github.com/zhigang1992/release-drafter.git
synced 2026-01-12 09:33:38 +08:00
11
index.js
11
index.js
@@ -1,6 +1,6 @@
|
||||
const getConfig = require('probot-config')
|
||||
const { isTriggerableBranch } = require('./lib/triggerable-branch')
|
||||
const { findReleases, generateReleaseBody } = require('./lib/releases')
|
||||
const { findReleases, generateReleaseInfo } = require('./lib/releases')
|
||||
const { findCommits, findPullRequests } = require('./lib/commits')
|
||||
const log = require('./lib/log')
|
||||
|
||||
@@ -30,20 +30,21 @@ module.exports = app => {
|
||||
const { draftRelease, lastRelease } = await findReleases({ app, context })
|
||||
const commits = await findCommits({ app, context, branch, lastRelease })
|
||||
const mergedPullRequests = await findPullRequests({ app, context, commits })
|
||||
const body = generateReleaseBody({ commits, config, lastRelease, mergedPullRequests })
|
||||
const releaseInfo = generateReleaseInfo({ commits, config, lastRelease, mergedPullRequests })
|
||||
|
||||
if (!draftRelease) {
|
||||
log({ app, context, message: 'Creating new draft release' })
|
||||
await context.github.repos.createRelease(context.repo({
|
||||
tag_name: '',
|
||||
body: body,
|
||||
name: releaseInfo.name,
|
||||
tag_name: releaseInfo.tag,
|
||||
body: releaseInfo.body,
|
||||
draft: true
|
||||
}))
|
||||
} else {
|
||||
log({ app, context, message: 'Updating existing draft release' })
|
||||
await context.github.repos.editRelease(context.repo({
|
||||
release_id: draftRelease.id,
|
||||
body: body
|
||||
body: releaseInfo.body
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const compareVersions = require('compare-versions')
|
||||
|
||||
const { getVersionInfo } = require('./versions')
|
||||
const log = require('./log')
|
||||
|
||||
const UNCATEGORIZED = 'UNCATEGORIZED'
|
||||
@@ -92,7 +93,13 @@ const categorizePullRequests = (pullRequests, categories) => {
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.generateReleaseBody = ({ commits, config, lastRelease, mergedPullRequests }) => {
|
||||
const templateNextVersion = (template, nextVersions) => {
|
||||
return template.replace('$NEXT_MAJOR_VERSION', nextVersions.incrementedMajor)
|
||||
.replace('$NEXT_MINOR_VERSION', nextVersions.incrementedMinor)
|
||||
.replace('$NEXT_PATCH_VERSION', nextVersions.incrementedPatch);
|
||||
}
|
||||
|
||||
module.exports.generateReleaseInfo = ({ commits, config, lastRelease, mergedPullRequests }) => {
|
||||
let body = config.template
|
||||
const [categoriesConfig, orderedCategories] = getCategoriesConfig({ config })
|
||||
|
||||
@@ -130,5 +137,20 @@ module.exports.generateReleaseBody = ({ commits, config, lastRelease, mergedPull
|
||||
|
||||
body = body.replace('$CONTRIBUTORS', contributorsSentence({ commits, pullRequests: mergedPullRequests }))
|
||||
|
||||
return body
|
||||
let name = config['default-release-name'] || '';
|
||||
let tag = config['default-release-tag'] || '';
|
||||
if (lastRelease) {
|
||||
const versionInfo = getVersionInfo(lastRelease);
|
||||
if (versionInfo) {
|
||||
body = templateNextVersion(body, versionInfo);
|
||||
name = templateNextVersion(name, versionInfo);
|
||||
tag = templateNextVersion(tag, versionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
tag,
|
||||
body
|
||||
}
|
||||
}
|
||||
|
||||
29
lib/versions.js
Normal file
29
lib/versions.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const semverRegex = /(\d+)\.(\d+)\.(\d+)/;
|
||||
|
||||
module.exports.getVersionInfo = (lastRelease) => {
|
||||
const lastReleaseTag = lastRelease.tag_name;
|
||||
const lastReleaseName = lastRelease.name;
|
||||
|
||||
let lastReleaseMatch;
|
||||
lastReleaseMatch = lastReleaseTag.match(semverRegex);
|
||||
if (! lastReleaseMatch) {
|
||||
lastReleaseMatch = lastReleaseName.match(semverRegex);
|
||||
}
|
||||
|
||||
if (! lastReleaseMatch) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const major = (lastReleaseMatch[1] - 0);
|
||||
const minor = (lastReleaseMatch[2] - 0);
|
||||
const patch = (lastReleaseMatch[3] - 0);
|
||||
|
||||
return {
|
||||
major,
|
||||
minor,
|
||||
patch,
|
||||
incrementedMajor: `${major + 1}.0.0`,
|
||||
incrementedMinor: `${major}.${minor + 1}.0`,
|
||||
incrementedPatch: `${major}.${minor}.${patch + 1}`,
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"collectCoverage": true,
|
||||
"collectCoverage": false,
|
||||
"collectCoverageFrom": [
|
||||
"index.js",
|
||||
"lib/**"
|
||||
|
||||
3
test/fixtures/config-with-next-versioning.yml
vendored
Normal file
3
test/fixtures/config-with-next-versioning.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
template: Placeholder with example. Automatically calculated values are next major=$NEXT_MAJOR_VERSION, minor=$NEXT_MINOR_VERSION, patch=$NEXT_PATCH_VERSION
|
||||
default-release-name: "v$NEXT_PATCH_VERSION (Code name: Placeholder)"
|
||||
default-release-tag: v$NEXT_PATCH_VERSION
|
||||
@@ -142,6 +142,32 @@ Previous tag: ''
|
||||
)
|
||||
})
|
||||
|
||||
it('makes next versions available as template placeholders', async () => {
|
||||
github.repos.getContent = fn().mockReturnValueOnce(mockConfig('config-with-next-versioning.yml'))
|
||||
github.repos.getReleases = fn().mockReturnValueOnce(Promise.resolve({ data:
|
||||
[ require('./fixtures/release') ]
|
||||
}))
|
||||
github.repos.compareCommits = fn().mockReturnValueOnce(Promise.resolve({ data: {
|
||||
commits: require('./fixtures/commits')
|
||||
} }))
|
||||
github.pullRequests.get = fn()
|
||||
.mockReturnValueOnce(Promise.resolve(require('./fixtures/pull-request-1')))
|
||||
.mockReturnValueOnce(Promise.resolve(require('./fixtures/pull-request-2')))
|
||||
|
||||
github.repos.createRelease = fn()
|
||||
|
||||
await app.receive({ name: 'push', payload: require('./fixtures/push') })
|
||||
|
||||
expect(github.repos.createRelease).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
body: `Placeholder with example. Automatically calculated values are next major=3.0.0, minor=2.1.0, patch=2.0.1`,
|
||||
draft: true,
|
||||
name: 'v2.0.1 (Code name: Placeholder)',
|
||||
tag_name: 'v2.0.1'
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
describe('with custom changes-template config', () => {
|
||||
it('creates a new draft using the template', async () => {
|
||||
github.repos.getContent = fn().mockReturnValueOnce(mockConfig('config-with-changes-templates.yml'))
|
||||
|
||||
45
test/versions.test.js
Normal file
45
test/versions.test.js
Normal file
@@ -0,0 +1,45 @@
|
||||
const { getVersionInfo } = require('../lib/versions')
|
||||
|
||||
describe('versions', () => {
|
||||
it('extracts a version-like string from the last tag', () => {
|
||||
const versionInfo = getVersionInfo({
|
||||
tag_name: 'v10.0.3',
|
||||
name: 'Some release'
|
||||
});
|
||||
|
||||
expect(versionInfo.incrementedMajor).toEqual('11.0.0');
|
||||
expect(versionInfo.incrementedMinor).toEqual('10.1.0');
|
||||
expect(versionInfo.incrementedPatch).toEqual('10.0.4');
|
||||
})
|
||||
|
||||
it('extracts a version-like string from the last release name', () => {
|
||||
const versionInfo = getVersionInfo({
|
||||
tag_name: 'notaproperversion',
|
||||
name: '10.0.3'
|
||||
});
|
||||
|
||||
expect(versionInfo.incrementedMajor).toEqual('11.0.0');
|
||||
expect(versionInfo.incrementedMinor).toEqual('10.1.0');
|
||||
expect(versionInfo.incrementedPatch).toEqual('10.0.4');
|
||||
})
|
||||
|
||||
it('extracts a version-like string from the last tag instead of the release name, if conflicting', () => {
|
||||
const versionInfo = getVersionInfo({
|
||||
tag_name: '10.0.3',
|
||||
name: '8.1.0'
|
||||
});
|
||||
|
||||
expect(versionInfo.incrementedMajor).toEqual('11.0.0');
|
||||
expect(versionInfo.incrementedMinor).toEqual('10.1.0');
|
||||
expect(versionInfo.incrementedPatch).toEqual('10.0.4');
|
||||
})
|
||||
|
||||
it('gives up if a semver version-like string cannot be found in either tag or release name', () => {
|
||||
const versionInfo = getVersionInfo({
|
||||
tag_name: '10.0',
|
||||
name: 'not a proper version'
|
||||
});
|
||||
|
||||
expect(versionInfo).toEqual(undefined);
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user