@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
package/lib/config.js CHANGED
@@ -1,18 +1,22 @@
1
- const { relative, dirname, join, extname, posix, win32 } = require('path')
2
- const { defaults, pick, omit, uniq, isPlainObject } = require('lodash')
1
+ const { relative, dirname, join, extname } = require('path')
2
+ const { defaults, defaultsDeep, pick, omit, uniq, isPlainObject } = require('lodash')
3
+ const semver = require('semver')
3
4
  const ciVersions = require('./util/ci-versions.js')
4
5
  const parseDependabot = require('./util/dependabot.js')
5
6
  const git = require('./util/git.js')
6
7
  const gitignore = require('./util/gitignore.js')
7
8
  const { mergeWithCustomizers, customizers } = require('./util/merge.js')
8
9
  const { FILE_KEYS, parseConfig: parseFiles, getAddedFiles, mergeFiles } = require('./util/files.js')
10
+ const template = require('./util/template.js')
11
+ const getCmdPath = require('./util/get-cmd-path.js')
12
+ const importOrRequire = require('./util/import-or-require.js')
13
+ const { makePosix, deglob, posixDir, posixGlob } = require('./util/path.js')
14
+ const { name: NAME, version: LATEST_VERSION } = require('../package.json')
9
15
 
10
16
  const CONFIG_KEY = 'templateOSS'
11
- const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {}
12
-
13
- const { name: NAME, version: LATEST_VERSION } = require('../package.json')
14
17
  const MERGE_KEYS = [...FILE_KEYS, 'defaultContent', 'content']
15
18
  const DEFAULT_CONTENT = require.resolve(NAME)
19
+ const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {}
16
20
 
17
21
  const merge = mergeWithCustomizers(
18
22
  customizers.mergeArrays('branches', 'distPaths', 'allowPaths', 'ignorePaths'),
@@ -23,43 +27,6 @@ const merge = mergeWithCustomizers(
23
27
  }
24
28
  )
25
29
 
26
- const makePosix = (v) => v.split(win32.sep).join(posix.sep)
27
- const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
28
- const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
29
- const posixGlob = (str) => `${posixDir(str)}**`
30
-
31
- const getCmdPath = (key, { pkgConfig, rootConfig, isRoot, pkg, rootPkg }) => {
32
- const result = (local, isRelative) => {
33
- let root = local
34
- const isLocal = local.startsWith('.') || local.startsWith('/')
35
-
36
- if (isLocal) {
37
- if (isRelative) {
38
- // Make a path relative from a workspace to the root if we are in a workspace
39
- local = makePosix(join(relative(pkg.path, rootPkg.path), local))
40
- }
41
- local = `node ${local}`
42
- root = `node ${root}`
43
- }
44
-
45
- return {
46
- isLocal,
47
- local,
48
- root,
49
- }
50
- }
51
-
52
- if (pkgConfig[key]) {
53
- return result(pkgConfig[key])
54
- }
55
-
56
- if (rootConfig[key]) {
57
- return result(rootConfig[key], !isRoot)
58
- }
59
-
60
- return result(key)
61
- }
62
-
63
30
  const mergeConfigs = (...configs) => {
64
31
  const mergedConfig = merge(...configs.map(c => pick(c, MERGE_KEYS)))
65
32
  return defaults(mergedConfig, {
@@ -72,37 +39,33 @@ const mergeConfigs = (...configs) => {
72
39
  })
73
40
  }
74
41
 
75
- const readContentPath = (path) => {
42
+ const readContentPath = async (path) => {
76
43
  if (!path) {
77
44
  return {}
78
45
  }
79
46
 
80
- let content = {}
81
47
  const index = extname(path) === '.js' ? path : join(path, 'index.js')
82
48
  const dir = dirname(index)
83
-
84
- try {
85
- content = require(index)
86
- } catch {
87
- // its ok if this fails since the content dir
88
- // might only be to provide other files. the
89
- // index.js is optional
90
- }
49
+ const content = await importOrRequire(index)
91
50
 
92
51
  return { content, dir }
93
52
  }
94
53
 
95
- const getConfig = (path, rawConfig) => {
96
- const config = omit(readContentPath(path).content, FILE_KEYS)
54
+ const getConfig = async (path, rawConfig) => {
55
+ const { content } = await readContentPath(path)
56
+ const config = omit(content, FILE_KEYS)
97
57
  return merge(config, rawConfig ? omit(rawConfig, FILE_KEYS) : {})
98
58
  }
99
59
 
100
- const getFiles = (path, rawConfig) => {
101
- const { content, dir } = readContentPath(path)
60
+ const getFiles = async (path, rawConfig, templateSettings) => {
61
+ const { content, dir } = await readContentPath(path)
102
62
  if (!dir) {
103
63
  return []
104
64
  }
105
- return [parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS)), dir]
65
+ return [
66
+ parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS), templateSettings),
67
+ dir,
68
+ ]
106
69
  }
107
70
 
108
71
  const getFullConfig = async ({
@@ -127,39 +90,15 @@ const getFullConfig = async ({
127
90
  // These config items are merged betweent the root and child workspaces and only come from
128
91
  // the package.json because they can be used to read configs from other the content directories
129
92
  const mergedConfig = mergeConfigs(rootPkg.config, pkg.config)
130
-
131
- const defaultConfig = getConfig(DEFAULT_CONTENT)
132
- const [defaultFiles, defaultDir] = getFiles(DEFAULT_CONTENT, mergedConfig)
93
+ const defaultConfig = await getConfig(DEFAULT_CONTENT)
133
94
  const useDefault = mergedConfig.defaultContent && defaultConfig
134
95
 
135
- const rootConfig = getConfig(rootPkg.config.content, rootPkg.config)
136
- const [rootFiles, rootDir] = getFiles(rootPkg.config.content, mergedConfig)
96
+ const rootConfig = await getConfig(rootPkg.config.content, rootPkg.config)
137
97
 
138
98
  // The content config only gets set from the package we are in, it doesn't inherit
139
99
  // anything from the root
140
100
  const rootPkgConfig = merge(useDefault, rootConfig)
141
- const pkgConfig = merge(useDefault, getConfig(pkg.config.content, pkg.config))
142
- const [pkgFiles, pkgDir] = getFiles(mergedConfig.content, mergedConfig)
143
-
144
- // Files get merged in from the default content (that template-oss provides) as well
145
- // as any content paths provided from the root or the workspace
146
- const fileDirs = uniq([useDefault && defaultDir, rootDir, pkgDir].filter(Boolean))
147
- const files = mergeFiles(useDefault && defaultFiles, rootFiles, pkgFiles)
148
- const repoFiles = isRoot ? files.rootRepo : files.workspaceRepo
149
- const moduleFiles = isRoot ? files.rootModule : files.workspaceModule
150
-
151
- const allowRootDirs = [
152
- // Allways allow module files in root or workspaces
153
- ...getAddedFiles(moduleFiles),
154
- ...isRoot ? [
155
- // in the root allow all repo files
156
- ...getAddedFiles(repoFiles),
157
- // and allow all workspace repo level files in the root
158
- ...pkgs
159
- .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false)
160
- .flatMap(() => getAddedFiles(files.workspaceRepo)),
161
- ] : [],
162
- ]
101
+ const pkgConfig = merge(useDefault, await getConfig(pkg.config.content, pkg.config))
163
102
 
164
103
  const npmPath = getCmdPath('npm', { pkgConfig, rootConfig, isRoot, pkg, rootPkg })
165
104
  const npxPath = getCmdPath('npx', { pkgConfig, rootConfig, isRoot, pkg, rootPkg })
@@ -180,11 +119,12 @@ const getFullConfig = async ({
180
119
  const gitBranches = await git.getBranches(rootPkg.path, branches)
181
120
  const defaultBranch = await git.defaultBranch(rootPkg.path) ?? 'main'
182
121
  const isReleaseBranch = !!pkgConfig.backport
183
- const publishTag = isReleaseBranch ? `next-${pkgConfig.backport}` : 'latest'
184
122
  const releaseBranch = isReleaseBranch
185
123
  ? pkgConfig.releaseBranch.replace(/\*/g, pkgConfig.backport)
186
124
  : defaultBranch
187
125
 
126
+ const esm = pkg.pkgJson?.type === 'module' || !!pkgConfig.typescript || !!pkgConfig.esm
127
+
188
128
  // all derived keys
189
129
  const derived = {
190
130
  isRoot,
@@ -207,20 +147,12 @@ const getFullConfig = async ({
207
147
  branchPatterns: gitBranches.patterns,
208
148
  isReleaseBranch,
209
149
  releaseBranch,
210
- publishTag,
211
150
  dependabot: parseDependabot(pkgConfig, defaultConfig, gitBranches.branches),
212
- // repo
151
+ // paths
213
152
  repoDir: rootPkg.path,
214
- repoFiles,
215
- applyRepo: !!repoFiles,
216
- // module
217
153
  moduleDir: pkg.path,
218
- moduleFiles,
219
- applyModule: !!moduleFiles,
220
- // package
221
154
  pkgName: pkg.pkgJson.name,
222
155
  pkgNameFs: pkg.pkgJson.name.replace(/\//g, '-').replace(/@/g, ''),
223
- // paths
224
156
  pkgPath,
225
157
  pkgDir: posixDir(pkgPath),
226
158
  pkgGlob: posixGlob(pkgPath),
@@ -228,6 +160,13 @@ const getFullConfig = async ({
228
160
  allFlags: isMono ? '-ws -iwr --if-present' : '',
229
161
  workspacePaths,
230
162
  workspaceGlobs: workspacePaths.map(posixGlob),
163
+ // type
164
+ esm,
165
+ cjsExt: esm ? 'cjs' : 'js',
166
+ deleteJsExt: esm ? 'js' : 'cjs',
167
+ // tap
168
+ tap18: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major === 18,
169
+ tap16: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major === 16,
231
170
  // booleans to control application of updates
232
171
  isForce,
233
172
  isDogFood,
@@ -243,20 +182,6 @@ const getFullConfig = async ({
243
182
  lockfile: rootPkgConfig.lockfile,
244
183
  // ci versions / engines
245
184
  ciVersions: ciVersions.get(pkg.pkgJson.engines?.node, pkgConfig),
246
- // gitignore
247
- ignorePaths: [
248
- ...gitignore.sort([
249
- ...gitignore.allowRootDir(allowRootDirs),
250
- ...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
251
- ...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
252
- ...(pkgConfig.ignorePaths || []),
253
- ]),
254
- // these cant be sorted since they rely on order
255
- // to allow a previously ignored directoy
256
- ...isRoot
257
- ? gitignore.allowDir(wsPkgs.map((p) => makePosix(relative(rootPkg.path, p.path))))
258
- : [],
259
- ],
260
185
  // needs update if we are dogfooding this repo, with force argv, or its
261
186
  // behind the current version
262
187
  needsUpdate: isForce || isDogFood || !isLatest,
@@ -264,15 +189,24 @@ const getFullConfig = async ({
264
189
  __NAME__: NAME,
265
190
  __CONFIG_KEY__: CONFIG_KEY,
266
191
  __VERSION__: LATEST_VERSION,
267
- __PARTIAL_DIRS__: fileDirs,
268
192
  }
269
193
 
270
- if (!pkgConfig.eslint) {
271
- derived.ignorePaths = derived.ignorePaths.filter(p => !p.includes('eslint'))
272
- if (Array.isArray(pkgConfig.requiredPackages?.devDependencies)) {
273
- pkgConfig.requiredPackages.devDependencies =
274
- pkgConfig.requiredPackages.devDependencies.filter(p => !p.includes('eslint'))
275
- }
194
+ if (!pkgConfig.eslint && Array.isArray(pkgConfig.requiredPackages?.devDependencies)) {
195
+ pkgConfig.requiredPackages.devDependencies =
196
+ pkgConfig.requiredPackages.devDependencies.filter(p => !p.includes('eslint'))
197
+ }
198
+
199
+ if (pkgConfig.typescript) {
200
+ defaultsDeep(pkgConfig, { allowPaths: [], requiredPackages: { devDependencies: [] } })
201
+ pkgConfig.distPaths = ['dist/']
202
+ pkgConfig.allowDistPaths = false
203
+ pkgConfig.allowPaths.push('/src/')
204
+ pkgConfig.requiredPackages.devDependencies.push(
205
+ 'typescript',
206
+ 'tshy',
207
+ '@typescript-eslint/parser',
208
+ ...derived.tap16 ? ['c8', 'ts-node'] : []
209
+ )
276
210
  }
277
211
 
278
212
  const gitUrl = await git.getUrl(rootPkg.path)
@@ -284,10 +218,55 @@ const getFullConfig = async ({
284
218
  }
285
219
  }
286
220
 
287
- return {
288
- ...pkgConfig,
289
- ...derived,
290
- }
221
+ const fullConfig = { ...pkgConfig, ...derived }
222
+
223
+ // files, come at the end since file names can be based on config
224
+ const [defaultFiles, defaultDir] = await getFiles(DEFAULT_CONTENT, mergedConfig, fullConfig)
225
+ const [rootFiles, rootDir] = await getFiles(rootPkg.config.content, mergedConfig, fullConfig)
226
+ const [pkgFiles, pkgDir] = await getFiles(mergedConfig.content, mergedConfig, fullConfig)
227
+
228
+ // Files get merged in from the default content (that template-oss provides) as well
229
+ // as any content paths provided from the root or the workspace
230
+ const fileDirs = uniq([useDefault && defaultDir, rootDir, pkgDir].filter(Boolean))
231
+ const files = mergeFiles(useDefault && defaultFiles, rootFiles, pkgFiles)
232
+ const repoFiles = isRoot ? files.rootRepo : files.workspaceRepo
233
+ const moduleFiles = isRoot ? files.rootModule : files.workspaceModule
234
+
235
+ Object.assign(fullConfig, {
236
+ repoFiles,
237
+ moduleFiles,
238
+ applyRepo: !!repoFiles,
239
+ applyModule: !!moduleFiles,
240
+ __PARTIAL_DIRS__: fileDirs,
241
+ // gitignore, these use the full config so need to come at the very end
242
+ ignorePaths: [
243
+ ...gitignore.sort([
244
+ ...gitignore.allowRootDir([
245
+ // Allways allow module files in root or workspaces
246
+ ...getAddedFiles(moduleFiles).map(s => template(s, fullConfig)),
247
+ ...isRoot ? [
248
+ // in the root allow all repo files
249
+ ...getAddedFiles(repoFiles).map(s => template(s, fullConfig)),
250
+ // and allow all workspace repo level files in the root
251
+ ...pkgs
252
+ .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false)
253
+ .flatMap(() => getAddedFiles(files.workspaceRepo)),
254
+ ] : [],
255
+ ]),
256
+ ...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
257
+ ...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
258
+ ...(pkgConfig.allowDistPaths ? pkgConfig.distPaths : []).map((p) => `!/${p}`),
259
+ ...(pkgConfig.ignorePaths || []),
260
+ ]),
261
+ // these cant be sorted since they rely on order
262
+ // to allow a previously ignored directoy
263
+ ...isRoot
264
+ ? gitignore.allowDir(wsPkgs.map((p) => makePosix(relative(rootPkg.path, p.path))))
265
+ : [],
266
+ ].filter(p => !pkgConfig.eslint ? !p.includes('eslint') : true),
267
+ })
268
+
269
+ return fullConfig
291
270
  }
292
271
 
293
272
  module.exports = getFullConfig
@@ -26,4 +26,4 @@ defaults:
26
26
  run:
27
27
  shell: $\{{ matrix.platform.shell }}
28
28
  steps:
29
- {{> stepsSetup jobIsMatrix=true }}
29
+ {{> stepsSetupYml jobIsMatrix=true }}
@@ -0,0 +1,51 @@
1
+ name: {{#if publish}}Publish{{else}}Check Publish{{/if}}
2
+ runs-on: ubuntu-latest
3
+ defaults:
4
+ run:
5
+ shell: bash
6
+ {{#if publish}}
7
+ permissions:
8
+ id-token: write
9
+ {{/if}}
10
+ steps:
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}
15
+ - name: Publish
16
+ env:
17
+ PUBLISH_TOKEN: $\{{ secrets.PUBLISH_TOKEN }}
18
+ {{else}}
19
+ {{> stepsSetupYml }}
20
+ - name: Check If Published
21
+ {{/if}}
22
+ run: |
23
+ EXIT_CODE=0
24
+
25
+ function each_release {
26
+ if {{#if publish}}npm publish --provenance --tag="$1"{{else}}npm view "$@" --loglevel=error > /dev/null{{/if}}; then
27
+ echo 0
28
+ else
29
+ echo 1
30
+ fi
31
+ }
32
+
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"
45
+ else
46
+ echo "$SPEC OK"
47
+ {{/unless}}
48
+ fi
49
+ done
50
+
51
+ exit $EXIT_CODE
@@ -5,4 +5,4 @@ defaults:
5
5
  run:
6
6
  shell: bash
7
7
  steps:
8
- {{> stepsSetup }}
8
+ {{> stepsSetupYml }}
@@ -0,0 +1,15 @@
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
+ {{#if updateNpm}}
11
+ - name: Install Latest npm
12
+ uses: ./.github/actions/install-latest-npm
13
+ with:
14
+ node: $\{{ steps.node.outputs.node-version }}
15
+ {{/if}}
@@ -0,0 +1,15 @@
1
+ {{~#unless jobSkipSetup}}
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}}
13
+ {{> stepNodeYml }}
14
+ {{> stepDepsYml }}
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 }}"}
@@ -0,0 +1,55 @@
1
+ name: 'Install Latest npm'
2
+ description: 'Install the latest version of npm compatible with the Node version'
3
+ inputs:
4
+ node:
5
+ description: 'Current Node version'
6
+ required: true
7
+ runs:
8
+ using: "composite"
9
+ steps:
10
+ # node 10/12/14 ship with npm@6, which is known to fail when updating itself in windows
11
+ - name: Update Windows npm
12
+ if: |
13
+ runner.os == 'Windows' && (
14
+ startsWith(inputs.node, 'v10.') ||
15
+ startsWith(inputs.node, 'v12.') ||
16
+ startsWith(inputs.node, 'v14.')
17
+ )
18
+ shell: cmd
19
+ run: |
20
+ curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz
21
+ tar xf npm-7.5.4.tgz
22
+ cd package
23
+ node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
24
+ cd ..
25
+ rmdir /s /q package
26
+ - name: Install Latest npm
27
+ shell: bash
28
+ env:
29
+ NODE_VERSION: $\{{ inputs.node }}
30
+ run: |
31
+ MATCH=""
32
+ SPECS=("latest" "next-10" "next-9" "next-8" "next-7" "next-6")
33
+
34
+ echo "node@$NODE_VERSION"
35
+
36
+ for SPEC in ${SPECS[@]}; do
37
+ ENGINES=$(npm view npm@$SPEC --json | jq -r '.engines.node')
38
+ echo "Checking if node@$NODE_VERSION satisfies npm@$SPEC ($ENGINES)"
39
+
40
+ if npx semver -r "$ENGINES" "$NODE_VERSION" > /dev/null; then
41
+ MATCH=$SPEC
42
+ echo "Found compatible version: npm@$MATCH"
43
+ break
44
+ fi
45
+ done
46
+
47
+ if [ -z $MATCH ]; then
48
+ echo "Could not find a compatible version of npm for node@$NODE_VERSION"
49
+ exit 1
50
+ fi
51
+
52
+ npm i --prefer-online --no-fund --no-audit -g npm@$MATCH
53
+ - name: npm Version
54
+ shell: bash
55
+ run: npm -v
@@ -8,5 +8,5 @@ on:
8
8
 
9
9
  jobs:
10
10
  audit:
11
- {{> job jobName="Audit Dependencies" jobDepFlags="--package-lock" }}
12
- {{> stepAudit }}
11
+ {{> jobYml jobName="Audit Dependencies" jobDepFlags="--package-lock" }}
12
+ {{> stepAuditYml }}
@@ -0,0 +1,49 @@
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
+ {{> jobYml
23
+ jobName="Lint All"
24
+ jobCheckout=(obj ref="${{ inputs.ref }}")
25
+ jobCreateCheck=(obj sha="${{ inputs.check-sha }}")
26
+ }}
27
+ {{> stepLintYml jobRunFlags=allFlags }}
28
+ - name: Conclude Check
29
+ uses: LouisBrunner/checks-action@v1.6.0
30
+ if: always()
31
+ with:
32
+ token: $\{{ secrets.GITHUB_TOKEN }}
33
+ conclusion: $\{{ job.status }}
34
+ check_id: $\{{ steps.create-check.outputs.check-id }}
35
+
36
+ test-all:
37
+ {{> jobMatrixYml
38
+ jobName="Test All"
39
+ jobCheckout=(obj ref="${{ inputs.ref }}")
40
+ jobCreateCheck=(obj sha="${{ inputs.check-sha }}")
41
+ }}
42
+ {{> stepTestYml jobRunFlags=allFlags }}
43
+ - name: Conclude Check
44
+ uses: LouisBrunner/checks-action@v1.6.0
45
+ if: always()
46
+ with:
47
+ token: $\{{ secrets.GITHUB_TOKEN }}
48
+ conclusion: $\{{ job.status }}
49
+ check_id: $\{{ steps.create-check.outputs.check-id }}
@@ -0,0 +1,13 @@
1
+ name: CI {{~#if isWorkspace}} - {{ pkgName }}{{/if}}
2
+
3
+ on:
4
+ {{> onCiYml }}
5
+
6
+ jobs:
7
+ lint:
8
+ {{> jobYml jobName="Lint" }}
9
+ {{> stepLintYml jobRunFlags=pkgFlags }}
10
+
11
+ test:
12
+ {{> jobMatrixYml jobName="Test" }}
13
+ {{> stepTestYml jobRunFlags=pkgFlags }}
@@ -24,7 +24,7 @@ jobs:
24
24
  contents: read
25
25
  security-events: write
26
26
  steps:
27
- {{> stepGit }}
27
+ {{> stepGitYml }}
28
28
  - name: Initialize CodeQL
29
29
  uses: github/codeql-action/init@v2
30
30
  with:
@@ -8,12 +8,22 @@ const localConfigs = readdir(__dirname)
8
8
 
9
9
  module.exports = {
10
10
  root: true,
11
- {{#if workspaceGlobs}}
12
11
  ignorePatterns: [
12
+ 'tap-testdir*/',
13
13
  {{#each workspaceGlobs}}
14
14
  '{{ . }}',
15
15
  {{/each}}
16
+ {{#if typescript}}
17
+ 'dist/',
18
+ {{/if}}
16
19
  ],
20
+ {{#if typescript}}
21
+ parser: '@typescript-eslint/parser',
22
+ settings: {
23
+ 'import/resolver': {
24
+ typescript: {},
25
+ },
26
+ },
17
27
  {{/if}}
18
28
  extends: [
19
29
  '@npmcli',
@@ -1,5 +1,7 @@
1
1
  # ignore everything in the root
2
2
  /*
3
+ # transient test directories
4
+ tap-testdir*/
3
5
 
4
6
  # keep these
5
7
  {{#each ignorePaths}}