@npmcli/template-oss 4.11.0 → 4.11.2
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-manager.js +2 -2
- package/bin/release-please.js +14 -7
- package/lib/content/CODEOWNERS +1 -1
- package/lib/content/_job-release-integration.yml +32 -0
- package/lib/content/index.js +1 -0
- package/lib/content/release.yml +89 -13
- package/lib/release-please/index.js +39 -18
- package/package.json +1 -1
package/bin/release-manager.js
CHANGED
|
@@ -53,7 +53,7 @@ const DEFAULT_RELEASE_PROCESS = `
|
|
|
53
53
|
Release Please will run on the just pushed release commit and create GitHub releases and tags for each package.
|
|
54
54
|
|
|
55
55
|
\`\`\`
|
|
56
|
-
gh run watch \`gh run list -w release -b <BASE-BRANCH> -L 1 --json databaseId -q ".[0].databaseId"\`
|
|
56
|
+
gh run watch \`gh run list -R {NWO} -w release -b <BASE-BRANCH> -L 1 --json databaseId -q ".[0].databaseId"\`
|
|
57
57
|
\`\`\`
|
|
58
58
|
` /* eslint-enable max-len */
|
|
59
59
|
|
|
@@ -82,7 +82,7 @@ const getReleaseProcess = async ({ owner, repo }) => {
|
|
|
82
82
|
} catch (e) {
|
|
83
83
|
log('Release wiki not found', e.message)
|
|
84
84
|
log('Using default release process')
|
|
85
|
-
releaseProcess = DEFAULT_RELEASE_PROCESS.trim() + '\n'
|
|
85
|
+
releaseProcess = DEFAULT_RELEASE_PROCESS.replace(/\{NWO\}/g, `${owner}/${repo}`).trim() + '\n'
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
// XXX: the release steps need to always be the last thing in the doc for this to work
|
package/bin/release-please.js
CHANGED
|
@@ -28,6 +28,18 @@ const debugPr = (val) => {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
const debugRelease = (val) => {
|
|
32
|
+
if (dryRun) {
|
|
33
|
+
console.log('ROOT RELEASE:', JSON.stringify(val, null, 2))
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const debugReleases = (val) => {
|
|
38
|
+
if (dryRun) {
|
|
39
|
+
console.log('ALL RELEASES:', JSON.stringify(val, null, 2))
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
31
43
|
main({
|
|
32
44
|
token: process.env.GITHUB_TOKEN,
|
|
33
45
|
repo: process.env.GITHUB_REPOSITORY,
|
|
@@ -44,18 +56,13 @@ main({
|
|
|
44
56
|
}
|
|
45
57
|
|
|
46
58
|
if (release) {
|
|
59
|
+
debugRelease(release)
|
|
47
60
|
core.setOutput('release', JSON.stringify(release))
|
|
48
|
-
core.setOutput('release-path', release.path)
|
|
49
|
-
core.setOutput('release-version', release.version)
|
|
50
|
-
core.setOutput('release-tag', release.tagName)
|
|
51
|
-
core.setOutput('release-url', release.url)
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
if (releases) {
|
|
64
|
+
debugReleases(releases)
|
|
55
65
|
core.setOutput('releases', JSON.stringify(releases))
|
|
56
|
-
core.setOutput('release-flags', JSON.stringify(releases.map((r) => {
|
|
57
|
-
return r.path === '.' ? '-iwr' : `-w ${r.path}`
|
|
58
|
-
})))
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
return null
|
package/lib/content/CODEOWNERS
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
*
|
|
1
|
+
* {{ codeowner }}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
runs-on: ubuntu-latest
|
|
2
|
+
defaults:
|
|
3
|
+
run:
|
|
4
|
+
shell: bash
|
|
5
|
+
steps:
|
|
6
|
+
{{> stepNode lockfile=false }}
|
|
7
|
+
- name: View in Registry
|
|
8
|
+
run: |
|
|
9
|
+
EXIT_CODE=0
|
|
10
|
+
|
|
11
|
+
function is_published {
|
|
12
|
+
if npm view "$@" --loglevel=error > /dev/null; then
|
|
13
|
+
echo 0
|
|
14
|
+
else
|
|
15
|
+
echo 1
|
|
16
|
+
fi
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
for release in $(echo '$\{{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do
|
|
20
|
+
name=$(echo "$release" | base64 --decode | jq -r .pkgName)
|
|
21
|
+
version=$(echo "$release" | base64 --decode | jq -r .version)
|
|
22
|
+
spec="$name@$version"
|
|
23
|
+
status=$(is_published "$spec")
|
|
24
|
+
if [[ "$status" -eq 1 ]]; then
|
|
25
|
+
echo "$spec ERROR"
|
|
26
|
+
EXIT_CODE=$status
|
|
27
|
+
else
|
|
28
|
+
echo "$spec OK"
|
|
29
|
+
fi
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
exit $EXIT_CODE
|
package/lib/content/index.js
CHANGED
package/lib/content/release.yml
CHANGED
|
@@ -18,8 +18,8 @@ jobs:
|
|
|
18
18
|
release:
|
|
19
19
|
outputs:
|
|
20
20
|
pr: $\{{ steps.release.outputs.pr }}
|
|
21
|
+
release: $\{{ steps.release.outputs.release }}
|
|
21
22
|
releases: $\{{ steps.release.outputs.releases }}
|
|
22
|
-
release-flags: $\{{ steps.release.outputs.release-flags }}
|
|
23
23
|
branch: $\{{ steps.release.outputs.pr-branch }}
|
|
24
24
|
pr-number: $\{{ steps.release.outputs.pr-number }}
|
|
25
25
|
comment-id: $\{{ steps.pr-comment.outputs.result }}
|
|
@@ -40,26 +40,25 @@ jobs:
|
|
|
40
40
|
REF_NAME: $\{{ github.ref_name }}
|
|
41
41
|
with:
|
|
42
42
|
script: |
|
|
43
|
-
const { REF_NAME, PR_NUMBER } = process.env
|
|
44
|
-
const repo
|
|
45
|
-
const issue = { ...repo, issue_number: PR_NUMBER }
|
|
43
|
+
const { REF_NAME, PR_NUMBER: issue_number } = process.env
|
|
44
|
+
const { runId, repo: { owner, repo } } = context
|
|
46
45
|
|
|
47
|
-
const { data: workflow } = await github.rest.actions.getWorkflowRun({
|
|
46
|
+
const { data: workflow } = await github.rest.actions.getWorkflowRun({ owner, repo, run_id: runId })
|
|
48
47
|
|
|
49
48
|
let body = '## Release Manager\n\n'
|
|
50
49
|
|
|
51
|
-
const comments = await github.paginate(github.rest.issues.listComments,
|
|
52
|
-
let commentId = comments
|
|
50
|
+
const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
|
|
51
|
+
let commentId = comments.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith(body))?.id
|
|
53
52
|
|
|
54
53
|
body += `Release workflow run: ${workflow.html_url}\n\n#### Force CI to Update This Release\n\n`
|
|
55
54
|
body += `This PR will be updated and CI will run for every non-\`chore:\` commit that is pushed to \`{{ defaultBranch }}\`. `
|
|
56
55
|
body += `To force CI to update this PR, run this command:\n\n`
|
|
57
|
-
body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME}\n\`\`\``
|
|
56
|
+
body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME} -R ${owner}/${repo}\n\`\`\``
|
|
58
57
|
|
|
59
58
|
if (commentId) {
|
|
60
|
-
await github.rest.issues.updateComment({
|
|
59
|
+
await github.rest.issues.updateComment({ owner, repo, comment_id: commentId, body })
|
|
61
60
|
} else {
|
|
62
|
-
const { data: comment } = await github.rest.issues.createComment({
|
|
61
|
+
const { data: comment } = await github.rest.issues.createComment({ owner, repo, issue_number, body })
|
|
63
62
|
commentId = comment?.id
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -123,9 +122,86 @@ jobs:
|
|
|
123
122
|
|
|
124
123
|
post-release:
|
|
125
124
|
needs: release
|
|
126
|
-
{{> job jobName="Post Release - Release" jobIf="needs.release.outputs.releases" }}
|
|
127
|
-
- name:
|
|
125
|
+
{{> job jobName="Post Release - Release" jobIf="needs.release.outputs.releases" jobSkipSetup=true }}
|
|
126
|
+
- name: Create Release PR Comment
|
|
127
|
+
uses: actions/github-script@v6
|
|
128
128
|
env:
|
|
129
129
|
RELEASES: $\{{ needs.release.outputs.releases }}
|
|
130
|
+
with:
|
|
131
|
+
script: |
|
|
132
|
+
const releases = JSON.parse(process.env.RELEASES)
|
|
133
|
+
const { runId, repo: { owner, repo } } = context
|
|
134
|
+
const issue_number = releases[0].prNumber
|
|
135
|
+
|
|
136
|
+
let body = '## Release Workflow\n\n'
|
|
137
|
+
for (const { pkgName, version, url } of releases) {
|
|
138
|
+
body += `- \`${pkgName}@${version}\` ${url}\n`
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
|
|
142
|
+
const releaseComments = comments.filter(c => c.user.login === 'github-actions[bot]' && c.body.includes('Release is at'))
|
|
143
|
+
|
|
144
|
+
for (const comment of releaseComments) {
|
|
145
|
+
await github.rest.issues.deleteComment({ owner, repo, comment_id: comment.id })
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`
|
|
149
|
+
await github.rest.issues.createComment({
|
|
150
|
+
owner,
|
|
151
|
+
repo,
|
|
152
|
+
issue_number,
|
|
153
|
+
body: `${body}- Workflow run: :arrows_counterclockwise: ${runUrl}`,
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
release-integration:
|
|
157
|
+
needs: release
|
|
158
|
+
name: Release Integration
|
|
159
|
+
if: needs.release.outputs.release
|
|
160
|
+
{{> jobReleaseIntegration }}
|
|
161
|
+
|
|
162
|
+
post-release-integration:
|
|
163
|
+
needs: [release, release-integration]
|
|
164
|
+
{{> job jobName="Post Release Integration - Release" jobIf="needs.release.outputs.release && always()" jobSkipSetup=true }}
|
|
165
|
+
- name: Get Needs Result
|
|
166
|
+
id: needs-result
|
|
130
167
|
run: |
|
|
131
|
-
|
|
168
|
+
result=""
|
|
169
|
+
if [[ "$\{{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
|
|
170
|
+
result="x"
|
|
171
|
+
elif [[ "$\{{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
|
|
172
|
+
result="heavy_multiplication_x"
|
|
173
|
+
else
|
|
174
|
+
result="white_check_mark"
|
|
175
|
+
fi
|
|
176
|
+
echo "::set-output name=result::$result"
|
|
177
|
+
- name: Update Release PR Comment
|
|
178
|
+
uses: actions/github-script@v6
|
|
179
|
+
env:
|
|
180
|
+
PR_NUMBER: $\{{ fromJSON(needs.release.outputs.release).prNumber }}
|
|
181
|
+
RESULT: $\{{ steps.needs-result.outputs.result }}
|
|
182
|
+
with:
|
|
183
|
+
script: |
|
|
184
|
+
const { PR_NUMBER: issue_number, RESULT } = process.env
|
|
185
|
+
const { repo: { owner, repo } } = context
|
|
186
|
+
|
|
187
|
+
const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
|
|
188
|
+
const updateComment = comments.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith('## Release Workflow\n\n'))
|
|
189
|
+
|
|
190
|
+
if (updateComment) {
|
|
191
|
+
console.log('Found comment to update:', JSON.stringify(updateComment, null, 2))
|
|
192
|
+
let body = updateComment.body.replace(/Workflow run: :[a-z_]+:/, `Workflow run: :${RESULT}:`)
|
|
193
|
+
if (RESULT === 'x') {
|
|
194
|
+
body += `\n\n:rotating_light:`
|
|
195
|
+
body += ` {{ codeowner }}: The post-release workflow failed for this release.`
|
|
196
|
+
body += ` Manual steps may need to be taken after examining the workflow output`
|
|
197
|
+
body += ` from the above workflow run. :rotating_light:`
|
|
198
|
+
}
|
|
199
|
+
await github.rest.issues.updateComment({
|
|
200
|
+
owner,
|
|
201
|
+
repo,
|
|
202
|
+
body,
|
|
203
|
+
comment_id: updateComment.id,
|
|
204
|
+
})
|
|
205
|
+
} else {
|
|
206
|
+
console.log('No matching comments found:', JSON.stringify(comments, null, 2))
|
|
207
|
+
}
|
|
@@ -9,17 +9,21 @@ RP.registerChangelogNotes('default', (o) => new ChangelogNotes(o))
|
|
|
9
9
|
RP.registerVersioningStrategy('default', (o) => new Version(o))
|
|
10
10
|
RP.registerPlugin('node-workspace', (o) => new NodeWs(o.github, o.targetBranch, o.repositoryConfig))
|
|
11
11
|
|
|
12
|
-
const main = async ({ repo:
|
|
12
|
+
const main = async ({ repo: _fullRepo, token, dryRun, branch, force }) => {
|
|
13
13
|
if (!token) {
|
|
14
14
|
throw new Error('Token is required')
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
if (!
|
|
17
|
+
if (!_fullRepo) {
|
|
18
18
|
throw new Error('Repo is required')
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
const github = await RP.GitHub.create({ owner, repo, token })
|
|
21
|
+
const fullRepo = _fullRepo.split('/')
|
|
22
|
+
const github = await RP.GitHub.create({ owner: fullRepo[0], repo: fullRepo[1], token })
|
|
23
|
+
const {
|
|
24
|
+
octokit,
|
|
25
|
+
repository: { owner, repo, defaultBranch },
|
|
26
|
+
} = github
|
|
23
27
|
|
|
24
28
|
// This is mostly for testing and debugging. Use environs with the
|
|
25
29
|
// format `RELEASE_PLEASE_<manfiestOverrideConfigName>` (eg
|
|
@@ -29,7 +33,7 @@ const main = async ({ repo: fullRepo, token, dryRun, branch, force }) => {
|
|
|
29
33
|
.filter(([k, v]) => k.startsWith('RELEASE_PLEASE_') && v != null)
|
|
30
34
|
.map(([k, v]) => [k.replace('RELEASE_PLEASE_', ''), v])
|
|
31
35
|
|
|
32
|
-
const baseBranch = branch ??
|
|
36
|
+
const baseBranch = branch ?? defaultBranch
|
|
33
37
|
|
|
34
38
|
const manifest = await RP.Manifest.fromManifest(
|
|
35
39
|
github,
|
|
@@ -40,7 +44,7 @@ const main = async ({ repo: fullRepo, token, dryRun, branch, force }) => {
|
|
|
40
44
|
)
|
|
41
45
|
|
|
42
46
|
if (force) {
|
|
43
|
-
const { data: releasePrs } = await
|
|
47
|
+
const { data: releasePrs } = await octokit.pulls.list({
|
|
44
48
|
owner,
|
|
45
49
|
repo,
|
|
46
50
|
head: `release-please--branches--${baseBranch}`,
|
|
@@ -59,7 +63,7 @@ const main = async ({ repo: fullRepo, token, dryRun, branch, force }) => {
|
|
|
59
63
|
// to have a different body string so we append a message a message that CI
|
|
60
64
|
// is running. This will force release-please to rebase the PR but it
|
|
61
65
|
// wont update the body again, so we only append to it.
|
|
62
|
-
await
|
|
66
|
+
await octokit.pulls.update({
|
|
63
67
|
owner,
|
|
64
68
|
repo,
|
|
65
69
|
pull_number: releasePr.number,
|
|
@@ -73,29 +77,46 @@ const main = async ({ repo: fullRepo, token, dryRun, branch, force }) => {
|
|
|
73
77
|
// We only ever get a single pull request with our current release-please settings
|
|
74
78
|
const rootPr = pullRequests.filter(Boolean)?.[0]
|
|
75
79
|
if (rootPr?.number) {
|
|
76
|
-
const commits = await
|
|
77
|
-
owner
|
|
78
|
-
repo
|
|
80
|
+
const commits = await octokit.paginate(octokit.rest.pulls.listCommits, {
|
|
81
|
+
owner,
|
|
82
|
+
repo,
|
|
79
83
|
pull_number: rootPr.number,
|
|
80
84
|
})
|
|
81
85
|
rootPr.sha = commits?.[commits.length - 1]?.sha
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
const releases = allReleases.filter(Boolean)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
let rootRelease = releases[0]
|
|
90
|
+
|
|
91
|
+
for (const release of releases) {
|
|
92
|
+
const prefix = release.path === '.' ? '' : release.path
|
|
93
|
+
|
|
94
|
+
if (!prefix) {
|
|
95
|
+
rootRelease = release
|
|
90
96
|
}
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
|
|
98
|
+
const [releasePr, releasePkg] = await Promise.all([
|
|
99
|
+
octokit.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
100
|
+
owner,
|
|
101
|
+
repo,
|
|
102
|
+
commit_sha: release.sha,
|
|
103
|
+
}).then(r => r.data[0]),
|
|
104
|
+
octokit.rest.repos.getContent({
|
|
105
|
+
owner,
|
|
106
|
+
repo,
|
|
107
|
+
ref: baseBranch,
|
|
108
|
+
path: `${prefix}/package.json`,
|
|
109
|
+
}).then(r => JSON.parse(Buffer.from(r.data.content, r.data.encoding))),
|
|
110
|
+
])
|
|
111
|
+
|
|
112
|
+
release.prNumber = releasePr.number
|
|
113
|
+
release.pkgName = releasePkg.name
|
|
114
|
+
}
|
|
93
115
|
|
|
94
116
|
return {
|
|
95
117
|
pr: rootPr,
|
|
96
118
|
release: rootRelease,
|
|
97
119
|
releases: releases.length ? releases : null,
|
|
98
|
-
workspaceReleases: workspaceReleases.length ? workspaceReleases : null,
|
|
99
120
|
}
|
|
100
121
|
}
|
|
101
122
|
|