@npmcli/template-oss 4.7.0 → 4.7.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/lib/config.js CHANGED
@@ -21,9 +21,9 @@ const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
21
21
  const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
22
22
  const posixGlob = (str) => `${posixDir(str)}**`
23
23
 
24
- const getCmdPath = (key, { rootConfig, defaultConfig, isRoot, path, root }) => {
24
+ const getCmdPath = (key, { rootConfig, defaultConfig, isRoot, pkg, rootPkg }) => {
25
25
  // Make a path relative from a workspace to the root if we are in a workspace
26
- const wsToRoot = (p) => isRoot ? p : makePosix(join(relative(path, root), p))
26
+ const wsToRoot = (p) => isRoot ? p : makePosix(join(relative(pkg.path, rootPkg.path), p))
27
27
 
28
28
  const rootPath = rootConfig[key]
29
29
  const defaultPath = defaultConfig[key]
@@ -82,46 +82,39 @@ const getFiles = (path, rawConfig) => {
82
82
  }
83
83
 
84
84
  const getFullConfig = async ({
85
- // the path to the root of the repo
86
- root,
87
- // the path to the package being operated on
88
- // this is the same as root when operating on the root
89
- path,
90
- // the full contents of the package.json for this package
91
- pkgJson,
92
- // an array of all package info {pkgJson,path,config}[]
93
- pkgs,
94
- // an array of all workspaces in this repo
95
- workspaces,
96
- // the config from the package.json in the root
97
- rootConfig: _rootConfig,
98
- // the config from the package.json being operated on
99
- pkgConfig: _pkgConfig,
85
+ // everything is an object or an array of objects with the following
86
+ // path: the path to the package root
87
+ // pkgJson: the package json path
88
+ // config: the template oss config from the package root
89
+ pkg, // the package currently being operated on
90
+ rootPkg, // the root pkg (same as pkg when operating on the root)
91
+ pkgs, // an array of all packages to be operated on
92
+ wsPkgs, // an array of all workspaces being operated
100
93
  }) => {
101
- const isRoot = root === path
94
+ const isRoot = rootPkg.path === pkg.path
102
95
  const isWorkspace = !isRoot
103
- const isMono = !!workspaces.length
96
+ const isMono = !!wsPkgs.length
104
97
  const isRootMono = isRoot && isMono
105
98
 
106
- const isLatest = _pkgConfig.version === LATEST_VERSION
107
- const isDogFood = pkgJson.name === NAME
99
+ const isLatest = pkg.config.version === LATEST_VERSION
100
+ const isDogFood = rootPkg.pkgJson.name === NAME
108
101
  const isForce = process.argv.includes('--force')
109
102
 
110
103
  // These config items are merged betweent the root and child workspaces and only come from
111
104
  // the package.json because they can be used to read configs from other the content directories
112
- const mergedConfig = mergeConfigs(_rootConfig, _pkgConfig)
105
+ const mergedConfig = mergeConfigs(rootPkg.config, pkg.config)
113
106
 
114
107
  const defaultConfig = getConfig(DEFAULT_CONTENT)
115
108
  const [defaultFiles, defaultDir] = getFiles(DEFAULT_CONTENT, mergedConfig)
116
109
  const useDefault = mergedConfig.defaultContent && defaultConfig
117
110
 
118
- const rootConfig = getConfig(_rootConfig.content, _rootConfig)
119
- const [rootFiles, rootDir] = getFiles(_rootConfig.content, mergedConfig)
111
+ const rootConfig = getConfig(rootPkg.config.content, rootPkg.config)
112
+ const [rootFiles, rootDir] = getFiles(rootPkg.config.content, mergedConfig)
120
113
 
121
114
  // The content config only gets set from the package we are in, it doesn't inherit
122
115
  // anything from the root
123
116
  const rootPkgConfig = merge(useDefault, rootConfig)
124
- const pkgConfig = merge(useDefault, getConfig(_pkgConfig.content, _pkgConfig))
117
+ const pkgConfig = merge(useDefault, getConfig(pkg.config.content, pkg.config))
125
118
  const [pkgFiles, pkgDir] = getFiles(mergedConfig.content, mergedConfig)
126
119
 
127
120
  // Files get merged in from the default content (that template-oss provides) as well
@@ -139,49 +132,60 @@ const getFullConfig = async ({
139
132
  ...getAddedFiles(repoFiles),
140
133
  // and allow all workspace repo level files in the root
141
134
  ...pkgs
142
- .filter(p => p.path !== root && p.config.workspaceRepo !== false)
135
+ .filter(p => p.path !== rootPkg.path && p.config.workspaceRepo !== false)
143
136
  .flatMap(() => getAddedFiles(files.workspaceRepo)),
144
137
  ] : [],
145
138
  ]
146
139
 
147
140
  // root only configs
148
- const npmPath = getCmdPath('npm', { rootConfig, defaultConfig, isRoot, path, root })
149
- const npxPath = getCmdPath('npx', { rootConfig, defaultConfig, isRoot, path, root })
141
+ const npmPath = getCmdPath('npm', { rootConfig, defaultConfig, isRoot, pkg, rootPkg })
142
+ const npxPath = getCmdPath('npx', { rootConfig, defaultConfig, isRoot, pkg, rootPkg })
150
143
 
151
144
  // these are written to ci yml files so it needs to always use posix
152
- const pkgPath = makePosix(relative(root, path)) || '.'
145
+ const pkgPath = makePosix(relative(rootPkg.path, pkg.path)) || '.'
153
146
 
154
147
  // we use the raw paths from the package.json workspaces as ignore patterns in
155
148
  // some cases. the workspaces passed in have already been run through map workspaces
156
- const workspacePaths = (pkgJson.workspaces || []).map(deglob)
149
+ const workspacePaths = (pkg.pkgJson.workspaces || []).map(deglob)
150
+
151
+ const isPrivate = !!pkg.pkgJson.private
152
+ const isPublic = !isPrivate
153
+ const publicPkgs = pkgs.filter(p => !p.pkgJson.private)
154
+ const allPrivate = pkgs.every(p => p.pkgJson.private)
157
155
 
158
156
  // all derived keys
159
157
  const derived = {
160
158
  isRoot,
161
159
  isWorkspace,
160
+ isMono,
162
161
  // Some files are written to the base of a repo but will
163
162
  // include configuration for all packages within a monorepo
164
163
  // For these cases it is helpful to know if we are in a
165
164
  // monorepo since template-oss might be used only for
166
165
  // workspaces and not the root or vice versa.
167
166
  isRootMono,
168
- isMono,
167
+ // public/private
168
+ isPublic,
169
+ isPrivate,
170
+ allPrivate,
171
+ // controls whether we are in a monorepo with any public workspaces
172
+ isMonoPublic: isMono && !!publicPkgs.filter(p => p.path !== rootPkg.path).length,
169
173
  // repo
170
- repoDir: root,
174
+ repoDir: rootPkg.path,
171
175
  repoFiles,
172
176
  applyRepo: !!repoFiles,
173
177
  // module
174
- moduleDir: path,
178
+ moduleDir: pkg.path,
175
179
  moduleFiles,
176
180
  applyModule: !!moduleFiles,
177
181
  // package
178
- pkgName: pkgJson.name,
179
- pkgNameFs: pkgJson.name.replace(/\//g, '-').replace(/@/g, ''),
182
+ pkgName: pkg.pkgJson.name,
183
+ pkgNameFs: pkg.pkgJson.name.replace(/\//g, '-').replace(/@/g, ''),
180
184
  // paths
181
185
  pkgPath,
182
186
  pkgDir: posixDir(pkgPath),
183
187
  pkgGlob: posixGlob(pkgPath),
184
- pkgFlags: isWorkspace ? `-w ${pkgJson.name}` : '',
188
+ pkgFlags: isWorkspace ? `-w ${pkg.pkgJson.name}` : '',
185
189
  allFlags: isMono ? '-ws -iwr --if-present' : '',
186
190
  workspacePaths,
187
191
  workspaceGlobs: workspacePaths.map(posixGlob),
@@ -208,7 +212,9 @@ const getFullConfig = async ({
208
212
  ]),
209
213
  // these cant be sorted since they rely on order
210
214
  // to allow a previously ignored directoy
211
- ...isRoot ? gitignore.allowDir(workspaces.map((p) => makePosix(relative(root, p)))) : [],
215
+ ...isRoot
216
+ ? gitignore.allowDir(wsPkgs.map((p) => makePosix(relative(rootPkg.path, p.path))))
217
+ : [],
212
218
  ],
213
219
  // needs update if we are dogfooding this repo, with force argv, or its
214
220
  // behind the current version
@@ -245,7 +251,7 @@ const getFullConfig = async ({
245
251
  derived.engines = pkgConfig.engines || engines
246
252
  }
247
253
 
248
- const gitUrl = await getGitUrl(root)
254
+ const gitUrl = await getGitUrl(rootPkg.path)
249
255
  if (gitUrl) {
250
256
  derived.repository = {
251
257
  type: 'git',
@@ -1,7 +1,7 @@
1
1
  {{#if jobCheck.sha}}
2
2
  - name: Get Workflow Job
3
3
  uses: actions/github-script@v6
4
- {{#if jobCheck.if}}if: {{ jobCheck.if }}{{/if}}
4
+ if: {{ jobCheck.sha }}
5
5
  id: check-output
6
6
  env:
7
7
  JOB_NAME: "{{#if jobName}}{{ jobName }}{{else}}{{ jobCheck.name }}{{/if}}"
@@ -21,7 +21,7 @@
21
21
  const job = data.jobs.find(j => j.name.endsWith(jobName))
22
22
  const jobUrl = job?.html_url
23
23
 
24
- const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/{{ jobCheck.sha }}`
24
+ const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/$\{{ {{ jobCheck.sha }} }}`
25
25
 
26
26
  let summary = `This check is assosciated with ${shaUrl}\n\n`
27
27
 
@@ -37,18 +37,18 @@
37
37
  uses: LouisBrunner/checks-action@v1.3.1
38
38
  {{#if jobCheck.sha}}
39
39
  id: check
40
- {{#if jobCheck.if}}if: {{ jobCheck.if }}{{/if}}
40
+ if: {{ jobCheck.sha }}
41
41
  {{else}}
42
- if: always()
42
+ if: {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}steps.check.outputs.check_id{{/if}} && always()
43
43
  {{/if}}
44
44
  with:
45
45
  token: $\{{ secrets.GITHUB_TOKEN }}
46
46
  {{#if jobCheck.sha}}
47
47
  status: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}in_progress{{/if}}
48
48
  name: {{#if jobCheck.name}}{{ jobCheck.name }}{{else}}{{ jobName }}{{/if}}{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}
49
- sha: {{ jobCheck.sha }}
49
+ sha: $\{{ {{ jobCheck.sha }} }}
50
50
  output: $\{{ steps.check-output.outputs.result }}
51
51
  {{else}}
52
- conclusion: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}$\{{ job.status }}{{/if}}
53
- check_id: {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}$\{{ steps.check.outputs.check_id }}{{/if}}
52
+ conclusion: $\{{ {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}job.status{{/if}} }}
53
+ check_id: $\{{ {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}steps.check.outputs.check_id{{/if}} }}
54
54
  {{/if}}
@@ -21,7 +21,7 @@ jobs:
21
21
  lint-all:
22
22
  {{> job
23
23
  jobName="Lint All"
24
- jobCheck=(obj sha="${{ inputs.check-sha }}" if="inputs.check-sha")
24
+ jobCheck=(obj sha="inputs.check-sha")
25
25
  jobCheckout=(obj ref="${{ inputs.ref }}")
26
26
  }}
27
27
  {{> stepLint jobRunFlags=allFlags }}
@@ -30,7 +30,7 @@ jobs:
30
30
  test-all:
31
31
  {{> jobMatrix
32
32
  jobName="Test All"
33
- jobCheck=(obj sha="${{ inputs.check-sha }}" if="inputs.check-sha")
33
+ jobCheck=(obj sha="inputs.check-sha")
34
34
  jobCheckout=(obj ref="${{ inputs.ref }}")
35
35
  }}
36
36
  {{> stepTest jobRunFlags=allFlags }}
@@ -1,8 +1,8 @@
1
1
  const { name: NAME, version: LATEST_VERSION } = require('../../package.json')
2
2
 
3
- const isPublic = (p) => !p.pkg.private
3
+ const isPublic = (p) => p.config.isPublic
4
4
 
5
- const sharedRoot = (name) => ({
5
+ const sharedRootAdd = (name) => ({
6
6
  // release
7
7
  '.github/workflows/release.yml': {
8
8
  file: 'release.yml',
@@ -26,6 +26,11 @@ const sharedRoot = (name) => ({
26
26
  comment = null
27
27
  },
28
28
  },
29
+ // this lint commits which is only necessary for releases
30
+ '.github/workflows/pull-request.yml': {
31
+ file: 'pull-request.yml',
32
+ filter: isPublic,
33
+ },
29
34
  // ci
30
35
  '.github/matchers/tap.json': 'tap.json',
31
36
  [`.github/workflows/ci${name ? `-${name}` : ''}.yml`]: 'ci.yml',
@@ -46,6 +51,12 @@ const sharedRoot = (name) => ({
46
51
  },
47
52
  })
48
53
 
54
+ const sharedRootRm = () => ({
55
+ '.github/workflows/pull-request.yml': {
56
+ filter: (p) => p.config.allPrivate,
57
+ },
58
+ })
59
+
49
60
  // Changes applied to the root of the repo
50
61
  const rootRepo = {
51
62
  add: {
@@ -55,13 +66,13 @@ const rootRepo = {
55
66
  '.github/CODEOWNERS': 'CODEOWNERS',
56
67
  '.github/workflows/audit.yml': 'audit.yml',
57
68
  '.github/workflows/codeql-analysis.yml': 'codeql-analysis.yml',
58
- '.github/workflows/pull-request.yml': 'pull-request.yml',
59
- ...sharedRoot(),
69
+ ...sharedRootAdd(),
70
+ },
71
+ rm: {
72
+ '.github/workflows/release-test.yml': true,
73
+ '.github/workflows/release-please.yml': true,
74
+ ...sharedRootRm(),
60
75
  },
61
- rm: [
62
- '.github/workflows/release-test.yml',
63
- '.github/workflows/release-please.yml',
64
- ],
65
76
  }
66
77
 
67
78
  // These are also applied to the root of the repo
@@ -86,12 +97,13 @@ const rootModule = {
86
97
  // Changes for each workspace but applied to the root of the repo
87
98
  const workspaceRepo = {
88
99
  add: {
89
- ...sharedRoot('{{ pkgNameFs }}'),
100
+ ...sharedRootAdd('{{ pkgNameFs }}'),
90
101
  },
91
- rm: [
102
+ rm: {
92
103
  // These are the old release please files that should be removed now
93
- '.github/workflows/release-please-{{ pkgNameFs }}.yml',
94
- ],
104
+ '.github/workflows/release-please-{{ pkgNameFs }}.yml': true,
105
+ ...sharedRootRm(),
106
+ },
95
107
  }
96
108
 
97
109
  // Changes for each workspace but applied to the relative workspace dir
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "separate-pull-requests": {{{ del }}},
3
- "plugins": {{#if isMono }}["node-workspace"]{{ else }}{{{ del }}}{{/if}},
3
+ "plugins": {{#if isMonoPublic }}["node-workspace"]{{ else }}{{{ del }}}{{/if}},
4
4
  "exclude-packages-from-root": true,
5
5
  "group-pull-request-title-pattern": "chore: release ${version}",
6
6
  "pull-request-title-pattern": "chore: release${component} ${version}",
@@ -64,7 +64,7 @@ jobs:
64
64
  }
65
65
 
66
66
  return commentId
67
- {{> stepChecks jobCheck=(obj name="Release" sha="${{ steps.release.outputs.pr-sha }}" if="steps.release.outputs.pr-number") }}
67
+ {{> stepChecks jobCheck=(obj name="Release" sha="steps.release.outputs.pr-sha") }}
68
68
 
69
69
  update:
70
70
  needs: release
@@ -92,8 +92,8 @@ jobs:
92
92
  git commit --all --amend --no-edit || true
93
93
  git push --force-with-lease
94
94
  echo "::set-output name=sha::$(git rev-parse HEAD)"
95
- {{> stepChecks jobName="Update - Release" jobCheck=(obj sha="${{ steps.commit.outputs.sha }}" name="Release" )}}
96
- {{> stepChecks jobCheck=(obj id="${{ needs.release.outputs.check-id }}" )}}
95
+ {{> stepChecks jobName="Update - Release" jobCheck=(obj sha="steps.commit.outputs.sha" name="Release" )}}
96
+ {{> stepChecks jobCheck=(obj id="needs.release.outputs.check-id" )}}
97
97
 
98
98
  ci:
99
99
  name: CI - Release
@@ -119,7 +119,7 @@ jobs:
119
119
  result="success"
120
120
  fi
121
121
  echo "::set-output name=result::$result"
122
- {{> stepChecks jobCheck=(obj id="${{ needs.update.outputs.check-id }}" status="${{ steps.needs-result.outputs.result }}") }}
122
+ {{> stepChecks jobCheck=(obj id="needs.update.outputs.check-id" status="steps.needs-result.outputs.result") }}
123
123
 
124
124
  post-release:
125
125
  needs: release
package/lib/index.js CHANGED
@@ -40,10 +40,7 @@ const getWsPkgs = async (root, rootPkg) => {
40
40
  }
41
41
  }
42
42
 
43
- return {
44
- pkgs: wsPkgs,
45
- paths: [...rootWorkspaces.values()],
46
- }
43
+ return wsPkgs
47
44
  }
48
45
 
49
46
  const getPkgs = async (root) => {
@@ -51,32 +48,29 @@ const getPkgs = async (root) => {
51
48
 
52
49
  const rootPkg = await getPkg(root)
53
50
 
54
- const ws = await getWsPkgs(root, rootPkg)
51
+ const wsPkgs = await getWsPkgs(root, rootPkg)
55
52
 
56
53
  return {
57
54
  rootPkg,
58
- pkgs: [rootPkg].concat(ws.pkgs),
59
- workspaces: ws.paths,
55
+ wsPkgs,
56
+ pkgs: [rootPkg].concat(wsPkgs),
60
57
  }
61
58
  }
62
59
 
63
60
  const runAll = async (root, checks) => {
64
61
  const results = []
65
- const { pkgs, workspaces, rootPkg: { config: rootConfig } } = await getPkgs(root)
62
+ const { pkgs, rootPkg, wsPkgs } = await getPkgs(root)
66
63
 
67
- for (const { pkgJson, path, config: pkgConfig } of pkgs) {
64
+ for (const pkg of pkgs) {
68
65
  // full config includes original config values
69
66
  const fullConfig = await getConfig({
70
- root,
71
- path,
72
- pkgJson,
67
+ pkg,
73
68
  pkgs,
74
- workspaces,
75
- rootConfig,
76
- pkgConfig,
69
+ rootPkg,
70
+ wsPkgs,
77
71
  })
78
72
 
79
- const options = { root, path, pkg: pkgJson, config: fullConfig }
73
+ const options = { root, path: pkg.path, pkg: pkg.pkgJson, config: fullConfig }
80
74
  log.verbose('run-all', options)
81
75
 
82
76
  // files can export multiple checks so flatten first
package/lib/util/files.js CHANGED
@@ -43,7 +43,14 @@ const getParsers = (dir, files, options) => {
43
43
  }
44
44
 
45
45
  const getRemovals = async (dir, files, options) => {
46
- const targets = fileEntries(dir, files, options).map(([t]) => globify(t))
46
+ const targets = fileEntries(dir, files, options)
47
+ .filter(([, source]) => {
48
+ if (typeof source === 'object' && typeof source.filter === 'function') {
49
+ return source.filter(options)
50
+ }
51
+ return true
52
+ })
53
+ .map(([t]) => globify(t))
47
54
  const globs = await Promise.all(targets.map(t => glob(t, { cwd: dir })))
48
55
  return globs.flat()
49
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/template-oss",
3
- "version": "4.7.0",
3
+ "version": "4.7.1",
4
4
  "description": "templated files used in npm CLI team oss projects",
5
5
  "main": "lib/content/index.js",
6
6
  "bin": {
@@ -17,7 +17,9 @@
17
17
  "test": "tap",
18
18
  "template-oss-apply": "template-oss-apply --force",
19
19
  "postlint": "template-oss-check",
20
- "postinstall": "template-oss-apply"
20
+ "postinstall": "template-oss-apply",
21
+ "test-all": "npm run test -ws -iwr --if-present",
22
+ "lint-all": "npm run lint -ws -iwr --if-present"
21
23
  },
22
24
  "repository": {
23
25
  "type": "git",
@@ -64,14 +66,20 @@
64
66
  "tap": {
65
67
  "timeout": 600,
66
68
  "nyc-arg": [
69
+ "--exclude",
70
+ "workspace/test-workspace/**",
67
71
  "--exclude",
68
72
  "tap-snapshots/**"
69
- ]
73
+ ],
74
+ "test-ignore": "^(workspace/test-workspace)/"
70
75
  },
71
76
  "templateOSS": {
72
77
  "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten."
73
78
  },
74
79
  "engines": {
75
80
  "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
76
- }
81
+ },
82
+ "workspaces": [
83
+ "workspace/test-workspace"
84
+ ]
77
85
  }