|
1 | 1 | const { compose } = require('ramda'); |
2 | | -const { |
3 | | - wrapPlugin, |
4 | | - appendMultiPlugin, |
5 | | -} = require('semantic-release-plugin-decorators'); |
6 | | -const pluginDefinitions = require('semantic-release/lib/definitions/plugins'); |
7 | | - |
8 | 2 | const { parse } = require('./comment-tag'); |
9 | 3 | const createChangelog = require('./create-changelog'); |
10 | 4 | const deleteStaleChangelogs = require('./delete-changelog'); |
11 | 5 | const withGithub = require('./with-github'); |
12 | | -const withGitHead = require('./with-git-head'); |
13 | 6 | const withNpmPackage = require('./with-npm-package'); |
14 | 7 | const withMatchingPullRequests = require('./with-matching-pull-requests'); |
15 | 8 |
|
16 | | -const NAMESPACE = 'githubPr'; |
17 | | - |
18 | 9 | const decoratePlugin = compose( |
19 | 10 | withGithub, |
20 | | - withGitHead, |
21 | 11 | withMatchingPullRequests, |
22 | 12 | withNpmPackage |
23 | 13 | ); |
24 | 14 |
|
25 | | -// Use `analyzeCommits` plugin as a hook to post a "no release" PR comment if |
26 | | -// there isn't a new release. We can't do this in `generateNotes` since it only runs |
27 | | -// if there's a new release. |
28 | | -const analyzeCommits = wrapPlugin( |
29 | | - NAMESPACE, |
30 | | - 'analyzeCommits', |
31 | | - plugin => async (pluginConfig, context) => { |
| 15 | +// Use the `analyzeCommits` step to post a "no release" PR comment when there |
| 16 | +// isn't a new release (we can't do this in `generateNotes` since it only runs |
| 17 | +// if there's a new release). |
| 18 | +const analyzeCommits = async (pluginConfig, context, results) => { |
| 19 | + return Promise.all(results).then(async results => { |
32 | 20 | const { githubRepo, pullRequests } = pluginConfig; |
33 | | - const nextRelease = await plugin(pluginConfig, context); |
| 21 | + const hasNextRelease = results.some(result => !!result); |
34 | 22 |
|
35 | | - if (!nextRelease) { |
| 23 | + if (!hasNextRelease) { |
36 | 24 | await pullRequests.forEach(async pr => { |
37 | 25 | const { number } = pr; |
38 | 26 | const createChangelogOnPr = createChangelog(pluginConfig, context); |
39 | 27 | const { data: comments } = await githubRepo.getIssueComments({ |
40 | 28 | number, |
41 | 29 | }); |
42 | 30 |
|
43 | | - // Create "no release" comment if there are no other comments posted |
44 | | - // by this set of plugins. We want to avoid duplicating the "no release" |
45 | | - // comment and/or posting it when another package has a release (monorepo). |
| 31 | + // Create a "no release" comment. |
| 32 | + // We only do this if there are no other comments posted by this plugin, |
| 33 | + // avoiding duplication of the "no release" comment and/or incorrectly posting |
| 34 | + // it when a different package in the same PR has a release (monorepo). |
46 | 35 | if (!comments.some(comment => !!parse(comment.body))) { |
47 | 36 | createChangelogOnPr(pr); |
48 | 37 | } |
49 | 38 | }); |
50 | 39 | } |
51 | 40 |
|
52 | | - // Clean up stale changelog comments, possibly sparing the "no release" |
53 | | - // comment if this package doesn't have a new release. |
| 41 | + // Clean up stale changelog comments from previous runs of this plugin. |
54 | 42 | await pullRequests.forEach( |
55 | | - deleteStaleChangelogs(!nextRelease)(pluginConfig, context) |
| 43 | + deleteStaleChangelogs(!hasNextRelease)(pluginConfig, context) |
56 | 44 | ); |
57 | 45 |
|
58 | | - return nextRelease; |
59 | | - }, |
60 | | - pluginDefinitions.analyzeCommits.default |
61 | | -); |
| 46 | + return; |
| 47 | + }); |
| 48 | +}; |
62 | 49 |
|
63 | | -// Append a plugin that generates PR comments from the release notes resulting |
64 | | -// from the configured `generateNotes` plugins that run ahead of it. |
65 | | -const generateNotes = appendMultiPlugin( |
66 | | - NAMESPACE, |
67 | | - 'generateNotes', |
68 | | - decoratePlugin(async (pluginConfig, context) => { |
| 50 | +// Use the "generateNotes" step to post a PR comments with the release notes |
| 51 | +// generated for the pending release. |
| 52 | +const generateNotes = async (pluginConfig, context, results) => { |
| 53 | + return Promise.all(results).then(async results => { |
69 | 54 | const { pullRequests } = pluginConfig; |
70 | 55 | const { nextRelease } = context; |
71 | 56 |
|
72 | 57 | await pullRequests.forEach( |
73 | | - // Create "release" comment |
| 58 | + // Create a "release" comment. |
74 | 59 | createChangelog(pluginConfig, context) |
75 | 60 | ); |
76 | 61 |
|
77 | 62 | return nextRelease.notes; |
78 | | - }), |
79 | | - pluginDefinitions.generateNotes.default |
80 | | -); |
| 63 | + }); |
| 64 | +}; |
| 65 | + |
| 66 | +const appendStep = (stepName, stepFn) => { |
| 67 | + const results = []; |
| 68 | + |
| 69 | + return Array(10) |
| 70 | + .fill(null) |
| 71 | + .map((value, index) => { |
| 72 | + return async (pluginConfig, context) => { |
| 73 | + const { |
| 74 | + options: { plugins }, |
| 75 | + } = context; |
| 76 | + const pluginName = plugins[index]; |
| 77 | + |
| 78 | + if (index === plugins.length) { |
| 79 | + return stepFn(pluginConfig, context, results); |
| 80 | + } |
| 81 | + |
| 82 | + if (!pluginName) { |
| 83 | + return ''; |
| 84 | + } |
| 85 | + |
| 86 | + const plugin = require(pluginName); |
| 87 | + const step = plugin && plugin[stepName]; |
| 88 | + |
| 89 | + if (!step) { |
| 90 | + return ''; |
| 91 | + } |
| 92 | + |
| 93 | + const result = step(pluginConfig, context); |
| 94 | + results.push(result); |
| 95 | + return result; |
| 96 | + }; |
| 97 | + }); |
| 98 | +}; |
81 | 99 |
|
82 | 100 | module.exports = { |
83 | 101 | verifyConditions: '@semantic-release/github', |
84 | | - analyzeCommits: decoratePlugin(analyzeCommits), |
85 | | - generateNotes, |
| 102 | + analyzeCommits: appendStep('analyzeCommits', decoratePlugin(analyzeCommits)), |
| 103 | + generateNotes: appendStep('generateNotes', decoratePlugin(generateNotes)), |
86 | 104 | }; |
0 commit comments