@npmcli/template-oss 4.19.0 → 4.20.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 (52) hide show
  1. package/README.md +15 -11
  2. package/bin/release-manager.js +6 -0
  3. package/lib/config.js +95 -117
  4. package/lib/content/{_job-matrix.yml → _job-matrix-yml.hbs} +1 -1
  5. package/lib/content/{_job-release-integration.yml → _job-release-integration-yml.hbs} +1 -1
  6. package/lib/content/{_job.yml → _job-yml.hbs} +1 -1
  7. package/lib/content/_step-node-yml.hbs +60 -0
  8. package/lib/content/_steps-setup-yml.hbs +6 -0
  9. package/lib/content/{audit.yml → audit-yml.hbs} +2 -2
  10. package/lib/content/{ci-release.yml → ci-release-yml.hbs} +6 -6
  11. package/lib/content/ci-yml.hbs +13 -0
  12. package/lib/content/{codeql-analysis.yml → codeql-analysis-yml.hbs} +1 -1
  13. package/lib/content/{eslintrc.js → eslintrc-js.hbs} +11 -1
  14. package/lib/content/{gitignore → gitignore.hbs} +2 -0
  15. package/lib/content/index.js +43 -39
  16. package/lib/content/{pkg.json → package-json.hbs} +8 -4
  17. package/lib/content/{post-dependabot.yml → post-dependabot-yml.hbs} +1 -1
  18. package/lib/content/{pull-request.yml → pull-request-yml.hbs} +1 -1
  19. package/lib/content/{release.yml → release-yml.hbs} +10 -10
  20. package/lib/content/tsconfig-json.hbs +17 -0
  21. package/lib/util/files.js +29 -20
  22. package/lib/util/get-cmd-path.js +36 -0
  23. package/lib/util/git.js +6 -2
  24. package/lib/util/import-or-require.js +29 -0
  25. package/lib/util/parser.js +6 -1
  26. package/lib/util/path.js +13 -0
  27. package/lib/util/template.js +9 -6
  28. package/package.json +10 -10
  29. package/lib/content/_step-node.yml +0 -57
  30. package/lib/content/_steps-setup.yml +0 -6
  31. package/lib/content/ci.yml +0 -13
  32. /package/lib/content/{CODEOWNERS → CODEOWNERS.hbs} +0 -0
  33. /package/lib/content/{CODE_OF_CONDUCT.md → CODE_OF_CONDUCT-md.hbs} +0 -0
  34. /package/lib/content/{CONTRIBUTING.md → CONTRIBUTING-md.hbs} +0 -0
  35. /package/lib/content/{LICENSE.md → LICENSE-md.hbs} +0 -0
  36. /package/lib/content/{SECURITY.md → SECURITY-md.hbs} +0 -0
  37. /package/lib/content/{_on-ci.yml → _on-ci-yml.hbs} +0 -0
  38. /package/lib/content/{_step-audit.yml → _step-audit-yml.hbs} +0 -0
  39. /package/lib/content/{_step-checks.yml → _step-checks-yml.hbs} +0 -0
  40. /package/lib/content/{_step-deps.yml → _step-deps-yml.hbs} +0 -0
  41. /package/lib/content/{_step-git.yml → _step-git-yml.hbs} +0 -0
  42. /package/lib/content/{_step-lint.yml → _step-lint-yml.hbs} +0 -0
  43. /package/lib/content/{_step-test.yml → _step-test-yml.hbs} +0 -0
  44. /package/lib/content/{bug.yml → bug-yml.hbs} +0 -0
  45. /package/lib/content/{commitlintrc.js → commitlintrc-js.hbs} +0 -0
  46. /package/lib/content/{config.yml → config-yml.hbs} +0 -0
  47. /package/lib/content/{dependabot.yml → dependabot-yml.hbs} +0 -0
  48. /package/lib/content/{npmrc → npmrc.hbs} +0 -0
  49. /package/lib/content/{release-please-config.json → release-please-config-json.hbs} +0 -0
  50. /package/lib/content/{release-please-manifest.json → release-please-manifest-json.hbs} +0 -0
  51. /package/lib/content/{settings.yml → settings-yml.hbs} +0 -0
  52. /package/lib/content/{tap.json → tap-json.hbs} +0 -0
package/README.md CHANGED
@@ -3,7 +3,11 @@
3
3
  This module bundles the npm CLI team's basics for package development into a
4
4
  single devDependency.
5
5
 
6
- **CAUTION: THESE CHANGES WILL OVERWRITE ANY LOCAL FILES AND SETTINGS**
6
+ > [!WARNING]
7
+ > THESE CHANGES WILL OVERWRITE LOCAL FILES AND SETTINGS
8
+
9
+ > [!IMPORTANT]
10
+ > This package does not follow semantic versioning for its API. This package is designed to be installed with `--save-exact` and therefore will make breaking API changes outside of major versions, including `engines` narrowing. Major versions are reserved for breaking changes to files written to a repo by this package.
7
11
 
8
12
  ### Configuration
9
13
 
@@ -60,21 +64,21 @@ any of the same settings in the root.
60
64
  ### Content
61
65
 
62
66
  All the templated content for this repo lives in
63
- [`lib/content/`](./lib/content/). The `index.js`[./lib/content/index.js] file
67
+ [`lib/content/`](./lib/content/). The [`index.js`](./lib/content/index.js) file
64
68
  controls how and where this content is written.
65
69
 
66
70
  Content files can be overwritten or merged with the existing target file.
67
- Currently mergining is only supported for `package.json` files.
71
+ Merging is only supported for some types of files (ini, yaml, json, package.json)
68
72
 
69
73
  Each content file goes through the following pipeline:
70
74
 
71
75
  1. It is read from its source location
72
- 1. It is are templated using Handlebars with the variables from each packages's
73
- config (with some derived values generated in [`config.js`](./lib/config.js)
74
- 1. It is parsed based on its file extension in
76
+ 2. It is compiled using [Handlebars](https://handlebarsjs.com/) with the variables from each packages's
77
+ config (with some derived values generated in [`config.js`](./lib/config.js))
78
+ 3. It is parsed based on its file extension in
75
79
  [`parser.js`](./lib/util/parser.js)
76
- 1. Additional logic is applied by the parser
77
- 1. It is written to its target location
80
+ 4. Additional logic is applied by the parser
81
+ 5. It is written to its target location
78
82
 
79
83
  ### Usage
80
84
 
@@ -82,7 +86,7 @@ This package provides two bin scripts:
82
86
 
83
87
  #### `template-oss-check`
84
88
 
85
- This will check if any of the applied files different from the target content,
89
+ This will check if any of the applied files differ from the target content,
86
90
  or if any of the other associated checks fail. The diffs of each file or check
87
91
  will be reported with instructions on how to fix it.
88
92
 
@@ -92,7 +96,7 @@ This will write all source files to their target locations in the cwd. It will
92
96
  do nothing if `package.json#templateOSS.version` is the same as the version
93
97
  being run. This can be overridden by `--force`.
94
98
 
95
- This is the script that is run on `postinsall`.
99
+ This is the script that is run on `postinstall`.
96
100
 
97
101
  ### Extending
98
102
 
@@ -100,7 +104,7 @@ This is the script that is run on `postinsall`.
100
104
 
101
105
  This directory is where all the logic for applying files lives. It should be
102
106
  possible to add new files without modifying anything in this directory. To add a
103
- file, add the templated file to `lib/content/$FILENAME` and add entry for it in
107
+ file, add the templated file to `lib/content/$FILENAME` and an entry for it in
104
108
  `lib/content/index.js` depending on where and when it should be written (root vs
105
109
  workspace, repo vs module, add vs remove, etc).
106
110
 
@@ -50,6 +50,12 @@ const MANUAL_PUBLISH_STEPS = `
50
50
  `
51
51
 
52
52
  const AUTO_PUBLISH_STEPS = `
53
+ 1. Approve this PR
54
+
55
+ \`\`\`sh
56
+ gh pr review <PR-NUMBER> -R {NWO} --approve
57
+ \`\`\`
58
+
53
59
  1. Merge release PR :rotating_light: Merging this will auto publish :rotating_light:
54
60
 
55
61
  \`\`\`sh
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 })
@@ -185,6 +124,8 @@ const getFullConfig = async ({
185
124
  ? pkgConfig.releaseBranch.replace(/\*/g, pkgConfig.backport)
186
125
  : defaultBranch
187
126
 
127
+ const esm = pkg.pkgJson?.type === 'module' || !!pkgConfig.typescript || !!pkgConfig.esm
128
+
188
129
  // all derived keys
189
130
  const derived = {
190
131
  isRoot,
@@ -209,18 +150,11 @@ const getFullConfig = async ({
209
150
  releaseBranch,
210
151
  publishTag,
211
152
  dependabot: parseDependabot(pkgConfig, defaultConfig, gitBranches.branches),
212
- // repo
153
+ // paths
213
154
  repoDir: rootPkg.path,
214
- repoFiles,
215
- applyRepo: !!repoFiles,
216
- // module
217
155
  moduleDir: pkg.path,
218
- moduleFiles,
219
- applyModule: !!moduleFiles,
220
- // package
221
156
  pkgName: pkg.pkgJson.name,
222
157
  pkgNameFs: pkg.pkgJson.name.replace(/\//g, '-').replace(/@/g, ''),
223
- // paths
224
158
  pkgPath,
225
159
  pkgDir: posixDir(pkgPath),
226
160
  pkgGlob: posixGlob(pkgPath),
@@ -228,6 +162,12 @@ const getFullConfig = async ({
228
162
  allFlags: isMono ? '-ws -iwr --if-present' : '',
229
163
  workspacePaths,
230
164
  workspaceGlobs: workspacePaths.map(posixGlob),
165
+ // type
166
+ esm,
167
+ cjsExt: esm ? 'cjs' : 'js',
168
+ deleteJsExt: esm ? 'js' : 'cjs',
169
+ // tap
170
+ tap18: semver.coerce(pkg.pkgJson?.devDependencies?.tap)?.major === 18,
231
171
  // booleans to control application of updates
232
172
  isForce,
233
173
  isDogFood,
@@ -243,20 +183,6 @@ const getFullConfig = async ({
243
183
  lockfile: rootPkgConfig.lockfile,
244
184
  // ci versions / engines
245
185
  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
186
  // needs update if we are dogfooding this repo, with force argv, or its
261
187
  // behind the current version
262
188
  needsUpdate: isForce || isDogFood || !isLatest,
@@ -264,15 +190,22 @@ const getFullConfig = async ({
264
190
  __NAME__: NAME,
265
191
  __CONFIG_KEY__: CONFIG_KEY,
266
192
  __VERSION__: LATEST_VERSION,
267
- __PARTIAL_DIRS__: fileDirs,
268
193
  }
269
194
 
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
- }
195
+ if (!pkgConfig.eslint && Array.isArray(pkgConfig.requiredPackages?.devDependencies)) {
196
+ pkgConfig.requiredPackages.devDependencies =
197
+ pkgConfig.requiredPackages.devDependencies.filter(p => !p.includes('eslint'))
198
+ }
199
+
200
+ if (pkgConfig.typescript) {
201
+ defaultsDeep(pkgConfig, { allowPaths: [], requiredPackages: { devDependencies: [] } })
202
+ pkgConfig.distPaths = null
203
+ pkgConfig.allowPaths.push('/src/')
204
+ pkgConfig.requiredPackages.devDependencies.push(
205
+ 'typescript',
206
+ 'tshy',
207
+ '@typescript-eslint/parser'
208
+ )
276
209
  }
277
210
 
278
211
  const gitUrl = await git.getUrl(rootPkg.path)
@@ -284,10 +217,55 @@ const getFullConfig = async ({
284
217
  }
285
218
  }
286
219
 
287
- return {
288
- ...pkgConfig,
289
- ...derived,
290
- }
220
+ const fullConfig = { ...pkgConfig, ...derived }
221
+
222
+ // files, come at the end since file names can be based on config
223
+ const [defaultFiles, defaultDir] = await getFiles(DEFAULT_CONTENT, mergedConfig, fullConfig)
224
+ const [rootFiles, rootDir] = await getFiles(rootPkg.config.content, mergedConfig, fullConfig)
225
+ const [pkgFiles, pkgDir] = await getFiles(mergedConfig.content, mergedConfig, fullConfig)
226
+
227
+ // Files get merged in from the default content (that template-oss provides) as well
228
+ // as any content paths provided from the root or the workspace
229
+ const fileDirs = uniq([useDefault && defaultDir, rootDir, pkgDir].filter(Boolean))
230
+ const files = mergeFiles(useDefault && defaultFiles, rootFiles, pkgFiles)
231
+ const repoFiles = isRoot ? files.rootRepo : files.workspaceRepo
232
+ const moduleFiles = isRoot ? files.rootModule : files.workspaceModule
233
+
234
+ Object.assign(fullConfig, {
235
+ repoFiles,
236
+ moduleFiles,
237
+ applyRepo: !!repoFiles,
238
+ applyModule: !!moduleFiles,
239
+ __PARTIAL_DIRS__: fileDirs,
240
+ // gitignore, these use the full config so need to come at the very end
241
+ ignorePaths: [
242
+ ...gitignore.sort([
243
+ ...gitignore.allowRootDir([
244
+ // Allways allow module files in root or workspaces
245
+ ...getAddedFiles(moduleFiles).map(s => template(s, fullConfig)),
246
+ ...isRoot ? [
247
+ // in the root allow all repo files
248
+ ...getAddedFiles(repoFiles).map(s => template(s, fullConfig)),
249
+ // and allow all workspace repo level files in the root
250
+ ...pkgs
251
+ .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false)
252
+ .flatMap(() => getAddedFiles(files.workspaceRepo)),
253
+ ] : [],
254
+ ]),
255
+ ...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
256
+ ...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
257
+ ...(pkgConfig.distPaths || []).map((p) => `!/${p}`),
258
+ ...(pkgConfig.ignorePaths || []),
259
+ ]),
260
+ // these cant be sorted since they rely on order
261
+ // to allow a previously ignored directoy
262
+ ...isRoot
263
+ ? gitignore.allowDir(wsPkgs.map((p) => makePosix(relative(rootPkg.path, p.path))))
264
+ : [],
265
+ ].filter(p => !pkgConfig.eslint ? !p.includes('eslint') : true),
266
+ })
267
+
268
+ return fullConfig
291
269
  }
292
270
 
293
271
  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 }}
@@ -29,7 +29,7 @@ defaults:
29
29
  run:
30
30
  shell: bash
31
31
  steps:
32
- {{> stepNode lockfile=false }}
32
+ {{> stepNodeYml lockfile=false }}
33
33
  - name: View in Registry
34
34
  run: |
35
35
  EXIT_CODE=0
@@ -5,4 +5,4 @@ defaults:
5
5
  run:
6
6
  shell: bash
7
7
  steps:
8
- {{> stepsSetup }}
8
+ {{> stepsSetupYml }}
@@ -0,0 +1,60 @@
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
+ {{#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
+ - 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
60
+ {{/if}}
@@ -0,0 +1,6 @@
1
+ {{~#if jobCheck}}{{> stepChecksYml }}{{/if}}
2
+ {{~#unless jobSkipSetup}}
3
+ {{> stepGitYml }}
4
+ {{> stepNodeYml }}
5
+ {{> stepDepsYml }}
6
+ {{/unless}}
@@ -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 }}
@@ -19,19 +19,19 @@ on:
19
19
 
20
20
  jobs:
21
21
  lint-all:
22
- {{> job
22
+ {{> jobYml
23
23
  jobName="Lint All"
24
24
  jobCheck=(obj sha="inputs.check-sha")
25
25
  jobCheckout=(obj ref="${{ inputs.ref }}")
26
26
  }}
27
- {{> stepLint jobRunFlags=allFlags }}
28
- {{> stepChecks jobCheck=true }}
27
+ {{> stepLintYml jobRunFlags=allFlags }}
28
+ {{> stepChecksYml jobCheck=true }}
29
29
 
30
30
  test-all:
31
- {{> jobMatrix
31
+ {{> jobMatrixYml
32
32
  jobName="Test All"
33
33
  jobCheck=(obj sha="inputs.check-sha")
34
34
  jobCheckout=(obj ref="${{ inputs.ref }}")
35
35
  }}
36
- {{> stepTest jobRunFlags=allFlags }}
37
- {{> stepChecks jobCheck=true }}
36
+ {{> stepTestYml jobRunFlags=allFlags }}
37
+ {{> stepChecksYml jobCheck=true }}
@@ -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}}