-
Notifications
You must be signed in to change notification settings - Fork 49
/
index.js
93 lines (86 loc) · 4.61 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { format } from "url";
import { find, merge } from "lodash-es";
import getStream from "get-stream";
import intoStream from "into-stream";
import { CommitParser } from "conventional-commits-parser";
import writer from "./wrappers/conventional-changelog-writer.js";
import { filterRevertedCommitsSync } from "conventional-commits-filter";
import { readPackageUp } from "read-package-up";
import debugFactory from "debug";
import loadChangelogConfig from "./lib/load-changelog-config.js";
import HOSTS_CONFIG from "./lib/hosts-config.js";
const debug = debugFactory("semantic-release:release-notes-generator");
/**
* Generate the changelog for all the commits in `options.commits`.
*
* @param {Object} pluginConfig The plugin configuration.
* @param {String} pluginConfig.preset conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint').
* @param {String} pluginConfig.config Requireable npm package with a custom conventional-changelog preset
* @param {Object} pluginConfig.parserOpts Additional `conventional-changelog-parser` options that will overwrite ones loaded by `preset` or `config`.
* @param {Object} pluginConfig.writerOpts Additional `conventional-changelog-writer` options that will overwrite ones loaded by `preset` or `config`.
* @param {Object} context The semantic-release context.
* @param {Array<Object>} context.commits The commits to analyze.
* @param {Object} context.lastRelease The last release with `gitHead` corresponding to the commit hash used to make the last release and `gitTag` corresponding to the git tag associated with `gitHead`.
* @param {Object} context.nextRelease The next release with `gitHead` corresponding to the commit hash used to make the release, the release `version` and `gitTag` corresponding to the git tag associated with `gitHead`.
* @param {Object} context.options.repositoryUrl The git repository URL.
*
* @returns {String} The changelog for all the commits in `context.commits`.
*/
export async function generateNotes(pluginConfig, context) {
const { commits, lastRelease, nextRelease, options, cwd } = context;
const repositoryUrl = options.repositoryUrl.replace(/\.git$/i, "");
const { parserOpts, writerOpts } = await loadChangelogConfig(pluginConfig, context);
const [match, auth, host, path] = /^(?!.+:\/\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(repositoryUrl) || [];
let { hostname, port, pathname, protocol } = new URL(
match ? `ssh://${auth ? `${auth}@` : ""}${host}/${path}` : repositoryUrl
);
port = protocol.includes("ssh") ? "" : port;
protocol = protocol && /http[^s]/.test(protocol) ? "http" : "https";
const [, owner, repository] = /^\/(?<owner>[^/]+)?\/?(?<repository>.+)?$/.exec(pathname) || [];
const { issue, commit, referenceActions, issuePrefixes } =
find(HOSTS_CONFIG, (conf) => conf.hostname === hostname) || HOSTS_CONFIG.default;
const parser = new CommitParser({ referenceActions, issuePrefixes, ...parserOpts });
const parsedCommits = filterRevertedCommitsSync(
commits
.filter(({ message, hash }) => {
if (!message.trim()) {
debug("Skip commit %s with empty message", hash);
return false;
}
return true;
})
.map((rawCommit) => ({
...rawCommit,
...parser.parse(rawCommit.message),
}))
);
const previousTag = lastRelease.gitTag || lastRelease.gitHead;
const currentTag = nextRelease.gitTag || nextRelease.gitHead;
const { host: hostConfig, linkCompare, linkReferences, commit: commitConfig, issue: issueConfig } = pluginConfig;
const changelogContext = merge(
{
version: nextRelease.version,
host: format({ protocol, hostname, port }),
owner,
repository,
previousTag,
currentTag,
linkCompare: currentTag && previousTag,
issue,
commit,
packageData: ((await readPackageUp({ normalize: false, cwd })) || {}).packageJson,
},
{ host: hostConfig, linkCompare, linkReferences, commit: commitConfig, issue: issueConfig }
);
debug("version: %o", changelogContext.version);
debug("host: %o", changelogContext.hostname);
debug("owner: %o", changelogContext.owner);
debug("repository: %o", changelogContext.repository);
debug("previousTag: %o", changelogContext.previousTag);
debug("currentTag: %o", changelogContext.currentTag);
debug("host: %o", changelogContext.host);
debug("linkReferences: %o", changelogContext.linkReferences);
debug("issue: %o", changelogContext.issue);
debug("commit: %o", changelogContext.commit);
return getStream(intoStream.object(parsedCommits).pipe(writer(changelogContext, writerOpts)));
}