@npmcli/template-oss 4.19.0 → 4.21.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.
Files changed (72) hide show
  1. package/README.md +35 -11
  2. package/bin/release-manager.js +23 -271
  3. package/bin/release-please.js +20 -55
  4. package/lib/config.js +98 -119
  5. package/lib/content/{_job-matrix.yml → _job-matrix-yml.hbs} +1 -1
  6. package/lib/content/_job-release-integration-yml.hbs +51 -0
  7. package/lib/content/{_job.yml → _job-yml.hbs} +1 -1
  8. package/lib/content/_step-node-yml.hbs +15 -0
  9. package/lib/content/_steps-setup-yml.hbs +15 -0
  10. package/lib/content/action-create-check-yml.hbs +50 -0
  11. package/lib/content/action-install-latest-npm-yml.hbs +55 -0
  12. package/lib/content/{audit.yml → audit-yml.hbs} +2 -2
  13. package/lib/content/ci-release-yml.hbs +49 -0
  14. package/lib/content/ci-yml.hbs +13 -0
  15. package/lib/content/{codeql-analysis.yml → codeql-analysis-yml.hbs} +1 -1
  16. package/lib/content/{eslintrc.js → eslintrc-js.hbs} +11 -1
  17. package/lib/content/{gitignore → gitignore.hbs} +2 -0
  18. package/lib/content/index.js +55 -40
  19. package/lib/content/{pkg.json → package-json.hbs} +19 -5
  20. package/lib/content/{post-dependabot.yml → post-dependabot-yml.hbs} +1 -1
  21. package/lib/content/{pull-request.yml → pull-request-yml.hbs} +3 -5
  22. package/lib/content/release-integration-yml.hbs +24 -0
  23. package/lib/content/release-please-config-json.hbs +23 -0
  24. package/lib/content/release-yml.hbs +245 -0
  25. package/lib/content/tsconfig-json.hbs +17 -0
  26. package/lib/release/changelog.js +184 -0
  27. package/lib/release/node-workspace-format.js +107 -0
  28. package/lib/release/node-workspace.js +95 -0
  29. package/lib/release/release-manager.js +287 -0
  30. package/lib/release/release-please.js +180 -0
  31. package/lib/release/util.js +42 -0
  32. package/lib/util/files.js +29 -20
  33. package/lib/util/get-cmd-path.js +36 -0
  34. package/lib/util/git.js +6 -2
  35. package/lib/util/import-or-require.js +29 -0
  36. package/lib/util/parser.js +6 -1
  37. package/lib/util/path.js +13 -0
  38. package/lib/util/template.js +9 -6
  39. package/package.json +21 -13
  40. package/lib/content/_job-release-integration.yml +0 -59
  41. package/lib/content/_step-checks.yml +0 -54
  42. package/lib/content/_step-node.yml +0 -57
  43. package/lib/content/_steps-setup.yml +0 -6
  44. package/lib/content/ci-release.yml +0 -37
  45. package/lib/content/ci.yml +0 -13
  46. package/lib/content/release-please-config.json +0 -13
  47. package/lib/content/release.yml +0 -217
  48. package/lib/release-please/changelog.js +0 -92
  49. package/lib/release-please/github.js +0 -72
  50. package/lib/release-please/index.js +0 -262
  51. package/lib/release-please/node-workspace.js +0 -192
  52. package/lib/release-please/util.js +0 -14
  53. package/lib/release-please/version.js +0 -103
  54. /package/lib/content/{CODEOWNERS → CODEOWNERS.hbs} +0 -0
  55. /package/lib/content/{CODE_OF_CONDUCT.md → CODE_OF_CONDUCT-md.hbs} +0 -0
  56. /package/lib/content/{CONTRIBUTING.md → CONTRIBUTING-md.hbs} +0 -0
  57. /package/lib/content/{LICENSE.md → LICENSE-md.hbs} +0 -0
  58. /package/lib/content/{SECURITY.md → SECURITY-md.hbs} +0 -0
  59. /package/lib/content/{_on-ci.yml → _on-ci-yml.hbs} +0 -0
  60. /package/lib/content/{_step-audit.yml → _step-audit-yml.hbs} +0 -0
  61. /package/lib/content/{_step-deps.yml → _step-deps-yml.hbs} +0 -0
  62. /package/lib/content/{_step-git.yml → _step-git-yml.hbs} +0 -0
  63. /package/lib/content/{_step-lint.yml → _step-lint-yml.hbs} +0 -0
  64. /package/lib/content/{_step-test.yml → _step-test-yml.hbs} +0 -0
  65. /package/lib/content/{bug.yml → bug-yml.hbs} +0 -0
  66. /package/lib/content/{commitlintrc.js → commitlintrc-js.hbs} +0 -0
  67. /package/lib/content/{config.yml → config-yml.hbs} +0 -0
  68. /package/lib/content/{dependabot.yml → dependabot-yml.hbs} +0 -0
  69. /package/lib/content/{npmrc → npmrc.hbs} +0 -0
  70. /package/lib/content/{release-please-manifest.json → release-please-manifest-json.hbs} +0 -0
  71. /package/lib/content/{settings.yml → settings-yml.hbs} +0 -0
  72. /package/lib/content/{tap.json → tap-json.hbs} +0 -0
@@ -1,57 +0,0 @@
1
- - name: Setup Node
2
- uses: actions/setup-node@v3
3
- id: node
4
- with:
5
- node-version: {{#if jobIsMatrix}}$\{{ matrix.node-version }}{{else}}{{ last ciVersions }}{{/if}}
6
- check-latest: contains({{#if jobIsMatrix}}matrix.node-version{{else}}'{{ last ciVersions }}'{{/if}}, '.x')
7
- {{#if lockfile}}
8
- cache: npm
9
- {{/if}}
10
-
11
- {{#if updateNpm}}
12
- # node 10/12/14 ship with npm@6, which is known to fail when updating itself in windows
13
- - name: Update Windows npm
14
- if: |
15
- matrix.platform.os == 'windows-latest' && (
16
- startsWith(steps.node.outputs.node-version, 'v10.') || startsWith(steps.node.outputs.node-version, 'v12.') || startsWith(steps.node.outputs.node-version, 'v14.')
17
- )
18
- run: |
19
- curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz
20
- tar xf npm-7.5.4.tgz
21
- cd package
22
- node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
23
- cd ..
24
- rmdir /s /q package
25
-
26
- # Start on Node 10 because we dont test on anything lower
27
- - name: Install npm@7 on Node 10
28
- shell: bash
29
- if: startsWith(steps.node.outputs.node-version, 'v10.')
30
- id: npm-7
31
- run: |
32
- npm i --prefer-online --no-fund --no-audit -g npm@7
33
- echo "updated=true" >> "$GITHUB_OUTPUT"
34
-
35
- - name: Install npm@8 on Node 12
36
- shell: bash
37
- if: startsWith(steps.node.outputs.node-version, 'v12.')
38
- id: npm-8
39
- run: |
40
- npm i --prefer-online --no-fund --no-audit -g npm@8
41
- echo "updated=true" >> "$GITHUB_OUTPUT"
42
-
43
- - name: Install npm@9 on Node 14/16/18.0
44
- shell: bash
45
- if: startsWith(steps.node.outputs.node-version, 'v14.') || startsWith(steps.node.outputs.node-version, 'v16.') || startsWith(steps.node.outputs.node-version, 'v18.0.')
46
- id: npm-9
47
- run: |
48
- npm i --prefer-online --no-fund --no-audit -g npm@9
49
- echo "updated=true" >> "$GITHUB_OUTPUT"
50
-
51
- - name: Install npm@latest on Node
52
- if: $\{{ !(steps.npm-7.outputs.updated || steps.npm-8.outputs.updated || steps.npm-9.outputs.updated) }}
53
- run: npm i --prefer-online --no-fund --no-audit -g npm@latest
54
-
55
- - name: npm Version
56
- run: npm -v
57
- {{/if}}
@@ -1,6 +0,0 @@
1
- {{~#if jobCheck}}{{> stepChecks }}{{/if}}
2
- {{~#unless jobSkipSetup}}
3
- {{> stepGit }}
4
- {{> stepNode }}
5
- {{> stepDeps }}
6
- {{/unless}}
@@ -1,37 +0,0 @@
1
-
2
- name: CI - Release
3
-
4
- on:
5
- workflow_dispatch:
6
- inputs:
7
- ref:
8
- required: true
9
- type: string
10
- default: {{ releaseBranch }}
11
- workflow_call:
12
- inputs:
13
- ref:
14
- required: true
15
- type: string
16
- check-sha:
17
- required: true
18
- type: string
19
-
20
- jobs:
21
- lint-all:
22
- {{> job
23
- jobName="Lint All"
24
- jobCheck=(obj sha="inputs.check-sha")
25
- jobCheckout=(obj ref="${{ inputs.ref }}")
26
- }}
27
- {{> stepLint jobRunFlags=allFlags }}
28
- {{> stepChecks jobCheck=true }}
29
-
30
- test-all:
31
- {{> jobMatrix
32
- jobName="Test All"
33
- jobCheck=(obj sha="inputs.check-sha")
34
- jobCheckout=(obj ref="${{ inputs.ref }}")
35
- }}
36
- {{> stepTest jobRunFlags=allFlags }}
37
- {{> stepChecks jobCheck=true }}
@@ -1,13 +0,0 @@
1
- name: CI {{~#if isWorkspace}} - {{ pkgName }}{{/if}}
2
-
3
- on:
4
- {{> onCi }}
5
-
6
- jobs:
7
- lint:
8
- {{> job jobName="Lint" }}
9
- {{> stepLint jobRunFlags=pkgFlags }}
10
-
11
- test:
12
- {{> jobMatrix jobName="Test" }}
13
- {{> stepTest jobRunFlags=pkgFlags }}
@@ -1,13 +0,0 @@
1
- {
2
- "separate-pull-requests": {{{ del }}},
3
- "plugins": {{#if isMonoPublic }}["node-workspace"]{{ else }}{{{ del }}}{{/if}},
4
- "exclude-packages-from-root": true,
5
- "group-pull-request-title-pattern": "chore: release ${version}",
6
- "pull-request-title-pattern": "chore: release${component} ${version}",
7
- "changelog-sections": {{{ json changelogTypes }}},
8
- "packages": {
9
- "{{ pkgPath }}": {
10
- {{#if isRoot}}"package-name": ""{{/if}}
11
- }
12
- }
13
- }
@@ -1,217 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- workflow_dispatch:
5
- inputs:
6
- release-pr:
7
- description: a release PR number to rerun release jobs on
8
- type: string
9
- push:
10
- branches:
11
- {{#each branchPatterns}}
12
- - {{ . }}
13
- {{/each}}
14
-
15
- permissions:
16
- contents: write
17
- pull-requests: write
18
- checks: write
19
-
20
- jobs:
21
- release:
22
- outputs:
23
- pr: $\{{ steps.release.outputs.pr }}
24
- release: $\{{ steps.release.outputs.release }}
25
- releases: $\{{ steps.release.outputs.releases }}
26
- branch: $\{{ steps.release.outputs.pr-branch }}
27
- pr-number: $\{{ steps.release.outputs.pr-number }}
28
- comment-id: $\{{ steps.pr-comment.outputs.result }}
29
- check-id: $\{{ steps.check.outputs.check_id }}
30
- {{> job jobName="Release" }}
31
- - name: Release Please
32
- id: release
33
- env:
34
- GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
35
- run: |
36
- {{ rootNpxPath }} --offline template-oss-release-please "$\{{ github.ref_name }}" "$\{{ inputs.release-pr }}"
37
- - name: Post Pull Request Comment
38
- if: steps.release.outputs.pr-number
39
- uses: actions/github-script@v6
40
- id: pr-comment
41
- env:
42
- PR_NUMBER: $\{{ steps.release.outputs.pr-number }}
43
- REF_NAME: $\{{ github.ref_name }}
44
- with:
45
- script: |
46
- const { REF_NAME, PR_NUMBER: issue_number } = process.env
47
- const { runId, repo: { owner, repo } } = context
48
-
49
- const { data: workflow } = await github.rest.actions.getWorkflowRun({ owner, repo, run_id: runId })
50
-
51
- let body = '## Release Manager\n\n'
52
-
53
- const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
54
- let commentId = comments.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith(body))?.id
55
-
56
- body += `Release workflow run: ${workflow.html_url}\n\n#### Force CI to Update This Release\n\n`
57
- body += `This PR will be updated and CI will run for every non-\`chore:\` commit that is pushed to \`${REF_NAME}\`. `
58
- body += `To force CI to update this PR, run this command:\n\n`
59
- body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME} -R ${owner}/${repo} -f release-pr=${issue_number}\n\`\`\``
60
-
61
- if (commentId) {
62
- await github.rest.issues.updateComment({ owner, repo, comment_id: commentId, body })
63
- } else {
64
- const { data: comment } = await github.rest.issues.createComment({ owner, repo, issue_number, body })
65
- commentId = comment?.id
66
- }
67
-
68
- return commentId
69
- {{> stepChecks jobCheck=(obj name="Release" sha="steps.release.outputs.pr-sha") }}
70
-
71
- update:
72
- needs: release
73
- outputs:
74
- sha: $\{{ steps.commit.outputs.sha }}
75
- check-id: $\{{ steps.check.outputs.check_id }}
76
- {{> job
77
- jobName="Update - Release"
78
- jobIf="needs.release.outputs.pr"
79
- jobCheckout=(obj ref="${{ needs.release.outputs.branch }}" fetch-depth=0)
80
- }}
81
- - name: Run Post Pull Request Actions
82
- env:
83
- RELEASE_PR_NUMBER: $\{{ needs.release.outputs.pr-number }}
84
- RELEASE_COMMENT_ID: $\{{ needs.release.outputs.comment-id }}
85
- GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
86
- run: |
87
- {{ rootNpmPath }} exec --offline -- template-oss-release-manager --lockfile={{ lockfile }} --publish={{ publish }}
88
- {{ rootNpmPath }} run rp-pull-request --ignore-scripts {{~#if allFlags}} {{ allFlags }}{{else}} --if-present{{/if}}
89
- - name: Commit
90
- id: commit
91
- env:
92
- GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
93
- run: |
94
- git commit --all --amend --no-edit || true
95
- git push --force-with-lease
96
- echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
97
- {{> stepChecks jobName="Update - Release" jobCheck=(obj sha="steps.commit.outputs.sha" name="Release" )}}
98
- {{> stepChecks jobCheck=(obj id="needs.release.outputs.check-id" )}}
99
-
100
- ci:
101
- name: CI - Release
102
- needs: [release, update]
103
- if: needs.release.outputs.pr
104
- uses: ./.github/workflows/ci-release.yml
105
- with:
106
- ref: $\{{ needs.release.outputs.branch }}
107
- check-sha: $\{{ needs.update.outputs.sha }}
108
-
109
- post-ci:
110
- needs: [release, update, ci]
111
- {{> job jobName="Post CI - Release" jobIf="needs.release.outputs.pr && always()" jobSkipSetup=true }}
112
- - name: Get Needs Result
113
- id: needs-result
114
- run: |
115
- result=""
116
- if [[ "$\{{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
117
- result="failure"
118
- elif [[ "$\{{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
119
- result="cancelled"
120
- else
121
- result="success"
122
- fi
123
- echo "result=$result" >> $GITHUB_OUTPUT
124
- {{> stepChecks jobCheck=(obj id="needs.update.outputs.check-id" status="steps.needs-result.outputs.result") }}
125
-
126
- post-release:
127
- needs: release
128
- {{> job jobName="Post Release - Release" jobIf="needs.release.outputs.releases" jobSkipSetup=true }}
129
- - name: Create Release PR Comment
130
- uses: actions/github-script@v6
131
- env:
132
- RELEASES: $\{{ needs.release.outputs.releases }}
133
- with:
134
- script: |
135
- const releases = JSON.parse(process.env.RELEASES)
136
- const { runId, repo: { owner, repo } } = context
137
- const issue_number = releases[0].prNumber
138
-
139
- let body = '## Release Workflow\n\n'
140
- for (const { pkgName, version, url } of releases) {
141
- body += `- \`${pkgName}@${version}\` ${url}\n`
142
- }
143
-
144
- const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
145
- .then(cs => cs.map(c => ({ id: c.id, login: c.user.login, body: c.body })))
146
- console.log(`Found comments: ${JSON.stringify(comments, null, 2)}`)
147
- const releaseComments = comments.filter(c => c.login === 'github-actions[bot]' && c.body.includes('Release is at'))
148
-
149
- for (const comment of releaseComments) {
150
- console.log(`Release comment: ${JSON.stringify(comment, null, 2)}`)
151
- await github.rest.issues.deleteComment({ owner, repo, comment_id: comment.id })
152
- }
153
-
154
- const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}`
155
- await github.rest.issues.createComment({
156
- owner,
157
- repo,
158
- issue_number,
159
- body: `${body}- Workflow run: :arrows_counterclockwise: ${runUrl}`,
160
- })
161
-
162
- release-integration:
163
- needs: release
164
- name: Release Integration
165
- if: needs.release.outputs.release
166
- {{> jobReleaseIntegration }}
167
-
168
- post-release-integration:
169
- needs: [release, release-integration]
170
- {{> job jobName="Post Release Integration - Release" jobIf="needs.release.outputs.release && always()" jobSkipSetup=true }}
171
- - name: Get Needs Result
172
- id: needs-result
173
- run: |
174
- if [[ "$\{{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
175
- result="x"
176
- elif [[ "$\{{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
177
- result="heavy_multiplication_x"
178
- else
179
- result="white_check_mark"
180
- fi
181
- echo "result=$result" >> $GITHUB_OUTPUT
182
- - name: Update Release PR Comment
183
- uses: actions/github-script@v6
184
- env:
185
- PR_NUMBER: $\{{ fromJSON(needs.release.outputs.release).prNumber }}
186
- RESULT: $\{{ steps.needs-result.outputs.result }}
187
- with:
188
- script: |
189
- const { PR_NUMBER: issue_number, RESULT } = process.env
190
- const { runId, repo: { owner, repo } } = context
191
-
192
- const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number })
193
- const updateComment = comments.find(c =>
194
- c.user.login === 'github-actions[bot]' &&
195
- c.body.startsWith('## Release Workflow\n\n') &&
196
- c.body.includes(runId)
197
- )
198
-
199
- if (updateComment) {
200
- console.log('Found comment to update:', JSON.stringify(updateComment, null, 2))
201
- let body = updateComment.body.replace(/Workflow run: :[a-z_]+:/, `Workflow run: :${RESULT}:`)
202
- const tagCodeowner = RESULT !== 'white_check_mark'
203
- if (tagCodeowner) {
204
- body += `\n\n:rotating_light:`
205
- body += ` {{ codeowner }}: The post-release workflow failed for this release.`
206
- body += ` Manual steps may need to be taken after examining the workflow output`
207
- body += ` from the above workflow run. :rotating_light:`
208
- }
209
- await github.rest.issues.updateComment({
210
- owner,
211
- repo,
212
- body,
213
- comment_id: updateComment.id,
214
- })
215
- } else {
216
- console.log('No matching comments found:', JSON.stringify(comments, null, 2))
217
- }
@@ -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
- }