Skip to content

Commit

Permalink
feat: add additional release links to the release
Browse files Browse the repository at this point in the history
A new option `addReleases` has been added.
Setting this option will add links to other releases
to the Github release body.

The option can be one of `false|"top"|"bottom"`.
The default is `false` to be backward compatible.

Closes #281
  • Loading branch information
Nils Plaschke committed Sep 7, 2020
1 parent 32654fb commit dea56d8
Show file tree
Hide file tree
Showing 10 changed files with 573 additions and 4 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,13 @@ Each label name is generated with [Lodash template](https://lodash.com/docs#temp
The `releasedLabels` ```['released<%= nextRelease.channel ? ` on @\${nextRelease.channel}` : "" %> from <%= branch.name %>']``` will generate the label:

> released on @next from branch next
#### addReleases

Add links to other releases to the GitHub release body.

Valid values for this option are `false`, `"top"` or `"bottom"`.

##### addReleases example

See [The introducing PR](https://github.com/semantic-release/github/pull/282) for an example on how it will look.
6 changes: 6 additions & 0 deletions lib/definitions/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ Your configuration for the \`assignees\` option is \`${stringify(assignees)}\`.`
)}) if defined, must be an \`Array\` of non empty \`String\`.
Your configuration for the \`releasedLabels\` option is \`${stringify(releasedLabels)}\`.`,
}),
EINVALIDADDRELEASES: ({addReleases}) => ({
message: 'Invalid `addReleases` option.',
details: `The [addReleases option](${linkify('README.md#options')}) if defined, must be one of \`false|top|bottom\`.
Your configuration for the \`addReleases\` option is \`${stringify(addReleases)}\`.`,
}),
EINVALIDGITHUBURL: () => ({
message: 'The git repository URL is not a valid GitHub URL.',
Expand Down
22 changes: 22 additions & 0 deletions lib/get-release-links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const {RELEASE_NAME} = require('./definitions/constants');

const linkify = (releaseInfo) =>
`${
releaseInfo.url
? releaseInfo.url.startsWith('http')
? `[${releaseInfo.name}](${releaseInfo.url})`
: `${releaseInfo.name}: \`${releaseInfo.url}\``
: `\`${releaseInfo.name}\``
}`;

const filterReleases = (releaseInfos) =>
releaseInfos.filter((releaseInfo) => releaseInfo.name && releaseInfo.name !== RELEASE_NAME);

module.exports = (releaseInfos) =>
`${
filterReleases(releaseInfos).length > 0
? `This release is also available on:\n${filterReleases(releaseInfos)
.map((releaseInfo) => `- ${linkify(releaseInfo)}`)
.join('\n')}`
: ''
}`;
6 changes: 3 additions & 3 deletions lib/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ module.exports = async (pluginConfig, context) => {
// When there are no assets, we publish a release directly
if (!assets || assets.length === 0) {
const {
data: {html_url: url},
data: {html_url: url, id: releaseId},
} = await github.repos.createRelease(release);

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

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

logger.log('Published GitHub release: %s', url);
return {url, name: RELEASE_NAME};
return {url, name: RELEASE_NAME, id: releaseId};
};
2 changes: 2 additions & 0 deletions lib/resolve-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = (
labels,
assignees,
releasedLabels,
addReleases,
},
{env}
) => ({
Expand All @@ -30,4 +31,5 @@ module.exports = (
: releasedLabels === false
? false
: castArray(releasedLabels),
addReleases: isNil(addReleases) ? false : addReleases,
});
21 changes: 20 additions & 1 deletion lib/success.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {isNil, uniqBy, template, flatten} = require('lodash');
const {isNil, uniqBy, template, flatten, isEmpty} = require('lodash');
const pFilter = require('p-filter');
const AggregateError = require('aggregate-error');
const issueParser = require('issue-parser');
Expand All @@ -9,6 +9,8 @@ const getClient = require('./get-client');
const getSearchQueries = require('./get-search-queries');
const getSuccessComment = require('./get-success-comment');
const findSRIssues = require('./find-sr-issues');
const {RELEASE_NAME} = require('./definitions/constants');
const getReleaseLinks = require('./get-release-links');

module.exports = async (pluginConfig, context) => {
const {
Expand All @@ -17,6 +19,7 @@ module.exports = async (pluginConfig, context) => {
nextRelease,
releases,
logger,
notes,
} = context;
const {
githubToken,
Expand All @@ -27,6 +30,7 @@ module.exports = async (pluginConfig, context) => {
failComment,
failTitle,
releasedLabels,
addReleases,
} = resolveConfig(pluginConfig, context);

const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
Expand Down Expand Up @@ -140,6 +144,21 @@ module.exports = async (pluginConfig, context) => {
);
}

if (addReleases !== false && errors.length === 0) {
const ghRelease = releases.find((release) => release.name && release.name === RELEASE_NAME);
if (!isNil(ghRelease)) {
const ghRelaseId = ghRelease.id;
const additionalReleases = getReleaseLinks(releases);
if (!isEmpty(additionalReleases) && !isNil(ghRelaseId)) {
const newBody =
addReleases === 'top'
? additionalReleases.concat('\n---\n', notes)
: notes.concat('\n---\n', additionalReleases);
await github.repos.updateRelease({owner, repo, release_id: ghRelaseId, body: newBody});
}
}
}

if (errors.length > 0) {
throw new AggregateError(errors);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const getClient = require('./get-client');
const getError = require('./get-error');

const isNonEmptyString = (value) => isString(value) && value.trim();
const oneOf = (enumArray) => (value) => enumArray.some((element) => element === value);
const isStringOrStringArray = (value) =>
isNonEmptyString(value) || (isArray(value) && value.every((string) => isNonEmptyString(string)));
const isArrayOf = (validator) => (array) => isArray(array) && array.every((value) => validator(value));
Expand All @@ -24,6 +25,7 @@ const VALIDATORS = {
labels: canBeDisabled(isArrayOf(isNonEmptyString)),
assignees: isArrayOf(isNonEmptyString),
releasedLabels: canBeDisabled(isArrayOf(isNonEmptyString)),
addReleases: canBeDisabled(oneOf(['bottom', 'top'])),
};

module.exports = async (pluginConfig, context) => {
Expand Down
74 changes: 74 additions & 0 deletions test/get-release-links.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const test = require('ava');
const getReleaseLinks = require('../lib/get-release-links');
const {RELEASE_NAME} = require('../lib/definitions/constants');

test('Comment for release with multiple releases', (t) => {
const releaseInfos = [
{name: RELEASE_NAME, url: 'https://github.com/release'},
{name: 'Http release', url: 'https://release.com/release'},
{name: 'npm release', url: 'https://npm.com/release'},
];
const comment = getReleaseLinks(releaseInfos);

t.is(
comment,
`This release is also available on:
- [Http release](https://release.com/release)
- [npm release](https://npm.com/release)`
);
});

test('Release with missing release URL', (t) => {
const releaseInfos = [
{name: RELEASE_NAME, url: 'https://github.com/release'},
{name: 'Http release', url: 'https://release.com/release'},
{name: 'npm release'},
];
const comment = getReleaseLinks(releaseInfos);

t.is(
comment,
`This release is also available on:
- [Http release](https://release.com/release)
- \`npm release\``
);
});

test('Release with one release', (t) => {
const releaseInfos = [
{name: RELEASE_NAME, url: 'https://github.com/release'},
{name: 'Http release', url: 'https://release.com/release'},
];
const comment = getReleaseLinks(releaseInfos);

t.is(
comment,
`This release is also available on:
- [Http release](https://release.com/release)`
);
});

test('Release with non http releases', (t) => {
const releaseInfos = [{name: 'S3', url: 's3://my-bucket/release-asset'}];
const comment = getReleaseLinks(releaseInfos);

t.is(
comment,
`This release is also available on:
- S3: \`s3://my-bucket/release-asset\``
);
});

test('Release with only github release', (t) => {
const releaseInfos = [{name: RELEASE_NAME, url: 'https://github.com/release'}];
const comment = getReleaseLinks(releaseInfos);

t.is(comment, '');
});

test('Comment with no release object', (t) => {
const releaseInfos = [];
const comment = getReleaseLinks(releaseInfos);

t.is(comment, '');
});
Loading

0 comments on commit dea56d8

Please sign in to comment.