@npmcli/template-oss 4.20.0 → 4.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/bin/release-manager.js +23 -277
- package/bin/release-please.js +20 -55
- package/lib/config.js +6 -5
- package/lib/content/_job-release-integration-yml.hbs +27 -35
- package/lib/content/_step-node-yml.hbs +3 -48
- package/lib/content/_steps-setup-yml.hbs +10 -1
- package/lib/content/action-create-check-yml.hbs +50 -0
- package/lib/content/action-install-latest-npm-yml.hbs +56 -0
- package/lib/content/ci-release-yml.hbs +16 -4
- package/lib/content/index.js +16 -5
- package/lib/content/package-json.hbs +13 -3
- package/lib/content/pull-request-yml.hbs +2 -4
- package/lib/content/release-integration-yml.hbs +24 -0
- package/lib/content/release-please-config-json.hbs +13 -3
- package/lib/content/release-yml.hbs +140 -112
- package/lib/release/changelog.js +196 -0
- package/lib/release/node-workspace-format.js +107 -0
- package/lib/release/node-workspace.js +95 -0
- package/lib/release/release-manager.js +287 -0
- package/lib/release/release-please.js +180 -0
- package/lib/release/util.js +42 -0
- package/package.json +12 -4
- package/lib/content/_step-checks-yml.hbs +0 -54
- package/lib/release-please/changelog.js +0 -92
- package/lib/release-please/github.js +0 -72
- package/lib/release-please/index.js +0 -262
- package/lib/release-please/node-workspace.js +0 -192
- package/lib/release-please/util.js +0 -14
- package/lib/release-please/version.js +0 -103
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
const RP = require('release-please')
|
|
2
|
+
const {
|
|
3
|
+
DefaultVersioningStrategy,
|
|
4
|
+
} = require('release-please/build/src/versioning-strategies/default.js')
|
|
5
|
+
const {
|
|
6
|
+
PrereleaseVersioningStrategy,
|
|
7
|
+
} = require('release-please/build/src/versioning-strategies/prerelease.js')
|
|
8
|
+
const { ROOT_PROJECT_PATH } = require('release-please/build/src/manifest.js')
|
|
9
|
+
const { CheckpointLogger, logger } = require('release-please/build/src/util/logger.js')
|
|
10
|
+
const assert = require('assert')
|
|
11
|
+
const core = require('@actions/core')
|
|
12
|
+
const omit = require('just-omit')
|
|
13
|
+
const ChangelogNotes = require('./changelog.js')
|
|
14
|
+
const NodeWorkspace = require('./node-workspace.js')
|
|
15
|
+
const NodeWorkspaceFormat = require('./node-workspace-format.js')
|
|
16
|
+
const { getPublishTag, noop } = require('./util.js')
|
|
17
|
+
|
|
18
|
+
class ReleasePlease {
|
|
19
|
+
#token
|
|
20
|
+
#owner
|
|
21
|
+
#repo
|
|
22
|
+
#branch
|
|
23
|
+
#backport
|
|
24
|
+
#defaultTag
|
|
25
|
+
#overrides
|
|
26
|
+
#silent
|
|
27
|
+
#trace
|
|
28
|
+
#info
|
|
29
|
+
|
|
30
|
+
#github
|
|
31
|
+
#octokit
|
|
32
|
+
#manifest
|
|
33
|
+
|
|
34
|
+
constructor ({
|
|
35
|
+
token,
|
|
36
|
+
repo,
|
|
37
|
+
branch,
|
|
38
|
+
backport,
|
|
39
|
+
defaultTag,
|
|
40
|
+
overrides,
|
|
41
|
+
silent,
|
|
42
|
+
trace,
|
|
43
|
+
}) {
|
|
44
|
+
assert(token, 'token is required')
|
|
45
|
+
assert(repo, 'repo is required')
|
|
46
|
+
assert(branch, 'branch is required')
|
|
47
|
+
assert(defaultTag, 'defaultTag is required')
|
|
48
|
+
|
|
49
|
+
this.#token = token
|
|
50
|
+
this.#owner = repo.split('/')[0]
|
|
51
|
+
this.#repo = repo.split('/')[1]
|
|
52
|
+
this.#branch = branch
|
|
53
|
+
this.#backport = backport
|
|
54
|
+
this.#defaultTag = defaultTag
|
|
55
|
+
this.#overrides = overrides
|
|
56
|
+
this.#silent = silent
|
|
57
|
+
this.#trace = trace
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static async run (options) {
|
|
61
|
+
const releasePlease = new ReleasePlease(options)
|
|
62
|
+
await releasePlease.init()
|
|
63
|
+
return releasePlease.run()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async init () {
|
|
67
|
+
RP.registerChangelogNotes('default', ({ github, ...o }) =>
|
|
68
|
+
new ChangelogNotes(github, o))
|
|
69
|
+
RP.registerVersioningStrategy('default', (o) =>
|
|
70
|
+
o.prerelease ? new PrereleaseVersioningStrategy(o) : new DefaultVersioningStrategy(o))
|
|
71
|
+
RP.registerPlugin('node-workspace', ({ github, targetBranch, repositoryConfig, ...o }) =>
|
|
72
|
+
new NodeWorkspace(github, targetBranch, repositoryConfig, o))
|
|
73
|
+
RP.registerPlugin('node-workspace-format', ({ github, targetBranch, repositoryConfig, ...o }) =>
|
|
74
|
+
new NodeWorkspaceFormat(github, targetBranch, repositoryConfig, o))
|
|
75
|
+
|
|
76
|
+
if (this.#silent) {
|
|
77
|
+
this.#info = noop
|
|
78
|
+
RP.setLogger(Object.entries(logger).reduce((acc, [k, v]) => {
|
|
79
|
+
if (typeof v === 'function') {
|
|
80
|
+
acc[k] = noop
|
|
81
|
+
}
|
|
82
|
+
return acc
|
|
83
|
+
}, {}))
|
|
84
|
+
} else {
|
|
85
|
+
this.#info = core.info
|
|
86
|
+
RP.setLogger(new CheckpointLogger(true, !!this.#trace))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.#github = await RP.GitHub.create({
|
|
90
|
+
owner: this.#owner,
|
|
91
|
+
repo: this.#repo,
|
|
92
|
+
token: this.#token,
|
|
93
|
+
})
|
|
94
|
+
this.#octokit = this.#github.octokit
|
|
95
|
+
this.#manifest = await RP.Manifest.fromManifest(
|
|
96
|
+
this.#github,
|
|
97
|
+
this.#branch,
|
|
98
|
+
undefined,
|
|
99
|
+
undefined,
|
|
100
|
+
this.#overrides
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async run () {
|
|
105
|
+
const rootPr = await this.#getRootPullRequest()
|
|
106
|
+
const releases = await this.#getReleases()
|
|
107
|
+
|
|
108
|
+
if (rootPr) {
|
|
109
|
+
this.#info(`root pr: ${JSON.stringify(omit(rootPr, 'body'))}`)
|
|
110
|
+
|
|
111
|
+
// release please does not guarantee that the release PR will have the latest sha,
|
|
112
|
+
// but we always need it so we can attach the relevant checks to the sha.
|
|
113
|
+
rootPr.sha = await this.#octokit.paginate(this.#octokit.rest.pulls.listCommits, {
|
|
114
|
+
owner: this.#owner,
|
|
115
|
+
repo: this.#repo,
|
|
116
|
+
pull_number: rootPr.number,
|
|
117
|
+
}).then(r => r[r.length - 1].sha)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (releases) {
|
|
121
|
+
this.#info(`found releases: ${releases.length}`)
|
|
122
|
+
|
|
123
|
+
for (const release of releases) {
|
|
124
|
+
this.#info(`release: ${JSON.stringify(omit(release, 'notes'))}`)
|
|
125
|
+
|
|
126
|
+
release.publishTag = getPublishTag(release.version, {
|
|
127
|
+
backport: this.#backport,
|
|
128
|
+
defaultTag: this.#defaultTag,
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
release.prNumber = await this.#octokit.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
132
|
+
owner: this.#owner,
|
|
133
|
+
repo: this.#repo,
|
|
134
|
+
commit_sha: release.sha,
|
|
135
|
+
per_page: 1,
|
|
136
|
+
}).then(r => r.data[0]?.number)
|
|
137
|
+
|
|
138
|
+
release.pkgName = await this.#octokit.rest.repos.getContent({
|
|
139
|
+
owner: this.#owner,
|
|
140
|
+
repo: this.#repo,
|
|
141
|
+
ref: this.#branch,
|
|
142
|
+
path: `${release.path === '.' ? '' : release.path}/package.json`,
|
|
143
|
+
}).then(r => JSON.parse(Buffer.from(r.data.content, r.data.encoding)).name)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
pr: rootPr,
|
|
149
|
+
releases: releases,
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async #getRootPullRequest () {
|
|
154
|
+
// We only ever get a single pull request with our current release-please settings
|
|
155
|
+
// Update this if we start creating individual PRs per workspace release
|
|
156
|
+
const pullRequests = await this.#manifest.createPullRequests()
|
|
157
|
+
return pullRequests.filter(Boolean)[0] ?? null
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async #getReleases () {
|
|
161
|
+
// if we have a root release, always put it as the first item in the array
|
|
162
|
+
const rawReleases = await this.#manifest.createReleases().then(r => r.filter(Boolean))
|
|
163
|
+
let rootRelease = null
|
|
164
|
+
const workspaceReleases = []
|
|
165
|
+
|
|
166
|
+
for (const release of rawReleases) {
|
|
167
|
+
if (release.path === ROOT_PROJECT_PATH) {
|
|
168
|
+
assert(!rootRelease, 'Multiple root releases detected. This should never happen.')
|
|
169
|
+
rootRelease = release
|
|
170
|
+
} else {
|
|
171
|
+
workspaceReleases.push(release)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const releases = [rootRelease, ...workspaceReleases].filter(Boolean)
|
|
176
|
+
return releases.length ? releases : null
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
module.exports = ReleasePlease
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const semver = require('semver')
|
|
2
|
+
|
|
3
|
+
const SPEC = new RegExp(`([^\\s]+@${semver.src[semver.tokens.FULLPLAIN]})`, 'g')
|
|
4
|
+
const code = (c) => `\`${c}\``
|
|
5
|
+
const wrapSpecs = (str) => str.replace(SPEC, code('$1'))
|
|
6
|
+
const block = (lang) => `\`\`\`${lang ? `${lang}` : ''}`
|
|
7
|
+
const link = (text, url) => `[${text}](${url})`
|
|
8
|
+
const list = (text) => `* ${text}`
|
|
9
|
+
const formatDate = (date = new Date()) => {
|
|
10
|
+
const year = date.getFullYear()
|
|
11
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
|
12
|
+
const day = date.getDate().toString().padStart(2, '0')
|
|
13
|
+
return [year, month, day].join('-')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const getPublishTag = (v, { backport, defaultTag }) => {
|
|
17
|
+
const version = semver.parse(v)
|
|
18
|
+
return version.prerelease.length
|
|
19
|
+
? `prerelease-${version.major}`
|
|
20
|
+
: backport ? `latest-${backport}`
|
|
21
|
+
: defaultTag.replace(/{{\s*major\s*}}/, version.major)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const makeGitHubUrl = (owner, repo) =>
|
|
25
|
+
(...p) => `https://github.com/${owner}/${repo}/${p.join('/')}`
|
|
26
|
+
|
|
27
|
+
const noop = () => {}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
// we use this string a lot, its duplicated in the changelog sections but its hard
|
|
31
|
+
// to access from within release please so we keep it here also.
|
|
32
|
+
DEPS: 'deps',
|
|
33
|
+
wrapSpecs,
|
|
34
|
+
code,
|
|
35
|
+
block,
|
|
36
|
+
link,
|
|
37
|
+
list,
|
|
38
|
+
formatDate,
|
|
39
|
+
getPublishTag,
|
|
40
|
+
makeGitHubUrl,
|
|
41
|
+
noop,
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/template-oss",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.21.1",
|
|
4
4
|
"description": "templated files used in npm CLI team oss projects",
|
|
5
5
|
"main": "lib/content/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"postlint": "template-oss-check",
|
|
20
20
|
"postinstall": "template-oss-apply",
|
|
21
21
|
"test-all": "npm run test -ws -iwr --if-present",
|
|
22
|
-
"lint-all": "npm run lint -ws -iwr --if-present"
|
|
22
|
+
"lint-all": "npm run lint -ws -iwr --if-present",
|
|
23
|
+
"test:record": "TAP_SNAPSHOT=1 NOCK_RECORD=1 tap"
|
|
23
24
|
},
|
|
24
25
|
"repository": {
|
|
25
26
|
"type": "git",
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
"@npmcli/map-workspaces": "^3.0.0",
|
|
42
43
|
"@npmcli/package-json": "^5.0.0",
|
|
43
44
|
"@octokit/rest": "^19.0.4",
|
|
45
|
+
"dedent": "^1.5.1",
|
|
44
46
|
"diff": "^5.0.0",
|
|
45
47
|
"glob": "^10.1.0",
|
|
46
48
|
"handlebars": "^4.7.7",
|
|
@@ -49,12 +51,14 @@
|
|
|
49
51
|
"json-parse-even-better-errors": "^3.0.0",
|
|
50
52
|
"just-deep-map-values": "^1.1.1",
|
|
51
53
|
"just-diff": "^6.0.0",
|
|
54
|
+
"just-omit": "^2.2.0",
|
|
52
55
|
"lodash": "^4.17.21",
|
|
53
56
|
"minimatch": "^9.0.2",
|
|
54
57
|
"npm-package-arg": "^11.0.1",
|
|
55
58
|
"proc-log": "^3.0.0",
|
|
56
|
-
"release-please": "
|
|
59
|
+
"release-please": "16.3.1",
|
|
57
60
|
"semver": "^7.3.5",
|
|
61
|
+
"undici": "^5.27.2",
|
|
58
62
|
"yaml": "^2.1.1"
|
|
59
63
|
},
|
|
60
64
|
"files": [
|
|
@@ -64,6 +68,7 @@
|
|
|
64
68
|
"devDependencies": {
|
|
65
69
|
"@npmcli/eslint-config": "^4.0.0",
|
|
66
70
|
"@npmcli/template-oss": "file:./",
|
|
71
|
+
"nock": "^13.3.8",
|
|
67
72
|
"tap": "^16.0.0"
|
|
68
73
|
},
|
|
69
74
|
"tap": {
|
|
@@ -74,7 +79,10 @@
|
|
|
74
79
|
"--exclude",
|
|
75
80
|
"tap-snapshots/**"
|
|
76
81
|
],
|
|
77
|
-
"test-ignore": "^(workspace/test-workspace)/"
|
|
82
|
+
"test-ignore": "^(workspace/test-workspace)/",
|
|
83
|
+
"node-arg": [
|
|
84
|
+
"--no-experimental-fetch"
|
|
85
|
+
]
|
|
78
86
|
},
|
|
79
87
|
"templateOSS": {
|
|
80
88
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
{{#if jobCheck.sha}}
|
|
2
|
-
- name: Get Workflow Job
|
|
3
|
-
uses: actions/github-script@v6
|
|
4
|
-
if: {{ jobCheck.sha }}
|
|
5
|
-
id: check-output
|
|
6
|
-
env:
|
|
7
|
-
JOB_NAME: "{{#if jobName}}{{ jobName }}{{else}}{{ jobCheck.name }}{{/if}}"
|
|
8
|
-
MATRIX_NAME: "{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}"
|
|
9
|
-
with:
|
|
10
|
-
script: |
|
|
11
|
-
const { owner, repo } = context.repo
|
|
12
|
-
|
|
13
|
-
const { data } = await github.rest.actions.listJobsForWorkflowRun({
|
|
14
|
-
owner,
|
|
15
|
-
repo,
|
|
16
|
-
run_id: context.runId,
|
|
17
|
-
per_page: 100
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME
|
|
21
|
-
const job = data.jobs.find(j => j.name.endsWith(jobName))
|
|
22
|
-
const jobUrl = job?.html_url
|
|
23
|
-
|
|
24
|
-
const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/$\{{ {{ jobCheck.sha }} }}`
|
|
25
|
-
|
|
26
|
-
let summary = `This check is assosciated with ${shaUrl}\n\n`
|
|
27
|
-
|
|
28
|
-
if (jobUrl) {
|
|
29
|
-
summary += `For run logs, click here: ${jobUrl}`
|
|
30
|
-
} else {
|
|
31
|
-
summary += `Run logs could not be found for a job with name: "${jobName}"`
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return { summary }
|
|
35
|
-
{{/if}}
|
|
36
|
-
- name: {{#if jobCheck.sha}}Create{{else}}Conclude{{/if}} Check
|
|
37
|
-
uses: LouisBrunner/checks-action@v1.6.0
|
|
38
|
-
{{#if jobCheck.sha}}
|
|
39
|
-
id: check
|
|
40
|
-
if: {{ jobCheck.sha }}
|
|
41
|
-
{{else}}
|
|
42
|
-
if: {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}steps.check.outputs.check_id{{/if}} && always()
|
|
43
|
-
{{/if}}
|
|
44
|
-
with:
|
|
45
|
-
token: $\{{ secrets.GITHUB_TOKEN }}
|
|
46
|
-
{{#if jobCheck.sha}}
|
|
47
|
-
status: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}in_progress{{/if}}
|
|
48
|
-
name: {{#if jobCheck.name}}{{ jobCheck.name }}{{else}}{{ jobName }}{{/if}}{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}
|
|
49
|
-
sha: $\{{ {{ jobCheck.sha }} }}
|
|
50
|
-
output: $\{{ steps.check-output.outputs.result }}
|
|
51
|
-
{{else}}
|
|
52
|
-
conclusion: $\{{ {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}job.status{{/if}} }}
|
|
53
|
-
check_id: $\{{ {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}steps.check.outputs.check_id{{/if}} }}
|
|
54
|
-
{{/if}}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const makeGh = require('./github.js')
|
|
2
|
-
const { link, code, specRe, list, dateFmt } = require('./util')
|
|
3
|
-
|
|
4
|
-
module.exports = class ChangelogNotes {
|
|
5
|
-
constructor (options) {
|
|
6
|
-
this.gh = makeGh(options.github)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
buildEntry (commit, authors = []) {
|
|
10
|
-
const breaking = commit.notes
|
|
11
|
-
.filter(n => n.title === 'BREAKING CHANGE')
|
|
12
|
-
.map(n => n.text)
|
|
13
|
-
|
|
14
|
-
const entry = []
|
|
15
|
-
|
|
16
|
-
if (commit.sha) {
|
|
17
|
-
// A link to the commit
|
|
18
|
-
entry.push(link(code(commit.sha.slice(0, 7)), this.gh.commit(commit.sha)))
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// A link to the pull request if the commit has one
|
|
22
|
-
const prNumber = commit.pullRequest?.number
|
|
23
|
-
if (prNumber) {
|
|
24
|
-
entry.push(link(`#${prNumber}`, this.gh.pull(prNumber)))
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// The title of the commit, with the optional scope as a prefix
|
|
28
|
-
const scope = commit.scope && `${commit.scope}:`
|
|
29
|
-
const subject = commit.bareMessage.replace(specRe, code('$1'))
|
|
30
|
-
entry.push([scope, subject].filter(Boolean).join(' '))
|
|
31
|
-
|
|
32
|
-
// A list og the authors github handles or names
|
|
33
|
-
if (authors.length && commit.type !== 'deps') {
|
|
34
|
-
entry.push(`(${authors.join(', ')})`)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
entry: entry.join(' '),
|
|
39
|
-
breaking,
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async buildNotes (rawCommits, { version, previousTag, currentTag, changelogSections }) {
|
|
44
|
-
const changelog = changelogSections.reduce((acc, c) => {
|
|
45
|
-
if (!c.hidden) {
|
|
46
|
-
acc[c.type] = {
|
|
47
|
-
title: c.section,
|
|
48
|
-
entries: [],
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return acc
|
|
52
|
-
}, {
|
|
53
|
-
breaking: {
|
|
54
|
-
title: '⚠️ BREAKING CHANGES',
|
|
55
|
-
entries: [],
|
|
56
|
-
},
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
// Only continue with commits that will make it to our changelog
|
|
60
|
-
const commits = rawCommits.filter(c => changelog[c.type])
|
|
61
|
-
|
|
62
|
-
const authorsByCommit = await this.gh.authors(commits)
|
|
63
|
-
|
|
64
|
-
// Group commits by type
|
|
65
|
-
for (const commit of commits) {
|
|
66
|
-
// when rebase merging multiple commits with a single PR, only the first commit
|
|
67
|
-
// will have a pr number when coming from release-please. this check will manually
|
|
68
|
-
// lookup commits without a pr number and find one if it exists
|
|
69
|
-
if (!commit.pullRequest?.number) {
|
|
70
|
-
commit.pullRequest = { number: await this.gh.commitPrNumber(commit) }
|
|
71
|
-
}
|
|
72
|
-
const { entry, breaking } = this.buildEntry(
|
|
73
|
-
commit,
|
|
74
|
-
authorsByCommit[commit.sha]
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
// Collect commits by type
|
|
78
|
-
changelog[commit.type].entries.push(entry)
|
|
79
|
-
|
|
80
|
-
// And push breaking changes to its own section
|
|
81
|
-
changelog.breaking.entries.push(...breaking)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const sections = Object.values(changelog)
|
|
85
|
-
.filter((s) => s.entries.length)
|
|
86
|
-
.map(({ title, entries }) => [`### ${title}`, entries.map(list).join('\n')].join('\n\n'))
|
|
87
|
-
|
|
88
|
-
const title = `## ${link(version, this.gh.compare(previousTag, currentTag))} (${dateFmt()})`
|
|
89
|
-
|
|
90
|
-
return [title, ...sections].join('\n\n').trim()
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
module.exports = (gh) => {
|
|
2
|
-
const { owner, repo } = gh.repository
|
|
3
|
-
|
|
4
|
-
const authors = async (commits) => {
|
|
5
|
-
const response = {}
|
|
6
|
-
|
|
7
|
-
const shas = commits.map(c => c.sha).filter(Boolean)
|
|
8
|
-
|
|
9
|
-
if (!shas.length) {
|
|
10
|
-
return response
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
try {
|
|
14
|
-
const { repository } = await gh.graphql(
|
|
15
|
-
`fragment CommitAuthors on GitObject {
|
|
16
|
-
... on Commit {
|
|
17
|
-
authors (first:10) {
|
|
18
|
-
nodes {
|
|
19
|
-
user { login }
|
|
20
|
-
name
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
query {
|
|
26
|
-
repository (owner:"${owner}", name:"${repo}") {
|
|
27
|
-
${shas.map((s) => {
|
|
28
|
-
return `_${s}: object (expression: "${s}") { ...CommitAuthors }`
|
|
29
|
-
})}
|
|
30
|
-
}
|
|
31
|
-
}`
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
for (const [key, commit] of Object.entries(repository)) {
|
|
35
|
-
if (commit) {
|
|
36
|
-
response[key.slice(1)] = commit.authors.nodes
|
|
37
|
-
.map((a) => a.user && a.user.login ? `@${a.user.login}` : a.name)
|
|
38
|
-
.filter(Boolean)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return response
|
|
43
|
-
} catch {
|
|
44
|
-
return response
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const commitPrNumber = async (commit) => {
|
|
49
|
-
try {
|
|
50
|
-
const res = await gh.octokit.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
51
|
-
owner,
|
|
52
|
-
repo,
|
|
53
|
-
commit_sha: commit.sha,
|
|
54
|
-
per_page: 1,
|
|
55
|
-
})
|
|
56
|
-
return res.data[0].number
|
|
57
|
-
} catch {
|
|
58
|
-
return null
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const url = (...p) => `https://github.com/${owner}/${repo}/${p.join('/')}`
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
authors,
|
|
66
|
-
commitPrNumber,
|
|
67
|
-
pull: (number) => url('pull', number),
|
|
68
|
-
commit: (sha) => url('commit', sha),
|
|
69
|
-
compare: (a, b) => a ? url('compare', `${a.toString()}...${b.toString()}`) : null,
|
|
70
|
-
release: (tag) => url('releases', 'tag', tag.toString()),
|
|
71
|
-
}
|
|
72
|
-
}
|