@npmcli/template-oss 4.11.3 → 4.12.0
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/bin/release-please.js +2 -2
- package/lib/content/SECURITY.md +1 -2
- package/lib/content/post-dependabot.yml +4 -4
- package/lib/content/release.yml +22 -11
- package/lib/release-please/changelog.js +11 -2
- package/lib/release-please/github.js +15 -0
- package/lib/release-please/index.js +201 -62
- package/package.json +1 -1
package/bin/release-please.js
CHANGED
|
@@ -4,7 +4,7 @@ const core = require('@actions/core')
|
|
|
4
4
|
const main = require('../lib/release-please/index.js')
|
|
5
5
|
|
|
6
6
|
const dryRun = !process.env.CI
|
|
7
|
-
const [branch,
|
|
7
|
+
const [branch, forcePullRequest] = process.argv.slice(2)
|
|
8
8
|
|
|
9
9
|
const debugPr = (val) => {
|
|
10
10
|
if (dryRun) {
|
|
@@ -45,7 +45,7 @@ main({
|
|
|
45
45
|
repo: process.env.GITHUB_REPOSITORY,
|
|
46
46
|
dryRun,
|
|
47
47
|
branch,
|
|
48
|
-
|
|
48
|
+
forcePullRequest: forcePullRequest ? +forcePullRequest : null,
|
|
49
49
|
}).then(({ pr, release, releases }) => {
|
|
50
50
|
if (pr) {
|
|
51
51
|
debugPr(pr)
|
package/lib/content/SECURITY.md
CHANGED
|
@@ -2,11 +2,10 @@ GitHub takes the security of our software products and services seriously, inclu
|
|
|
2
2
|
|
|
3
3
|
If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways.
|
|
4
4
|
|
|
5
|
-
If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly
|
|
5
|
+
If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly through [opensource-security@github.com](mailto:opensource-security@github.com).
|
|
6
6
|
|
|
7
7
|
If the vulnerability you have found is [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) and you would like for your finding to be considered for a bounty reward, please submit the vulnerability to us through [HackerOne](https://hackerone.com/github) in order to be eligible to receive a bounty award.
|
|
8
8
|
|
|
9
9
|
**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
|
|
10
10
|
|
|
11
11
|
Thanks for helping make GitHub safe for everyone.
|
|
12
|
-
|
|
@@ -27,11 +27,11 @@ jobs:
|
|
|
27
27
|
run: |
|
|
28
28
|
dependabot_dir="$\{{ steps.metadata.outputs.directory }}"
|
|
29
29
|
if [[ "$dependabot_dir" == "/" ]]; then
|
|
30
|
-
echo "
|
|
30
|
+
echo "workspace=-iwr" >> $GITHUB_OUTPUT
|
|
31
31
|
else
|
|
32
32
|
# strip leading slash from directory so it works as a
|
|
33
33
|
# a path to the workspace flag
|
|
34
|
-
echo "
|
|
34
|
+
echo "workspace=-w ${dependabot_dir#/}" >> $GITHUB_OUTPUT
|
|
35
35
|
fi
|
|
36
36
|
|
|
37
37
|
- name: Apply Changes
|
|
@@ -40,7 +40,7 @@ jobs:
|
|
|
40
40
|
run: |
|
|
41
41
|
{{ rootNpmPath }} run template-oss-apply $\{{ steps.flags.outputs.workspace }}
|
|
42
42
|
if [[ `git status --porcelain` ]]; then
|
|
43
|
-
echo "
|
|
43
|
+
echo "changes=true" >> $GITHUB_OUTPUT
|
|
44
44
|
fi
|
|
45
45
|
# This only sets the conventional commit prefix. This workflow can't reliably determine
|
|
46
46
|
# what the breaking change is though. If a BREAKING CHANGE message is required then
|
|
@@ -50,7 +50,7 @@ jobs:
|
|
|
50
50
|
else
|
|
51
51
|
prefix='chore'
|
|
52
52
|
fi
|
|
53
|
-
echo "
|
|
53
|
+
echo "message=$prefix: postinstall for dependabot template-oss PR" >> $GITHUB_OUTPUT
|
|
54
54
|
|
|
55
55
|
# This step will fail if template-oss has made any workflow updates. It is impossible
|
|
56
56
|
# for a workflow to update other workflows. In the case it does fail, we continue
|
package/lib/content/release.yml
CHANGED
|
@@ -2,6 +2,10 @@ name: Release
|
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
release-pr:
|
|
7
|
+
description: a release PR number to rerun release jobs on
|
|
8
|
+
type: string
|
|
5
9
|
push:
|
|
6
10
|
branches:
|
|
7
11
|
{{#each branches}}
|
|
@@ -30,7 +34,7 @@ jobs:
|
|
|
30
34
|
env:
|
|
31
35
|
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
|
|
32
36
|
run: |
|
|
33
|
-
{{ rootNpxPath }} --offline template-oss-release-please $\{{ github.ref_name }} $\{{
|
|
37
|
+
{{ rootNpxPath }} --offline template-oss-release-please "$\{{ github.ref_name }}" "$\{{ inputs.release-pr }}"
|
|
34
38
|
- name: Post Pull Request Comment
|
|
35
39
|
if: steps.release.outputs.pr-number
|
|
36
40
|
uses: actions/github-script@v6
|
|
@@ -53,7 +57,7 @@ jobs:
|
|
|
53
57
|
body += `Release workflow run: ${workflow.html_url}\n\n#### Force CI to Update This Release\n\n`
|
|
54
58
|
body += `This PR will be updated and CI will run for every non-\`chore:\` commit that is pushed to \`{{ defaultBranch }}\`. `
|
|
55
59
|
body += `To force CI to update this PR, run this command:\n\n`
|
|
56
|
-
body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME} -R ${owner}/${repo}\n\`\`\``
|
|
60
|
+
body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME} -R ${owner}/${repo} -f release-pr=${issue_number}\n\`\`\``
|
|
57
61
|
|
|
58
62
|
if (commentId) {
|
|
59
63
|
await github.rest.issues.updateComment({ owner, repo, comment_id: commentId, body })
|
|
@@ -90,7 +94,7 @@ jobs:
|
|
|
90
94
|
run: |
|
|
91
95
|
git commit --all --amend --no-edit || true
|
|
92
96
|
git push --force-with-lease
|
|
93
|
-
echo "
|
|
97
|
+
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
|
94
98
|
{{> stepChecks jobName="Update - Release" jobCheck=(obj sha="steps.commit.outputs.sha" name="Release" )}}
|
|
95
99
|
{{> stepChecks jobCheck=(obj id="needs.release.outputs.check-id" )}}
|
|
96
100
|
|
|
@@ -117,7 +121,7 @@ jobs:
|
|
|
117
121
|
else
|
|
118
122
|
result="success"
|
|
119
123
|
fi
|
|
120
|
-
echo "
|
|
124
|
+
echo "result=$result" >> $GITHUB_OUTPUT
|
|
121
125
|
{{> stepChecks jobCheck=(obj id="needs.update.outputs.check-id" status="steps.needs-result.outputs.result") }}
|
|
122
126
|
|
|
123
127
|
post-release:
|
|
@@ -139,14 +143,17 @@ jobs:
|
|
|
139
143
|
}
|
|
140
144
|
|
|
141
145
|
const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
|
|
142
|
-
|
|
146
|
+
.then(cs => cs.map(c => ({ id: c.id, login: c.user.login, body: c.body })))
|
|
147
|
+
console.log(`Found comments: ${JSON.stringify(comments, null, 2)}`)
|
|
148
|
+
const releaseComments = comments.filter(c => c.login === 'github-actions[bot]' && c.body.includes('Release is at'))
|
|
143
149
|
|
|
144
150
|
for (const comment of releaseComments) {
|
|
151
|
+
console.log(`Release comment: ${JSON.stringify(comment, null, 2)}`)
|
|
145
152
|
await github.rest.issues.deleteComment({ owner, repo, comment_id: comment.id })
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`
|
|
149
|
-
await github.rest.issues.createComment({
|
|
156
|
+
await github.rest.issues.createComment({
|
|
150
157
|
owner,
|
|
151
158
|
repo,
|
|
152
159
|
issue_number,
|
|
@@ -165,7 +172,6 @@ jobs:
|
|
|
165
172
|
- name: Get Needs Result
|
|
166
173
|
id: needs-result
|
|
167
174
|
run: |
|
|
168
|
-
result=""
|
|
169
175
|
if [[ "$\{{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
|
|
170
176
|
result="x"
|
|
171
177
|
elif [[ "$\{{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
|
|
@@ -173,7 +179,7 @@ jobs:
|
|
|
173
179
|
else
|
|
174
180
|
result="white_check_mark"
|
|
175
181
|
fi
|
|
176
|
-
echo "
|
|
182
|
+
echo "result=$result" >> $GITHUB_OUTPUT
|
|
177
183
|
- name: Update Release PR Comment
|
|
178
184
|
uses: actions/github-script@v6
|
|
179
185
|
env:
|
|
@@ -182,15 +188,20 @@ jobs:
|
|
|
182
188
|
with:
|
|
183
189
|
script: |
|
|
184
190
|
const { PR_NUMBER: issue_number, RESULT } = process.env
|
|
185
|
-
const { repo: { owner, repo } } = context
|
|
191
|
+
const { runId, repo: { owner, repo } } = context
|
|
186
192
|
|
|
187
193
|
const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
|
|
188
|
-
const updateComment = comments.find(c =>
|
|
194
|
+
const updateComment = comments.find(c =>
|
|
195
|
+
c.user.login === 'github-actions[bot]' &&
|
|
196
|
+
c.body.startsWith('## Release Workflow\n\n') &&
|
|
197
|
+
c.body.includes(runId)
|
|
198
|
+
)
|
|
189
199
|
|
|
190
200
|
if (updateComment) {
|
|
191
201
|
console.log('Found comment to update:', JSON.stringify(updateComment, null, 2))
|
|
192
202
|
let body = updateComment.body.replace(/Workflow run: :[a-z_]+:/, `Workflow run: :${RESULT}:`)
|
|
193
|
-
|
|
203
|
+
const tagCodeowner = RESULT !== 'white_check_mark'
|
|
204
|
+
if (tagCodeowner) {
|
|
194
205
|
body += `\n\n:rotating_light:`
|
|
195
206
|
body += ` {{ codeowner }}: The post-release workflow failed for this release.`
|
|
196
207
|
body += ` Manual steps may need to be taken after examining the workflow output`
|
|
@@ -19,7 +19,7 @@ module.exports = class ChangelogNotes {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// A link to the pull request if the commit has one
|
|
22
|
-
const prNumber = commit.pullRequest
|
|
22
|
+
const prNumber = commit.pullRequest?.number
|
|
23
23
|
if (prNumber) {
|
|
24
24
|
entry.push(link(`#${prNumber}`, this.gh.pull(prNumber)))
|
|
25
25
|
}
|
|
@@ -63,7 +63,16 @@ module.exports = class ChangelogNotes {
|
|
|
63
63
|
|
|
64
64
|
// Group commits by type
|
|
65
65
|
for (const commit of commits) {
|
|
66
|
-
|
|
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
|
+
)
|
|
67
76
|
|
|
68
77
|
// Collect commits by type
|
|
69
78
|
changelog[commit.type].entries.push(entry)
|
|
@@ -45,10 +45,25 @@ module.exports = (gh) => {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
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
|
+
|
|
48
62
|
const url = (...p) => `https://github.com/${owner}/${repo}/${p.join('/')}`
|
|
49
63
|
|
|
50
64
|
return {
|
|
51
65
|
authors,
|
|
66
|
+
commitPrNumber,
|
|
52
67
|
pull: (number) => url('pull', number),
|
|
53
68
|
commit: (sha) => url('commit', sha),
|
|
54
69
|
compare: (a, b) => a ? url('compare', `${a.toString()}...${b.toString()}`) : null,
|
|
@@ -4,26 +4,33 @@ const ChangelogNotes = require('./changelog.js')
|
|
|
4
4
|
const Version = require('./version.js')
|
|
5
5
|
const NodeWs = require('./node-workspace.js')
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const logger = new CheckpointLogger(true, true)
|
|
8
|
+
RP.setLogger(logger)
|
|
8
9
|
RP.registerChangelogNotes('default', (o) => new ChangelogNotes(o))
|
|
9
10
|
RP.registerVersioningStrategy('default', (o) => new Version(o))
|
|
10
11
|
RP.registerPlugin('node-workspace', (o) => new NodeWs(o.github, o.targetBranch, o.repositoryConfig))
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const omit = (obj, ...keys) => {
|
|
14
|
+
const res = {}
|
|
15
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
16
|
+
if (!keys.includes(key)) {
|
|
17
|
+
res[key] = value
|
|
18
|
+
}
|
|
15
19
|
}
|
|
20
|
+
return res
|
|
21
|
+
}
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
const getManifest = async ({ repo: fullRepo, token, branch }) => {
|
|
24
|
+
const fullRepoParts = fullRepo.split('/')
|
|
25
|
+
const github = await RP.GitHub.create({
|
|
26
|
+
owner: fullRepoParts[0],
|
|
27
|
+
repo: fullRepoParts[1],
|
|
28
|
+
token,
|
|
29
|
+
})
|
|
20
30
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
octokit,
|
|
25
|
-
repository: { owner, repo, defaultBranch },
|
|
26
|
-
} = github
|
|
31
|
+
const { octokit, repository: { owner, repo, defaultBranch } } = github
|
|
32
|
+
|
|
33
|
+
const baseBranch = branch ?? defaultBranch
|
|
27
34
|
|
|
28
35
|
// This is mostly for testing and debugging. Use environs with the
|
|
29
36
|
// format `RELEASE_PLEASE_<manfiestOverrideConfigName>` (eg
|
|
@@ -33,8 +40,6 @@ const main = async ({ repo: _fullRepo, token, dryRun, branch, force }) => {
|
|
|
33
40
|
.filter(([k, v]) => k.startsWith('RELEASE_PLEASE_') && v != null)
|
|
34
41
|
.map(([k, v]) => [k.replace('RELEASE_PLEASE_', ''), v])
|
|
35
42
|
|
|
36
|
-
const baseBranch = branch ?? defaultBranch
|
|
37
|
-
|
|
38
43
|
const manifest = await RP.Manifest.fromManifest(
|
|
39
44
|
github,
|
|
40
45
|
baseBranch,
|
|
@@ -43,79 +48,213 @@ const main = async ({ repo: _fullRepo, token, dryRun, branch, force }) => {
|
|
|
43
48
|
Object.fromEntries(manifestOverrides)
|
|
44
49
|
)
|
|
45
50
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
return {
|
|
52
|
+
github,
|
|
53
|
+
manifest,
|
|
54
|
+
octokit,
|
|
55
|
+
owner,
|
|
56
|
+
repo,
|
|
57
|
+
baseBranch,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
const getReleasesFromPr = async ({ manifest, github, number }) => {
|
|
62
|
+
const baseUrl = `https://github.com/${github.repository.owner}/${github.repository.repo}`
|
|
63
|
+
// get the release please formatted pull request
|
|
64
|
+
let pullRequest
|
|
65
|
+
const prGenerator = github.pullRequestIterator(this.targetBranch, 'MERGED', 200, false)
|
|
66
|
+
for await (const pr of prGenerator) {
|
|
67
|
+
if (pr.number === number) {
|
|
68
|
+
pullRequest = pr
|
|
69
|
+
break
|
|
55
70
|
}
|
|
71
|
+
}
|
|
72
|
+
const strategiesByPath = await manifest.getStrategiesByPath()
|
|
73
|
+
const releases = []
|
|
74
|
+
for (const path in manifest.repositoryConfig) {
|
|
75
|
+
const config = manifest.repositoryConfig[path]
|
|
76
|
+
const release = await strategiesByPath[path].buildRelease(pullRequest)
|
|
77
|
+
if (release) {
|
|
78
|
+
const { tag, ...rest } = release
|
|
79
|
+
releases.push({
|
|
80
|
+
...rest,
|
|
81
|
+
...tag.version,
|
|
82
|
+
tagName: tag.toString(),
|
|
83
|
+
version: tag.version.toString(),
|
|
84
|
+
path,
|
|
85
|
+
draft: false,
|
|
86
|
+
url: `${baseUrl}/releases/tag/${tag.toString()}`,
|
|
87
|
+
prerelease: config.prerelease && !!tag.version.preRelease,
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return releases
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const getReleaseArtifacts = async ({ dryRun, manifest, forceReleases }) => {
|
|
95
|
+
let pullRequests = []
|
|
96
|
+
let releases = []
|
|
97
|
+
|
|
98
|
+
if (forceReleases) {
|
|
99
|
+
releases = forceReleases
|
|
100
|
+
} else if (dryRun) {
|
|
101
|
+
pullRequests = await manifest.buildPullRequests()
|
|
102
|
+
releases = await manifest.buildReleases()
|
|
103
|
+
} else {
|
|
104
|
+
pullRequests = await manifest.createPullRequests()
|
|
105
|
+
releases = await manifest.createReleases()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
pullRequests: pullRequests.filter(Boolean),
|
|
110
|
+
releases: releases.filter(Boolean),
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// XXX(hack): to get release please to recreate a pull request it needs
|
|
115
|
+
// to have a different body string so we append a message a message that CI
|
|
116
|
+
// is running. This will force release-please to rebase the PR but it
|
|
117
|
+
// wont update the body again, so we only append to it.
|
|
118
|
+
const touchPullRequest = async ({ octokit, owner, repo, releasePr }) => {
|
|
119
|
+
const id = process.env.GITHUB_RUN_ID
|
|
120
|
+
? `by https://github.com/${owner}/${repo}/actions/runs/${process.env.GITHUB_RUN_ID}`
|
|
121
|
+
: `manually starting at ${new Date().toJSON()}`
|
|
122
|
+
|
|
123
|
+
await octokit.pulls.update({
|
|
124
|
+
owner,
|
|
125
|
+
repo,
|
|
126
|
+
pull_number: releasePr.number,
|
|
127
|
+
body: `${releasePr.body.trim()}\n- This PR is being recreated ${id}`,
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const main = async ({ repo: fullRepo, token, dryRun, branch, forcePullRequest }) => {
|
|
132
|
+
if (!token) {
|
|
133
|
+
throw new Error('Token is required')
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!fullRepo) {
|
|
137
|
+
throw new Error('Repo is required')
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const {
|
|
141
|
+
github,
|
|
142
|
+
octokit,
|
|
143
|
+
manifest,
|
|
144
|
+
owner,
|
|
145
|
+
repo,
|
|
146
|
+
baseBranch,
|
|
147
|
+
} = await getManifest({ repo: fullRepo, token, branch })
|
|
56
148
|
|
|
57
|
-
|
|
58
|
-
const id = process.env.GITHUB_RUN_ID
|
|
59
|
-
? `by https://github.com/${owner}/${repo}/actions/runs/${process.env.GITHUB_RUN_ID}`
|
|
60
|
-
: `manually starting at ${new Date().toJSON()}`
|
|
149
|
+
let forceReleases = null
|
|
61
150
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// is running. This will force release-please to rebase the PR but it
|
|
65
|
-
// wont update the body again, so we only append to it.
|
|
66
|
-
await octokit.pulls.update({
|
|
151
|
+
if (forcePullRequest) {
|
|
152
|
+
const { data: releasePr } = await octokit.rest.pulls.get({
|
|
67
153
|
owner,
|
|
68
154
|
repo,
|
|
69
|
-
pull_number:
|
|
70
|
-
body: `${releasePr.body.trim()}\n- This PR is being recreated ${id}`,
|
|
155
|
+
pull_number: forcePullRequest,
|
|
71
156
|
})
|
|
157
|
+
|
|
158
|
+
if (!releasePr) {
|
|
159
|
+
throw new Error(`Could not find PR from number: ${forcePullRequest}`)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (releasePr.state === 'open') {
|
|
163
|
+
await touchPullRequest({ octokit, owner, repo, releasePr })
|
|
164
|
+
} else if (releasePr.state === 'closed' && releasePr.merged) {
|
|
165
|
+
forceReleases = await getReleasesFromPr({ manifest, github, number: releasePr.number })
|
|
166
|
+
} else {
|
|
167
|
+
throw new Error(`Could not run workflow on PR with wrong state: ${JSON.stringify(
|
|
168
|
+
releasePr,
|
|
169
|
+
null,
|
|
170
|
+
2
|
|
171
|
+
)}`)
|
|
172
|
+
}
|
|
72
173
|
}
|
|
73
174
|
|
|
74
|
-
const pullRequests = await (dryRun
|
|
75
|
-
const allReleases = await (dryRun ? manifest.buildReleases() : manifest.createReleases())
|
|
175
|
+
const { pullRequests, releases } = await getReleaseArtifacts({ dryRun, manifest, forceReleases })
|
|
76
176
|
|
|
77
177
|
// We only ever get a single pull request with our current release-please settings
|
|
78
|
-
|
|
178
|
+
// Update this if we start creating individual PRs per workspace release
|
|
179
|
+
const rootPr = pullRequests[0]
|
|
180
|
+
let rootRelease = releases[0]
|
|
181
|
+
|
|
182
|
+
logger.debug(`pull requests: ${pullRequests.length}`)
|
|
183
|
+
logger.debug(`releases: ${releases.length}`)
|
|
184
|
+
|
|
185
|
+
if (rootPr) {
|
|
186
|
+
logger.debug(`root pr: ${JSON.stringify(omit(rootPr, 'body'), null, 2)}`)
|
|
187
|
+
}
|
|
188
|
+
|
|
79
189
|
if (rootPr?.number) {
|
|
80
190
|
const commits = await octokit.paginate(octokit.rest.pulls.listCommits, {
|
|
81
191
|
owner,
|
|
82
192
|
repo,
|
|
83
193
|
pull_number: rootPr.number,
|
|
84
194
|
})
|
|
85
|
-
rootPr.sha = commits?.[commits.length - 1]?.sha
|
|
86
|
-
}
|
|
87
195
|
|
|
88
|
-
|
|
89
|
-
|
|
196
|
+
const prSha = commits?.[commits.length - 1]?.sha
|
|
197
|
+
if (!prSha) {
|
|
198
|
+
throw new Error(`Could not find a latest sha for pull request: ${rootPr.number}`)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
rootPr.sha = prSha
|
|
202
|
+
}
|
|
90
203
|
|
|
91
204
|
for (const release of releases) {
|
|
92
|
-
const
|
|
205
|
+
const { path, sha } = release
|
|
206
|
+
const prefix = path === '.' ? '' : path
|
|
207
|
+
const isRoot = !prefix
|
|
208
|
+
const packagePath = `${prefix}/package.json`
|
|
93
209
|
|
|
94
|
-
|
|
95
|
-
|
|
210
|
+
logger.debug(`release: ${JSON.stringify({
|
|
211
|
+
...omit(release, 'notes'),
|
|
212
|
+
isRoot,
|
|
213
|
+
prefix,
|
|
214
|
+
}, null, 2)}`)
|
|
215
|
+
|
|
216
|
+
const releasePrNumber = await octokit.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
217
|
+
owner,
|
|
218
|
+
repo,
|
|
219
|
+
commit_sha: sha,
|
|
220
|
+
per_page: 1,
|
|
221
|
+
}).then(r => r.data[0]?.number)
|
|
222
|
+
|
|
223
|
+
if (!releasePrNumber) {
|
|
224
|
+
throw new Error(`Could not find release PR number from commit: "${sha}"`)
|
|
96
225
|
}
|
|
97
226
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
227
|
+
logger.debug(`pr from ${sha}: ${releasePrNumber}`)
|
|
228
|
+
|
|
229
|
+
const releasePkgName = await octokit.rest.repos.getContent({
|
|
230
|
+
owner,
|
|
231
|
+
repo,
|
|
232
|
+
ref: baseBranch,
|
|
233
|
+
path: packagePath,
|
|
234
|
+
}).then(r => {
|
|
235
|
+
try {
|
|
236
|
+
return JSON.parse(Buffer.from(r.data.content, r.data.encoding)).name
|
|
237
|
+
} catch {
|
|
238
|
+
return null
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
if (!releasePkgName) {
|
|
243
|
+
throw new Error(`Could not find package name for release at: "${packagePath}#${baseBranch}"`)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
logger.debug(`pkg name from ${packagePath}#${baseBranch}: "${releasePkgName}"`)
|
|
247
|
+
|
|
248
|
+
release.prNumber = releasePrNumber
|
|
249
|
+
release.pkgName = releasePkgName
|
|
250
|
+
if (isRoot) {
|
|
251
|
+
rootRelease = release
|
|
252
|
+
}
|
|
114
253
|
}
|
|
115
254
|
|
|
116
255
|
return {
|
|
117
|
-
pr: rootPr,
|
|
118
|
-
release: rootRelease,
|
|
256
|
+
pr: rootPr ?? null,
|
|
257
|
+
release: rootRelease ?? null,
|
|
119
258
|
releases: releases.length ? releases : null,
|
|
120
259
|
}
|
|
121
260
|
}
|