@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 CHANGED
@@ -123,3 +123,23 @@ trivial to swap out this content directory for a different one as it is only
123
123
  referenced in a single place in `lib/config.js`. However, it's not currently
124
124
  possible to change this value at runtime, but that might become possible in
125
125
  future versions of this package.
126
+
127
+ ### Testing
128
+
129
+ The files `test/release/release-manager.js` and `test/release/release-please.js`
130
+ use recorded `nock` fixtures to generate snapshots. To update these fixtures run:
131
+
132
+ ```sh
133
+ GITHUB_TOKEN=$(gh auth token) npm run test:record --- test/release/release-{please,manager}.js
134
+ ```
135
+
136
+ If you only need to update fixtures for one, it's best to only run that single
137
+ test file.
138
+
139
+ #### `test/release/release-please.js`
140
+
141
+ This test file uses the repo `npm/npm-cli-release-please` to record its
142
+ fixtures. It expects `https://github.com/npm/npm-cli-release-please` to be
143
+ checked out in a sibling directory to this repo. It also needs the current
144
+ branch set to `template-oss-mock-testing-branch-do-not-delete` before the tests
145
+ are run.
@@ -1,283 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { Octokit } = require('@octokit/rest')
4
- const semver = require('semver')
5
- const mapWorkspaces = require('@npmcli/map-workspaces')
6
- const { join } = require('path')
3
+ const core = require('@actions/core')
4
+ const { parseArgs } = require('util')
5
+ const ReleaseManager = require('../lib/release/release-manager')
7
6
 
8
- const log = (...logs) => console.error('LOG', ...logs)
9
-
10
- const ROOT = process.cwd()
11
- const pkg = require(join(ROOT, 'package.json'))
12
-
13
- const args = process.argv.slice(2).reduce((acc, a) => {
14
- const [k, v] = a.replace(/^--/g, '').split('=')
15
- acc[k] = v === 'true'
16
- return acc
17
- }, {})
18
-
19
- /* eslint-disable max-len */
20
- const MANUAL_PUBLISH_STEPS = `
21
- 1. Checkout the release branch and test
22
-
23
- \`\`\`sh
24
- gh pr checkout <PR-NUMBER> --force
25
- npm ${args.lockfile ? 'ci' : 'update'}
26
- npm test
27
- gh pr checks <PR-NUMBER> -R {NWO} --watch
28
- \`\`\`
29
-
30
- 1. Publish workspaces
31
-
32
- \`\`\`sh
33
- npm publish -w <WS-PKG-N>
34
- \`\`\`
35
-
36
- 1. Publish
37
-
38
- \`\`\`sh
39
- npm publish <PUBLISH-FLAGS>
40
- \`\`\`
41
-
42
- 1. Merge release PR
43
-
44
- \`\`\`sh
45
- gh pr merge <PR-NUMBER> -R {NWO} --rebase
46
- git checkout <BASE-BRANCH>
47
- git fetch
48
- git reset --hard origin/<BASE-BRANCH>
49
- \`\`\`
50
- `
51
-
52
- const AUTO_PUBLISH_STEPS = `
53
- 1. Approve this PR
54
-
55
- \`\`\`sh
56
- gh pr review <PR-NUMBER> -R {NWO} --approve
57
- \`\`\`
58
-
59
- 1. Merge release PR :rotating_light: Merging this will auto publish :rotating_light:
60
-
61
- \`\`\`sh
62
- gh pr merge <PR-NUMBER> -R {NWO} --rebase
63
- \`\`\`
64
- `
65
-
66
- const DEFAULT_RELEASE_PROCESS = (args.publish ? AUTO_PUBLISH_STEPS : MANUAL_PUBLISH_STEPS) + `
67
- 1. Check For Release Tags
68
-
69
- Release Please will run on the just pushed release commit and create GitHub releases and tags for each package.
70
-
71
- \`\`\`
72
- gh run watch -R {NWO} $(gh run list -R {NWO} -w release -b <BASE-BRANCH> -L 1 --json databaseId -q ".[0].databaseId")
73
- \`\`\`
74
- `
75
- /* eslint-enable max-len */
76
-
77
- const getReleaseProcess = async ({ owner, repo }) => {
78
- const RELEASE_LIST_ITEM = /^\d+\.\s/gm
79
-
80
- log(`Fetching release process from:`, owner, repo, 'wiki')
81
-
82
- let releaseProcess = ''
83
- try {
84
- releaseProcess = await new Promise((resolve, reject) => {
85
- require('https')
86
- .get(`https://raw.githubusercontent.com/wiki/${owner}/${repo}/Release-Process.md`, resp => {
87
- let d = ''
88
- resp.on('data', c => (d += c))
89
- resp.on('end', () => {
90
- if (resp.statusCode !== 200) {
91
- reject(new Error(`${resp.req.protocol + resp.req.host + resp.req.path}: ${d}`))
92
- } else {
93
- resolve(d)
94
- }
95
- })
96
- })
97
- .on('error', reject)
98
- })
99
- } catch (e) {
100
- log('Release wiki not found', e.message)
101
- log('Using default release process')
102
- releaseProcess = DEFAULT_RELEASE_PROCESS.replace(/\{NWO\}/g, `${owner}/${repo}`).trim() + '\n'
103
- }
104
-
105
- // XXX: the release steps need to always be the last thing in the doc for this to work
106
- const releaseLines = releaseProcess.split('\n')
107
- const releaseStartLine = releaseLines.reduce((acc, line, index) =>
108
- line.match(/^#+\s/) ? index : acc, 0)
109
- const section = releaseLines.slice(releaseStartLine).join('\n')
110
-
111
- return section.split({
112
- [Symbol.split] (str) {
113
- const [, ...matches] = str.split(RELEASE_LIST_ITEM)
114
- log(`Found ${matches.length} release items`)
115
- return matches.map((m) => `- [ ] <STEP_INDEX>. ${m}`.trim())
116
- },
117
- })
118
- }
119
-
120
- const getPrReleases = async (pr) => {
121
- const RELEASE_SEPARATOR = /<details><summary>.*<\/summary>/g
122
- const MONO_VERSIONS = /<details><summary>(?:(.*?):\s)?(.*?)<\/summary>/
123
- const ROOT_VERSION = /\n##\s\[(.*?)\]/
124
-
125
- const workspaces = [...await mapWorkspaces({ pkg: pkg, cwd: ROOT })].reduce((acc, [k]) => {
126
- const wsComponentName = k.startsWith('@') ? k.split('/')[1] : k
127
- acc[wsComponentName] = k
128
- return acc
129
- }, {})
130
-
131
- const getReleaseInfo = ({ name, version: rawVersion }) => {
132
- const version = semver.parse(rawVersion)
133
- const prerelease = !!version.prerelease.length
134
- const tag = `${name ? `${name}-` : ''}v${rawVersion}`
135
- const workspace = workspaces[name]
136
-
137
- return {
138
- name,
139
- tag,
140
- prerelease,
141
- version: rawVersion,
142
- major: version.major,
143
- url: `https://github.com/${pr.base.repo.full_name}/releases/tag/${tag}`,
144
- flags: `${name ? `-w ${workspace}` : ''} ${prerelease ? `--tag prerelease` : ''}`.trim(),
145
- }
146
- }
147
-
148
- const releases = pr.body.match(RELEASE_SEPARATOR)
149
-
150
- if (!releases) {
151
- log('Found no monorepo, checking for single root version')
152
- const [, version] = pr.body.match(ROOT_VERSION) || []
153
-
154
- if (!version) {
155
- throw new Error('Could not find version with:', ROOT_VERSION)
156
- }
157
-
158
- log('Found version', version)
159
- return [getReleaseInfo({ version })]
160
- }
161
-
162
- log(`Found ${releases.length} releases`)
163
-
164
- return releases.reduce((acc, r) => {
165
- const [, name, version] = r.match(MONO_VERSIONS)
166
- const release = getReleaseInfo({ name, version })
167
-
168
- if (!name) {
169
- log('Found root', release)
170
- acc[0] = release
171
- } else {
172
- log('Found workspace', release)
173
- acc[1].push(release)
174
- }
175
-
176
- return acc
177
- }, [null, []])
178
- }
179
-
180
- const appendToComment = async ({ github, commentId, title, body }) => {
181
- if (!commentId) {
182
- log(`No comment id, skipping append to comment`)
183
- return
184
- }
185
-
186
- const { data: comment } = await github.rest.issues.getComment({
187
- ...github.repo,
188
- comment_id: commentId,
189
- })
190
-
191
- const hasAppended = comment.body.includes(title)
192
-
193
- log('Found comment with id:', commentId)
194
- log(hasAppended ? 'Comment has aready been appended, replacing' : 'Appending to comment')
195
-
196
- const prefix = hasAppended
197
- ? comment.body.split(title)[0]
198
- : comment.body
199
-
200
- return github.rest.issues.updateComment({
201
- ...github.repo,
202
- comment_id: commentId,
203
- body: [prefix, title, body].join('\n\n'),
204
- })
205
- }
206
-
207
- const main = async (env) => {
7
+ ReleaseManager.run({
208
8
  // These env vars are set by the release.yml workflow from template-oss
209
- const {
210
- CI,
211
- GITHUB_TOKEN,
212
- GITHUB_REPOSITORY,
213
- RELEASE_PR_NUMBER,
214
- RELEASE_COMMENT_ID, // comment is optional for testing
215
- } = env
216
-
217
- if (!CI || !GITHUB_TOKEN || !GITHUB_REPOSITORY || !RELEASE_PR_NUMBER) {
218
- throw new Error('This script is designed to run in CI. If you want to test it, set the ' +
219
- `following env vars: \`CI, GITHUB_TOKEN, GITHUB_REPOSITORY, RELEASE_PR_NUMBER\``)
220
- }
221
-
222
- const [owner, repo] = GITHUB_REPOSITORY.split('/')
223
- const github = new Octokit({ auth: GITHUB_TOKEN })
224
- github.repo = { owner, repo }
225
-
226
- const { data: pr } = await github.rest.pulls.get({
227
- ...github.repo,
228
- pull_number: RELEASE_PR_NUMBER,
9
+ token: process.env.GITHUB_TOKEN,
10
+ repo: process.env.GITHUB_REPOSITORY,
11
+ cwd: process.cwd(),
12
+ ...parseArgs({
13
+ options: {
14
+ pr: { type: 'string' },
15
+ backport: { type: 'string' },
16
+ defaultTag: { type: 'string' },
17
+ lockfile: { type: 'boolean' },
18
+ publish: { type: 'boolean' },
19
+ },
20
+ }).values,
21
+ })
22
+ .then((result) => {
23
+ core.setOutput('result', result)
24
+ return null
229
25
  })
230
-
231
- const [release, workspaces = []] = await getPrReleases(pr)
232
-
233
- const RELEASE_OMIT_PRERELEASE = '> NOT FOR PRERELEASE'
234
- const RELEASE_OMIT_WORKSPACES = 'Publish workspaces'
235
- const releaseItems = (await getReleaseProcess({ owner, repo }))
236
- .filter((item) => {
237
- if (release.prerelease && item.includes(RELEASE_OMIT_PRERELEASE)) {
238
- return false
239
- }
240
-
241
- if (!workspaces.length && item.includes(RELEASE_OMIT_WORKSPACES)) {
242
- return false
243
- }
244
-
245
- return true
246
- })
247
- .map((item, index) => item.replace('<STEP_INDEX>', index + 1))
248
-
249
- log(
250
- `Filtered ${releaseItems.length} release process items:\n`,
251
- releaseItems.map(r => r.split('\n')[0].replace('- [ ] ', '')).join(', ')
252
- )
253
-
254
- const releaseTitle = `### Release Checklist for ${release.tag}`
255
- const releaseChecklist = releaseItems
256
- .join('\n\n')
257
- .replace(/<PR-NUMBER>/g, RELEASE_PR_NUMBER)
258
- .replace(/<RELEASE-BRANCH>/g, pr.head.ref)
259
- .replace(/<BASE-BRANCH>/g, pr.base.ref)
260
- .replace(/<MAJOR>/g, release.major)
261
- .replace(/<X\.Y\.Z>/g, release.version)
262
- .replace(/<GITHUB-RELEASE-LINK>/g, release.url)
263
- .replace(/<PUBLISH-FLAGS>/g, release.flags)
264
- .replace(/^(\s*\S.*)(-w <WS-PKG-N>)$/gm, workspaces.map(w => `$1${w.flags}`).join('\n'))
265
- .trim()
266
-
267
- await appendToComment({
268
- github,
269
- commentId: RELEASE_COMMENT_ID,
270
- title: releaseTitle,
271
- body: releaseChecklist,
26
+ .catch(err => {
27
+ core.setFailed('Release Manager failed')
28
+ core.error(err)
272
29
  })
273
-
274
- if (!RELEASE_COMMENT_ID) {
275
- console.log(releaseChecklist)
276
- }
277
- }
278
-
279
- main(process.env)
280
- // This is part of the release CI and is for posting a release manager
281
- // comment to the issue but we dont want it to ever fail the workflow so
282
- // just log but dont set the error code
283
- .catch(err => console.error(err))
@@ -1,75 +1,40 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const core = require('@actions/core')
4
- const main = require('../lib/release-please/index.js')
4
+ const { parseArgs } = require('util')
5
+ const ReleasePlease = require('../lib/release/release-please.js')
5
6
 
6
- const dryRun = !process.env.CI
7
- const [branch, forcePullRequest] = process.argv.slice(2)
8
-
9
- const debugPr = (val) => {
10
- if (dryRun) {
11
- console.log('PR:', val.title.toString())
12
- console.log('='.repeat(40))
13
- console.log(val.body.toString())
14
- console.log('='.repeat(40))
15
- for (const update of val.updates.filter(u => u.updater.changelogEntry)) {
16
- console.log('CHANGELOG:', update.path)
17
- console.log('-'.repeat(40))
18
- console.log(update.updater.changelogEntry)
19
- console.log('-'.repeat(40))
20
- }
21
- for (const update of val.updates.filter(u => u.updater.rawContent)) {
22
- console.log('package:', update.path)
23
- console.log('-'.repeat(40))
24
- console.log(JSON.parse(update.updater.rawContent).name)
25
- console.log(JSON.parse(update.updater.rawContent).version)
26
- console.log('-'.repeat(40))
27
- }
28
- }
29
- }
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
-
43
- main({
7
+ ReleasePlease.run({
44
8
  token: process.env.GITHUB_TOKEN,
45
9
  repo: process.env.GITHUB_REPOSITORY,
46
- dryRun,
47
- branch,
48
- forcePullRequest: forcePullRequest ? +forcePullRequest : null,
49
- }).then(({ pr, release, releases }) => {
10
+ ...parseArgs({
11
+ options: {
12
+ branch: { type: 'string' },
13
+ backport: { type: 'string' },
14
+ defaultTag: { type: 'string' },
15
+ },
16
+ }).values,
17
+ // This is mostly for testing and debugging. Use environs with the format
18
+ // `RELEASE_PLEASE_<manfiestOverrideConfigName>`
19
+ // (eg`RELEASE_PLEASE_lastReleaseSha=<SHA>`) to set one-off config items for
20
+ // the release please run without needing to commit and push the config.
21
+ overrides: Object.fromEntries(Object.entries(process.env)
22
+ .filter(([k, v]) => k.startsWith('RELEASE_PLEASE_') && v != null)
23
+ .map(([k, v]) => [k.replace('RELEASE_PLEASE_', ''), v])),
24
+ }).then(({ pr, releases }) => {
50
25
  if (pr) {
51
- debugPr(pr)
52
26
  core.setOutput('pr', JSON.stringify(pr))
53
27
  core.setOutput('pr-branch', pr.headBranchName)
54
28
  core.setOutput('pr-number', pr.number)
55
29
  core.setOutput('pr-sha', pr.sha)
56
30
  }
57
31
 
58
- if (release) {
59
- debugRelease(release)
60
- core.setOutput('release', JSON.stringify(release))
61
- }
62
-
63
32
  if (releases) {
64
- debugReleases(releases)
65
33
  core.setOutput('releases', JSON.stringify(releases))
66
34
  }
67
35
 
68
36
  return null
69
37
  }).catch(err => {
70
- if (dryRun) {
71
- console.error(err)
72
- } else {
73
- core.setFailed(`failed: ${err}`)
74
- }
38
+ core.setFailed('Release Please failed')
39
+ core.error(err)
75
40
  })
package/lib/config.js CHANGED
@@ -119,7 +119,6 @@ const getFullConfig = async ({
119
119
  const gitBranches = await git.getBranches(rootPkg.path, branches)
120
120
  const defaultBranch = await git.defaultBranch(rootPkg.path) ?? 'main'
121
121
  const isReleaseBranch = !!pkgConfig.backport
122
- const publishTag = isReleaseBranch ? `next-${pkgConfig.backport}` : 'latest'
123
122
  const releaseBranch = isReleaseBranch
124
123
  ? pkgConfig.releaseBranch.replace(/\*/g, pkgConfig.backport)
125
124
  : defaultBranch
@@ -148,7 +147,6 @@ const getFullConfig = async ({
148
147
  branchPatterns: gitBranches.patterns,
149
148
  isReleaseBranch,
150
149
  releaseBranch,
151
- publishTag,
152
150
  dependabot: parseDependabot(pkgConfig, defaultConfig, gitBranches.branches),
153
151
  // paths
154
152
  repoDir: rootPkg.path,
@@ -168,6 +166,7 @@ const getFullConfig = async ({
168
166
  deleteJsExt: esm ? 'js' : 'cjs',
169
167
  // tap
170
168
  tap18: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major === 18,
169
+ tap16: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major === 16,
171
170
  // booleans to control application of updates
172
171
  isForce,
173
172
  isDogFood,
@@ -199,12 +198,14 @@ const getFullConfig = async ({
199
198
 
200
199
  if (pkgConfig.typescript) {
201
200
  defaultsDeep(pkgConfig, { allowPaths: [], requiredPackages: { devDependencies: [] } })
202
- pkgConfig.distPaths = null
201
+ pkgConfig.distPaths = ['dist/']
202
+ pkgConfig.allowDistPaths = false
203
203
  pkgConfig.allowPaths.push('/src/')
204
204
  pkgConfig.requiredPackages.devDependencies.push(
205
205
  'typescript',
206
206
  'tshy',
207
- '@typescript-eslint/parser'
207
+ '@typescript-eslint/parser',
208
+ ...derived.tap16 ? ['c8', 'ts-node'] : []
208
209
  )
209
210
  }
210
211
 
@@ -254,7 +255,7 @@ const getFullConfig = async ({
254
255
  ]),
255
256
  ...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
256
257
  ...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
257
- ...(pkgConfig.distPaths || []).map((p) => `!/${p}`),
258
+ ...(pkgConfig.allowDistPaths ? pkgConfig.distPaths : []).map((p) => `!/${p}`),
258
259
  ...(pkgConfig.ignorePaths || []),
259
260
  ]),
260
261
  // these cant be sorted since they rely on order
@@ -1,59 +1,51 @@
1
- {{#if publish}}
1
+ name: {{#if publish}}Publish{{else}}Check Publish{{/if}}
2
2
  runs-on: ubuntu-latest
3
3
  defaults:
4
4
  run:
5
5
  shell: bash
6
+ {{#if publish}}
6
7
  permissions:
7
- deployments: write
8
8
  id-token: write
9
+ {{/if}}
9
10
  steps:
10
- - name: Checkout
11
- uses: actions/checkout@v3
12
- with:
13
- ref: $\{{ fromJSON(needs.release.outputs.release).tagName }}
14
- - name: Setup Node
15
- uses: actions/setup-node@v3
16
- with:
17
- node-version: 18.x
18
- - name: Install npm@latest
19
- run: |
20
- npm i --prefer-online --no-fund --no-audit -g npm@latest
21
- npm config set '//registry.npmjs.org/:_authToken'=\${PUBLISH_TOKEN}
11
+ {{#if publish}}
12
+ {{> stepsSetupYml jobCheckout=(obj ref="${{ fromJSON(inputs.releases)[0].tagName }}") }}
13
+ - name: Set npm authToken
14
+ run: npm config set '//registry.npmjs.org/:_authToken'=\${PUBLISH_TOKEN}
22
15
  - name: Publish
23
16
  env:
24
17
  PUBLISH_TOKEN: $\{{ secrets.PUBLISH_TOKEN }}
25
- run: npm publish --provenance --tag={{ publishTag }}
26
- {{else}}
27
- runs-on: ubuntu-latest
28
- defaults:
29
- run:
30
- shell: bash
31
- steps:
32
- {{> stepNodeYml lockfile=false }}
33
- - name: View in Registry
18
+ {{else}}
19
+ {{> stepsSetupYml }}
20
+ - name: Check If Published
21
+ {{/if}}
34
22
  run: |
35
23
  EXIT_CODE=0
36
24
 
37
- function is_published {
38
- if npm view "$@" --loglevel=error > /dev/null; then
25
+ function each_release {
26
+ if {{#if publish}}npm publish --provenance --tag="$1"{{else}}npm view "$@" --loglevel=error > /dev/null{{/if}}; then
39
27
  echo 0
40
28
  else
41
29
  echo 1
42
30
  fi
43
31
  }
44
32
 
45
- for release in $(echo '$\{{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do
46
- name=$(echo "$release" | base64 --decode | jq -r .pkgName)
47
- version=$(echo "$release" | base64 --decode | jq -r .version)
48
- spec="$name@$version"
49
- status=$(is_published "$spec")
50
- if [[ "$status" -eq 1 ]]; then
51
- echo "$spec ERROR"
52
- EXIT_CODE=$status
33
+ for release in $(echo '$\{{ inputs.releases }}' | jq -r '.[] | @base64'); do
34
+ {{#if publish}}
35
+ PUBLISH_TAG=$(echo "$release" | base64 --decode | jq -r .publishTag)
36
+ STATUS=$(each_release "$PUBLISH_TAG")
37
+ {{else}}
38
+ SPEC="$(echo "$release" | base64 --decode | jq -r .pkgName)@$(echo "$release" | base64 --decode | jq -r .version)"
39
+ STATUS=$(each_release "$SPEC")
40
+ {{/if}}
41
+ if [[ "$STATUS" -eq 1 ]]; then
42
+ EXIT_CODE=$STATUS
43
+ {{#unless publish}}
44
+ echo "$SPEC ERROR"
53
45
  else
54
- echo "$spec OK"
46
+ echo "$SPEC OK"
47
+ {{/unless}}
55
48
  fi
56
49
  done
57
50
 
58
51
  exit $EXIT_CODE
59
- {{/if}}
@@ -7,54 +7,9 @@
7
7
  {{#if lockfile}}
8
8
  cache: npm
9
9
  {{/if}}
10
-
11
10
  {{#if updateNpm}}
12
- {{#if jobIsMatrix}}
13
- # node 10/12/14 ship with npm@6, which is known to fail when updating itself in windows
14
- - name: Update Windows npm
15
- if: |
16
- matrix.platform.os == 'windows-latest' && (
17
- startsWith(steps.node.outputs.node-version, 'v10.') ||
18
- startsWith(steps.node.outputs.node-version, 'v12.') ||
19
- startsWith(steps.node.outputs.node-version, 'v14.')
20
- )
21
- run: |
22
- curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz
23
- tar xf npm-7.5.4.tgz
24
- cd package
25
- node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
26
- cd ..
27
- rmdir /s /q package
28
- {{/if}}
29
-
30
11
  - name: Install Latest npm
31
- shell: bash
32
- env:
33
- NODE_VERSION: $\{{ steps.node.outputs.node-version }}
34
- run: |
35
- MATCH=""
36
- SPECS=("latest" "next-10" "next-9" "next-8" "next-7" "next-6")
37
-
38
- echo "node@$NODE_VERSION"
39
-
40
- for SPEC in ${SPECS[@]}; do
41
- ENGINES=$(npm view npm@$SPEC --json | jq -r '.engines.node')
42
- echo "Checking if node@$NODE_VERSION satisfies npm@$SPEC ($ENGINES)"
43
-
44
- if npx semver -r "$ENGINES" "$NODE_VERSION" > /dev/null; then
45
- MATCH=$SPEC
46
- echo "Found compatible version: npm@$MATCH"
47
- break
48
- fi
49
- done
50
-
51
- if [ -z $MATCH ]; then
52
- echo "Could not find a compatible version of npm for node@$NODE_VERSION"
53
- exit 1
54
- fi
55
-
56
- npm i --prefer-online --no-fund --no-audit -g npm@$MATCH
57
-
58
- - name: npm Version
59
- run: npm -v
12
+ uses: ./.github/actions/install-latest-npm
13
+ with:
14
+ node: $\{{ steps.node.outputs.node-version }}
60
15
  {{/if}}
@@ -1,6 +1,15 @@
1
- {{~#if jobCheck}}{{> stepChecksYml }}{{/if}}
2
1
  {{~#unless jobSkipSetup}}
3
2
  {{> stepGitYml }}
3
+ {{~#if jobCreateCheck}}
4
+ - name: Create Check
5
+ id: create-check
6
+ if: {{ jobCreateCheck.sha }}
7
+ uses: ./.github/actions/create-check
8
+ with:
9
+ name: "{{ jobName }}{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}"
10
+ token: $\{{ secrets.GITHUB_TOKEN }}
11
+ sha: {{ jobCreateCheck.sha }}
12
+ {{/if}}
4
13
  {{> stepNodeYml }}
5
14
  {{> stepDepsYml }}
6
15
  {{/unless}}
@@ -0,0 +1,50 @@
1
+ name: 'Create Check'
2
+ inputs:
3
+ name:
4
+ required: true
5
+ token:
6
+ required: true
7
+ sha:
8
+ required: true
9
+ check-name:
10
+ default: ''
11
+ outputs:
12
+ check-id:
13
+ value: $\{{ steps.create-check.outputs.check_id }}
14
+ runs:
15
+ using: "composite"
16
+ steps:
17
+ - name: Get Workflow Job
18
+ uses: actions/github-script@v6
19
+ id: workflow
20
+ env:
21
+ JOB_NAME: "$\{{ inputs.name }}"
22
+ SHA: "$\{{ inputs.sha }}"
23
+ with:
24
+ result-encoding: string
25
+ script: |
26
+ const { repo: { owner, repo}, runId, serverUrl } = context
27
+ const { JOB_NAME, SHA } = process.env
28
+
29
+ const job = await github.rest.actions.listJobsForWorkflowRun({
30
+ owner,
31
+ repo,
32
+ run_id: runId,
33
+ per_page: 100
34
+ }).then(r => r.data.jobs.find(j => j.name.endsWith(JOB_NAME)))
35
+
36
+ return [
37
+ `This check is assosciated with ${serverUrl}/${owner}/${repo}/commit/${SHA}.`,
38
+ 'Run logs:',
39
+ job?.html_url || `could not be found for a job ending with: "${JOB_NAME}"`,
40
+ ].join(' ')
41
+ - name: Create Check
42
+ uses: LouisBrunner/checks-action@v1.6.0
43
+ id: create-check
44
+ with:
45
+ token: $\{{ inputs.token }}
46
+ sha: $\{{ inputs.sha }}
47
+ status: in_progress
48
+ name: $\{{ inputs.check-name || inputs.name }}
49
+ output: |
50
+ {"summary":"$\{{ steps.workflow.outputs.result }}"}