8000 feat: add additional release links to the release · Chumper/github@162d9af · GitHub
[go: up one dir, main page]

Skip to content

Commit 162d9af

Browse files
author
Nils Plaschke
committed
feat: add additional release links to the release
A new option `addReleases` has been added. Setting this option will instruct the plugin to append all additional releases to the Github release. The option can be one of `false|top|bottom` and the releases are appended to the top or bottom of the releases depending on the option. The default is `false` to be backward compatible. Closes semantic-release#281
1 parent 32654fb commit 162d9af

10 files changed

+385
-5
lines changed

README.md

Lines changed: 8 additions & 0 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,11 @@ Each label name is generated with [Lodash template](https://lodash.com/docs#temp
204204
The `releasedLabels` ```['released<%= nextRelease.channel ? ` on @\${nextRelease.channel}` : "" %> from <%= branch.name %>']``` will generate the label:
205205

206206
> released on @next from branch next
207+
208+
#### addReleases
209+
210+
This is boolean value that will append all releases except the github release to the top of the github releases.
211+
212+
##### addReleases example
213+
214+
See [The introducing PR](https://github.com/semantic-release/github/pull/282) for an example on how it will look.

lib/definitions/errors.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ Your configuration for the \`assignees\` option is \`${stringify(assignees)}\`.`
5757
)}) if defined, must be an \`Array\` of non empty \`String\`.
5858
5959
Your configuration for the \`releasedLabels\` option is \`${stringify(releasedLabels)}\`.`,
60+
}),
61+
EINVALIDADDRELEASES: ({addReleases}) => ({
62+
message: 'Invalid `addReleases` option.',
63+
details: `The [addReleases option](${linkify('README.md#options')}) if defined, must be a \`Boolean\`.
64+
65+
Your configuration for the \`addReleases\` option is \`${stringify(addReleases)}\`.`,
6066
}),
6167
EINVALIDGITHUBURL: () => ({
6268
message: 'The git repository URL is not a valid GitHub URL.',

lib/get-release-links.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const {RELEASE_NAME} = require('./definitions/constants');
2+
3+
const linkify = (releaseInfo) =>
4+
`${
5+
releaseInfo.url
6+
? releaseInfo.url.startsWith('http')
7+
? `[${releaseInfo.name}](${releaseInfo.url})`
8+
: `${releaseInfo.name}: \`${releaseInfo.url}\``
9+
: `\`${releaseInfo.name}\``
10+
}`;
11+
12+
const filterReleases = (releaseInfos) =>
13+
releaseInfos.filter((releaseInfo) => releaseInfo.name && releaseInfo.name !== RELEASE_NAME);
14+
15+
module.exports = (releaseInfos) =>
16+
`${
17+
filterReleases(releaseInfos).length > 0
18+
? `This release is also available on:\n${filterReleases(releaseInfos)
19+
.map((releaseInfo) => `- ${linkify(releaseInfo)}`)
20+
.join('\n')}\n---\n`
21+
: ''
22+
}`;

lib/publish.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ module.exports = async (pluginConfig, context) => {
2828
// When there are no assets, we publish a release directly
2929
if (!assets || assets.length === 0) {
3030
const {
31-
data: {html_url: url},
31+
data: {html_url: url, id: releaseId},
3232
} = await github.repos.createRelease(release);
3333

3434
logger.log('Published GitHub release: %s', url);
35-
return {url, name: RELEASE_NAME};
35+
return {url, name: RELEASE_NAME, id: releaseId};
3636
}
3737

3838
// We'll create a draft release, append the assets to it, and then publish it.
@@ -94,5 +94,5 @@ module.exports = async (pluginConfig, context) => {
9494
} = await github.repos.updateRelease({owner, repo, release_id: releaseId, draft: false});
9595

9696
logger.log('Published GitHub release: %s', url);
97-
return {url, name: RELEASE_NAME};
97+
return {url, name: RELEASE_NAME, id: releaseId};
9898
};

lib/resolve-config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = (
1212
labels,
1313
assignees,
1414
releasedLabels,
15+
addReleases,
1516
},
1617
{env}
1718
) => ({
@@ -30,4 +31,5 @@ module.exports = (
3031
: releasedLabels === false
3132
? false
3233
: castArray(releasedLabels),
34+
addReleases: isNil(addReleases) ? false : addReleases,
3335
});

lib/success.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const {isNil, uniqBy, template, flatten} = require('lodash');
1+
const {isNil, uniqBy, template, flatten, isEmpty} = require('lodash');
22
const pFilter = require('p-filter');
33
const AggregateError = require('aggregate-error');
44
const issueParser = require('issue-parser');
@@ -9,6 +9,8 @@ const getClient = require('./get-client');
99
const getSearchQueries = require('./get-search-queries');
1010
const getSuccessComment = require('./get-success-comment');
1111
const findSRIssues = require('./find-sr-issues');
12+
const {RELEASE_NAME} = require('./definitions/constants');
13+
const getReleaseLinks = require('./get-release-links');
1214

1315
module.exports = async (pluginConfig, context) => {
1416
const {
@@ -17,6 +19,7 @@ module.exports = async (pluginConfig, context) => {
1719
nextRelease,
1820
releases,
1921
logger,
22+
notes,
2023
} = context;
2124
const {
2225
githubToken,
@@ -27,6 +30,7 @@ module.exports = async (pluginConfig, context) => {
2730
failComment,
2831
failTitle,
2932
releasedLabels,
33+
addReleases,
3034
} = resolveConfig(pluginConfig, context);
3135

3236
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
@@ -140,6 +144,17 @@ module.exports = async (pluginConfig, context) => {
140144
);
141145
}
142146

147+
if (addReleases === true && errors.length === 0) {
148+
const ghRelease = releases.find((release) => release.name && release.name === RELEASE_NAME);
149+
if (!isNil(ghRelease)) {
150+
const ghRelaseId = ghRelease.id;
151+
const additionalReleases = getReleaseLinks(releases);
152+
if (!isEmpty(additionalReleases) && !isNil(ghRelaseId)) {
153+
await github.repos.updateRelease({owner, repo, release_id: ghRelaseId, body: additionalReleases.concat(notes)});
154+
}
155+
}
156+
}
157+
143158
if (errors.length > 0) {
144159
throw new AggregateError(errors);
145160
}

lib/verify.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const {isString, isPlainObject, isNil, isArray, isNumber} = require('lodash');
1+
const {isString, isPlainObject, isNil, isArray, isNumber, isBoolean} = require('lodash');
22
const urlJoin = require('url-join');
33
const AggregateError = require('aggregate-error');
44
const parseGithubUrl = require('./parse-github-url');
@@ -7,6 +7,7 @@ const getClient = require('./get-client');
77
const getError = require('./get-error');
88

99
const isNonEmptyString = (value) => isString(value) && value.trim();
10+
const isEnabled = (value) => isBoolean(value);
1011
const isStringOrStringArray = (value) =>
1112
isNonEmptyString(value) || (isArray(value) && value.every((string) => isNonEmptyString(string)));
1213
const isArrayOf = (validator) => (array) => isArray(array) && array.every((value) => validator(value));
@@ -24,6 +25,7 @@ const VALIDATORS = {
2425
labels: canBeDisabled(isArrayOf(isNonEmptyString)),
2526
assignees: isArrayOf(isNonEmptyString),
2627
releasedLabels: canBeDisabled(isArrayOf(isNonEmptyString)),
28+
addReleases: isEnabled,
2729
};
2830

2931
module.exports = async (pluginConfig, context) => {

test/get-release-links.test.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
const test = require('ava');
2+
const getReleaseLinks = require('../lib/get-release-links');
3+
const {RELEASE_NAME} = require('../lib/definitions/constants');
4+
5+
test('Comment for release with multiple releases', (t) => {
6+
const releaseInfos = [
7+
{name: RELEASE_NAME, url: 'https://github.com/release'},
8+
{name: 'Http release', url: 'https://release.com/release'},
9+
{name: 'npm release', url: 'https://npm.com/release'},
10+
];
11+
const comment = getReleaseLinks(releaseInfos);
12+
13+
t.is(
14+
comment,
15+
`This release is also available on:
16+
- [Http release](https://release.com/release)
17+
- [npm release](https://npm.com/release)
18+
---
19+
`
20+
);
21+
});
22+
23+
test('Release with missing release URL', (t) => {
24+
const releaseInfos = [
25+
{name: RELEASE_NAME, url: 'https://github.com/release'},
26+
{name: 'Http release', url: 'https://release.com/release'},
27+
{name: 'npm release'},
28+
];
29+
const comment = getReleaseLinks(releaseInfos);
30+
31+
t.is(
32+
comment,
33+
`This release is also available on:
34+
- [Http release](https://release.com/release)
35+
- \`npm release\`
36+
---
37+
`
38+
);
39+
});
40+
41+
test('Release with one release', (t) => {
42+
const releaseInfos = [
43+
{name: RELEASE_NAME, url: 'https://github.com/release'},
44+
{name: 'Http release', url: 'https://release.com/release'},
45+
];
46+
const comment = getReleaseLinks(releaseInfos);
47+
48+
t.is(
49+
comment,
50+
`This release is also available on:
51+
- [Http release](https://release.com/release)
52+
---
53+
`
54+
);
55+
});
56+
57+
test('Release with non http releases', (t) => {
58+
const releaseInfos = [{name: 'S3', url: 's3://my-bucket/release-asset'}];
59+
const comment = getReleaseLinks(releaseInfos);
60+
61+
t.is(
62+
comment,
63+
`This release is also available on:
64+
- S3: \`s3://my-bucket/release-asset\`
65+
---
66+
`
67+
);
68+
});
69+
70+
test('Release with only github release', (t) => {
71+
const releaseInfos = [{name: RELEASE_NAME, url: 'https://github.com/release'}];
72+
const comment = getReleaseLinks(releaseInfos);
73+
74+
t.is(comment, '');
75+
});
76+
77+
test('Comment with no release object', (t) => {
78+
const releaseInfos = [];
79+
const comment = getReleaseLinks(releaseInfos);
80+
81+
t.is(comment, '');
82+
});

0 commit comments

Comments
 (0)
0