19
19
release :
20
20
outputs :
21
21
pr : ${{ steps.release.outputs.pr }}
22
+ release : ${{ steps.release.outputs.release }}
22
23
releases : ${{ steps.release.outputs.releases }}
23
- release-flags : ${{ steps.release.outputs.release-flags }}
24
24
branch : ${{ steps.release.outputs.pr-branch }}
25
25
pr-number : ${{ steps.release.outputs.pr-number }}
26
26
comment-id : ${{ steps.pr-comment.outputs.result }}
@@ -63,26 +63,25 @@ jobs:
63
63
REF_NAME : ${{ github.ref_name }}
64
64
with :
65
65
script : |
66
- const { REF_NAME, PR_NUMBER } = process.env
67
- const repo = { owner: context.repo.owner, repo: context.repo.repo }
68
- const issue = { ...repo, issue_number: PR_NUMBER }
66
+ const { REF_NAME, PR_NUMBER: issue_number } = process.env
67
+ const { runId, repo: { owner, repo } } = context
69
68
70
- const { data: workflow } = await github.rest.actions.getWorkflowRun({ ... repo, run_id: context. runId })
69
+ const { data: workflow } = await github.rest.actions.getWorkflowRun({ owner, repo, run_id: runId })
71
70
72
71
let body = '## Release Manager\n\n'
73
72
74
- const comments = await github.paginate(github.rest.issues.listComments, issue )
75
- let commentId = comments? .find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith(body))?.id
73
+ const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number } )
74
+ let commentId = comments.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith(body))?.id
76
75
77
76
body += `Release workflow run: ${workflow.html_url}\n\n#### Force CI to Update This Release\n\n`
78
77
body += `This PR will be updated and CI will run for every non-\`chore:\` commit that is pushed to \`main\`. `
79
78
body += `To force CI to update this PR, run this command:\n\n`
80
- body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME}\n\`\`\``
79
+ body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME} -R ${owner}/${repo} \n\`\`\``
81
80
82
81
if (commentId) {
83
- await github.rest.issues.updateComment({ ... repo, comment_id: commentId, body })
82
+ await github.rest.issues.updateComment({ owner, repo, comment_id: commentId, body })
84
83
} else {
85
- const { data: comment } = await github.rest.issues.createComment({ ...issue , body })
84
+ const { data: comment } = await github.rest.issues.createComment({ owner, repo, issue_number , body })
86
85
commentId = comment?.id
87
86
}
88
87
@@ -276,12 +275,45 @@ jobs:
276
275
run :
277
276
shell : bash
278
277
steps :
279
- - name : Checkout
280
- uses : actions/checkout@v3
281
- - name : Setup Git User
282
- run : |
283
- git config --global user.email "npm-cli+bot@github.com"
284
- git config --global user.name "npm CLI robot"
278
+ - name : Create Release PR Comment
279
+ uses : actions/github-script@v6
280
+ env :
281
+ RELEASES : ${{ needs.release.outputs.releases }}
282
+ with :
283
+ script : |
284
+ const releases = JSON.parse(process.env.RELEASES)
285
+ const { runId, repo: { owner, repo } } = context
286
+ const issue_number = releases[0].prNumber
287
+
288
+ let body = '## Release Workflow\n\n'
289
+ for (const { pkgName, version, url } of releases) {
290
+ body += `- \`${pkgName}@${version}\` ${url}\n`
291
+ }
292
+
293
+ const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
294
+ const releaseComments = comments.filter(c => c.user.login === 'github-actions[bot]' && c.body.includes('Release is at'))
295
+
296
+ for (const comment of releaseComments) {
297
+ await github.rest.issues.deleteComment({ owner, repo, comment_id: comment.id })
298
+ }
299
+
300
+ const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`
301
+ await github.rest.issues.createComment({
302
+ owner,
303
+ repo,
304
+ issue_number,
305
+ body: `${body}- Workflow run: :arrows_counterclockwise: ${runUrl}`,
306
+ })
307
+
308
+ release-integration :
309
+ needs : release
310
+ name : Release Integration
311
+ if : needs.release.outputs.release
312
+ runs-on : ubuntu-latest
313
+ defaults :
314
+ run :
315
+ shell : bash
316
+ steps :
285
317
- name : Setup Node
286
318
uses : actions/setup-node@v3
287
319
with :
@@ -290,10 +322,82 @@ jobs:
290
322
run : npm i --prefer-online --no-fund --no-audit -g npm@8
291
323
- name : npm Version
292
324
run : npm -v
293
- - name : Install Dependencies
294
- run : npm i --ignore-scripts --no-audit --no-fund
295
- - name : Run Post Release Actions
296
- env :
297
- RELEASES : ${{ needs.release.outputs.releases }}
325
+ - name : View in Registry
326
+ run : |
327
+ EXIT_CODE=0
328
+
329
+ function is_published {
330
+ if npm view "$@" --loglevel=error > /dev/null; then
331
+ echo 0
332
+ else
333
+ echo 1
334
+ fi
335
+ }
336
+
337
+ for release in $(echo '${{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do
338
+ name=$(echo "$release" | base64 --decode | jq -r .pkgName)
339
+ version=$(echo "$release" | base64 --decode | jq -r .version)
340
+ spec="$name@$version"
341
+ status=$(is_published "$spec")
342
+ if [[ "$status" -eq 1 ]]; then
343
+ echo "$spec ERROR"
344
+ EXIT_CODE=$status
345
+ else
346
+ echo "$spec OK"
347
+ fi
348
+ done
349
+
350
+ exit $EXIT_CODE
351
+
352
+ post-release-integration :
353
+ needs : [ release, release-integration ]
354
+ name : Post Release Integration - Release
355
+ if : github.repository_owner == 'npm' && needs.release.outputs.release && always()
356
+ runs-on : ubuntu-latest
357
+ defaults :
358
+ run :
359
+ shell : bash
360
+ steps :
361
+ - name : Get Needs Result
362
+ id : needs-result
298
363
run : |
299
- npm run rp-release --ignore-scripts --if-present ${{ join(fromJSON(needs.release.outputs.release-flags), ' ') }}
364
+ result=""
365
+ if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
366
+ result="x"
367
+ elif [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
368
+ result="heavy_multiplication_x"
369
+ else
370
+ result="white_check_mark"
371
+ fi
372
+ echo "::set-output name=result::$result"
373
+ - name : Update Release PR Comment
374
+ uses : actions/github-script@v6
375
+ env :
376
+ PR_NUMBER : ${{ fromJSON(needs.release.outputs.release).prNumber }}
377
+ RESULT : ${{ steps.needs-result.outputs.result }}
378
+ with :
379
+ script : |
380
+ const { PR_NUMBER: issue_number, RESULT } = process.env
381
+ const { repo: { owner, repo } } = context
382
+
383
+ const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
384
+ const updateComment = comments.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith('## Release Workflow\n\n'))
385
+
386
+ if (updateComment) {
387
+ console.log('Found comment to update:', JSON.stringify(updateComment, null, 2))
388
+ let body = updateComment.body.replace(/Workflow run: :[a-z_]+:/, `Workflow run: :${RESULT}:`)
389
+ if (RESULT === 'x') {
390
+ body += `\n\n:rotating_light:`
391
+ body += ` @npm/cli-team: The post-release workflow failed for this release.`
392
+ body += ` Manual steps may need to be taken after examining the workflow output`
393
+ body += ` from the above workflow run. :rotating_light:`
394
+ }
395
+ await github.rest.issues.updateComment({
396
+ owner,
397
+ repo,
398
+ body,
399
+ comment_id: updateComment.id,
400
+ })
401
+ } else {
402
+ console.log('No matching comments found:', JSON.stringify(comments, null, 2))
403
+ }
0 commit comments