@npmcli/template-oss 4.1.2 → 4.3.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 (44) hide show
  1. package/bin/release-please.js +42 -28
  2. package/lib/apply/apply-files.js +1 -1
  3. package/lib/apply/index.js +1 -1
  4. package/lib/check/check-apply.js +5 -4
  5. package/lib/check/index.js +1 -1
  6. package/lib/config.js +178 -121
  7. package/lib/content/_job-matrix.yml +29 -0
  8. package/lib/content/_job.yml +8 -0
  9. package/lib/content/_on-ci.yml +30 -0
  10. package/lib/content/_step-checks.yml +24 -0
  11. package/lib/content/_step-deps.yml +2 -0
  12. package/lib/content/_step-git.yml +12 -0
  13. package/lib/content/_step-lint.yml +4 -0
  14. package/lib/content/{setup-node.yml → _step-node.yml} +12 -9
  15. package/lib/content/_step-test.yml +4 -0
  16. package/lib/content/_steps-setup.yml +6 -0
  17. package/lib/content/audit.yml +3 -6
  18. package/lib/content/ci-release.yml +31 -0
  19. package/lib/content/ci.yml +6 -54
  20. package/lib/content/codeql-analysis.yml +10 -17
  21. package/lib/content/commitlintrc.js +1 -1
  22. package/lib/content/dependabot.yml +2 -2
  23. package/lib/content/eslintrc.js +7 -0
  24. package/lib/content/gitignore +1 -14
  25. package/lib/content/index.js +62 -27
  26. package/lib/content/npmrc +1 -1
  27. package/lib/content/pkg.json +34 -14
  28. package/lib/content/post-dependabot.yml +55 -16
  29. package/lib/content/pull-request.yml +11 -13
  30. package/lib/content/release-please-config.json +5 -5
  31. package/lib/content/release-please-manifest.json +1 -1
  32. package/lib/content/release.yml +125 -0
  33. package/lib/index.js +27 -30
  34. package/lib/release-please/index.js +26 -5
  35. package/lib/util/files.js +71 -27
  36. package/lib/util/gitignore.js +34 -0
  37. package/lib/util/merge.js +21 -0
  38. package/lib/util/parser.js +76 -18
  39. package/lib/util/template.js +30 -21
  40. package/package.json +7 -2
  41. package/lib/content/release-please.yml +0 -73
  42. package/lib/content/release-test.yml +0 -46
  43. package/lib/content/setup-deps.yml +0 -1
  44. package/lib/content/setup-git.yml +0 -11
@@ -6,30 +6,24 @@ const main = require('../lib/release-please/index.js')
6
6
  const dryRun = !process.env.CI
7
7
  const [branch] = process.argv.slice(2)
8
8
 
9
- const setOutput = (key, val) => {
10
- if (val && (!Array.isArray(val) || val.length)) {
11
- if (dryRun) {
12
- if (key === 'pr') {
13
- console.log('PR:', val.title.toString())
14
- console.log('='.repeat(40))
15
- console.log(val.body.toString())
16
- console.log('='.repeat(40))
17
- for (const update of val.updates.filter(u => u.updater.changelogEntry)) {
18
- console.log('CHANGELOG:', update.path)
19
- console.log('-'.repeat(40))
20
- console.log(update.updater.changelogEntry)
21
- console.log('-'.repeat(40))
22
- }
23
- for (const update of val.updates.filter(u => u.updater.rawContent)) {
24
- console.log('package:', update.path)
25
- console.log('-'.repeat(40))
26
- console.log(JSON.parse(update.updater.rawContent).name)
27
- console.log(JSON.parse(update.updater.rawContent).version)
28
- console.log('-'.repeat(40))
29
- }
30
- }
31
- } else {
32
- core.setOutput(key, JSON.stringify(val))
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))
33
27
  }
34
28
  }
35
29
  }
@@ -39,10 +33,30 @@ main({
39
33
  repo: process.env.GITHUB_REPOSITORY,
40
34
  dryRun,
41
35
  branch,
42
- }).then(({ pr, releases, release }) => {
43
- setOutput('pr', pr)
44
- setOutput('releases', releases)
45
- setOutput('release', release)
36
+ }).then(({ pr, release, releases }) => {
37
+ if (pr) {
38
+ debugPr(pr)
39
+ core.setOutput('pr', JSON.stringify(pr))
40
+ core.setOutput('pr-branch', pr.headBranchName)
41
+ core.setOutput('pr-number', pr.number)
42
+ core.setOutput('pr-sha', pr.sha)
43
+ }
44
+
45
+ if (release) {
46
+ core.setOutput('release', JSON.stringify(release))
47
+ core.setOutput('release-path', release.path)
48
+ core.setOutput('release-version', release.version)
49
+ core.setOutput('release-tag', release.tagName)
50
+ core.setOutput('release-url', release.url)
51
+ }
52
+
53
+ if (releases) {
54
+ core.setOutput('releases', JSON.stringify(releases))
55
+ core.setOutput('release-flags', JSON.stringify(releases.map((r) => {
56
+ return r.path === '.' ? '-iwr' : `-w ${r.path}`
57
+ })))
58
+ }
59
+
46
60
  return null
47
61
  }).catch(err => {
48
62
  if (dryRun) {
@@ -3,7 +3,7 @@ const log = require('proc-log')
3
3
  const { rmEach, parseEach } = require('../util/files.js')
4
4
 
5
5
  const run = async (dir, files, options) => {
6
- const { rm = [], add = {} } = files
6
+ const { rm, add } = files
7
7
 
8
8
  log.verbose('apply-files', 'rm', rm)
9
9
  await rmEach(dir, rm, options, (f) => fs.rm(f))
@@ -1,6 +1,6 @@
1
1
  const run = require('../index.js')
2
2
 
3
- module.exports = (root, content) => run(root, content, [
3
+ module.exports = (root) => run(root, [
4
4
  require('./apply-files.js'),
5
5
  require('./apply-version.js'),
6
6
  ])
@@ -2,13 +2,14 @@ const log = require('proc-log')
2
2
  const { relative, basename } = require('path')
3
3
  const { rmEach, parseEach } = require('../util/files.js')
4
4
  const { partition } = require('lodash')
5
+ const localeCompare = require('@isaacs/string-locale-compare')('en')
5
6
 
6
7
  const solution = 'npx template-oss-apply --force'
7
8
 
8
9
  const run = async (type, dir, files, options) => {
9
10
  const res = []
10
11
  const rel = (f) => relative(options.root, f)
11
- const { add: addFiles = {}, rm: rmFiles = [] } = files
12
+ const { add: addFiles, rm: rmFiles } = files
12
13
 
13
14
  const rm = await rmEach(dir, rmFiles, options, (f) => rel(f))
14
15
  const [add, update] = partition(await parseEach(dir, addFiles, options, async (p) => {
@@ -28,7 +29,7 @@ const run = async (type, dir, files, options) => {
28
29
  if (rm.length) {
29
30
  res.push({
30
31
  title: `The following ${type} files need to be deleted:`,
31
- body: rm,
32
+ body: rm.sort(localeCompare),
32
33
  solution,
33
34
  })
34
35
  }
@@ -37,13 +38,13 @@ const run = async (type, dir, files, options) => {
37
38
  if (add.length) {
38
39
  res.push({
39
40
  title: `The following ${type} files need to be added:`,
40
- body: add,
41
+ body: add.sort(localeCompare),
41
42
  solution,
42
43
  })
43
44
  }
44
45
 
45
46
  log.verbose('check-apply', 'update', update)
46
- res.push(...update.map(({ file, diff }) => ({
47
+ res.push(...update.sort((a, b) => localeCompare(a.file, b.file)).map(({ file, diff }) => ({
47
48
  title: `The ${type} file ${basename(file)} needs to be updated:`,
48
49
  body: [`${file}\n${'='.repeat(40)}\n${diff}`],
49
50
  solution,
@@ -1,6 +1,6 @@
1
1
  const run = require('../index.js')
2
2
 
3
- module.exports = (root, content) => run(root, content, [
3
+ module.exports = (root) => run(root, [
4
4
  require('./check-apply.js'),
5
5
  require('./check-required.js'),
6
6
  require('./check-unwanted.js'),
package/lib/config.js CHANGED
@@ -1,101 +1,154 @@
1
- const { relative, dirname, join, posix, win32 } = require('path')
2
- const log = require('proc-log')
3
- const { uniq, defaults } = require('lodash')
1
+ const { relative, dirname, join, extname, posix, win32 } = require('path')
2
+ const { defaults, pick, omit, uniq } = require('lodash')
4
3
  const parseCIVersions = require('./util/parse-ci-versions.js')
5
4
  const getGitUrl = require('./util/get-git-url.js')
6
- const { name: NAME, version: LATEST_VERSION } = require('../package.json')
5
+ const gitignore = require('./util/gitignore.js')
6
+ const { withArrays } = require('./util/merge.js')
7
+ const { FILE_KEYS, parseConfig: parseFiles, getAddedFiles } = require('./util/files.js')
7
8
 
8
9
  const CONFIG_KEY = 'templateOSS'
9
10
  const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {}
10
11
 
11
- const getContent = (contentPath) => {
12
- if (typeof contentPath === 'string') {
13
- return defaults(require(contentPath), {
14
- sourceDir: dirname(require.resolve(contentPath)),
15
- })
16
- } else {
17
- // allow passing in content directly for tests
18
- return contentPath
12
+ const { name: NAME, version: LATEST_VERSION } = require('../package.json')
13
+ const MERGE_KEYS = [...FILE_KEYS, 'defaultContent', 'content']
14
+ const DEFAULT_CONTENT = require.resolve(NAME)
15
+
16
+ const merge = withArrays('branches', 'distPaths', 'allowPaths', 'ignorePaths')
17
+
18
+ const makePosix = (v) => v.split(win32.sep).join(posix.sep)
19
+ const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
20
+ const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
21
+ const posixGlob = (str) => `${posixDir(str)}**`
22
+
23
+ const getCmdPath = (key, { rootConfig, defaultConfig, isRoot, path, root }) => {
24
+ // Make a path relative from a workspace to the root if we are in a workspace
25
+ const wsToRoot = (p) => isRoot ? p : makePosix(join(relative(path, root), p))
26
+
27
+ const rootPath = rootConfig[key]
28
+ const defaultPath = defaultConfig[key]
29
+ const isLocal = rootPath && rootPath !== defaultPath
30
+
31
+ return {
32
+ isLocal,
33
+ root: !isLocal ? defaultPath : `node ${rootPath}`,
34
+ local: !isLocal ? defaultPath : `node ${wsToRoot(rootPath)}`,
19
35
  }
20
36
  }
21
37
 
22
- // falsy means no content of this type
23
- const getFiles = (config, content) => config ? content : null
24
- const getFileKeys = (files) => files ? Object.keys(files.add || {}) : []
25
- const negatePath = (p) => {
26
- // XXX: this negates the first part of each path for the gitignore
27
- // files. it might make sense to negate more specific portions of the
28
- // path for some paths like workspaces. so instead of ignoring !/workspaces
29
- // it would only ignore !/workspaces/a, !/workspaces/b, etc
30
- const [first, ...parts] = p.split(posix.sep)
31
- const isDir = parts.length > 0
32
- return `!${posix.sep}${first}${isDir ? posix.sep : ''}`
38
+ const mergeConfigs = (...configs) => {
39
+ const mergedConfig = merge(...configs.map(c => pick(c, MERGE_KEYS)))
40
+ return defaults(mergedConfig, {
41
+ defaultContent: DEFAULT_CONTENT,
42
+ // allow all file types by default
43
+ ...FILE_KEYS.reduce((acc, key) => {
44
+ acc[key] = true
45
+ return acc
46
+ }, {}),
47
+ })
33
48
  }
34
49
 
35
- const makePosix = (str) => str.split(win32.sep).join(posix.sep)
50
+ const readContentPath = (path) => {
51
+ if (!path) {
52
+ return {}
53
+ }
36
54
 
37
- const getConfig = async ({
38
- pkgs,
39
- workspaces,
55
+ let content = {}
56
+ const index = extname(path) === '.js' ? path : join(path, 'index.js')
57
+ const dir = dirname(index)
58
+
59
+ try {
60
+ content = require(index)
61
+ } catch {
62
+ // its ok if this fails since the content dir
63
+ // might only be to provide other files. the
64
+ // index.js is optional
65
+ }
66
+
67
+ return { content, dir }
68
+ }
69
+
70
+ const getConfig = (path, rawConfig) => {
71
+ const config = omit(readContentPath(path).content, FILE_KEYS)
72
+ return merge(config, rawConfig ? omit(rawConfig, FILE_KEYS) : {})
73
+ }
74
+
75
+ const getFiles = (path, rawConfig) => {
76
+ const { content, dir } = readContentPath(path)
77
+ if (!dir) {
78
+ return []
79
+ }
80
+ return [parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS)), dir]
81
+ }
82
+
83
+ const getFullConfig = async ({
84
+ // the path to the root of the repo
40
85
  root,
86
+ // the path to the package being operated on
87
+ // this is the same as root when operating on the root
41
88
  path,
42
- pkg,
43
- // default content path is looked up via require.resolve
44
- // so use the name of this module since package.json#main
45
- // points to the content dir
46
- content: contentPath = NAME,
47
- config: {
48
- rootRepo,
49
- rootModule,
50
- workspaceRepo,
51
- workspaceModule,
52
- version,
53
- ...pkgConfig // this includes config merged in from root
54
- },
89
+ // the full contents of the package.json for this package
90
+ pkgJson,
91
+ // an array of all package info {pkgJson,path,config}[]
92
+ pkgs,
93
+ // an array of all workspaces in this repo
94
+ workspaces,
95
+ // the config from the package.json in the root
96
+ rootConfig: _rootConfig,
97
+ // the config from the package.json being operated on
98
+ pkgConfig: _pkgConfig,
55
99
  }) => {
56
100
  const isRoot = root === path
57
- const isLatest = version === LATEST_VERSION
58
- const isDogFood = pkg.name === NAME
101
+ const isLatest = _pkgConfig.version === LATEST_VERSION
102
+ const isDogFood = pkgJson.name === NAME
59
103
  const isForce = process.argv.includes('--force')
60
- const rawPkgConfig = getPkgConfig(pkg)
61
-
62
- // this is written to ci yml files so it needs to always use posix
63
- const pkgRelPath = makePosix(relative(root, path))
64
- const gitUrl = await getGitUrl(root)
65
104
 
66
- const {
67
- rootRepo: rootRepoContent,
68
- rootModule: rootModuleContent,
69
- workspaceRepo: workspaceRepoContent,
70
- workspaceModule: workspaceModuleContent,
71
- ...baseContent
72
- } = getContent(contentPath)
73
-
74
- let repoFiles, moduleFiles
75
- const ignorePaths = []
76
-
77
- if (isRoot) {
78
- repoFiles = getFiles(rootRepo, rootRepoContent)
79
- moduleFiles = getFiles(rootModule, rootModuleContent)
80
- ignorePaths.push(
81
- // allow workspace paths if they are set, this is directly from
82
- // map-workspaces so normalize to posix paths for gitignore
83
- ...workspaces.map((p) => makePosix(relative(root, p))),
84
- // allow both the repo and module files since this is the root
85
- ...getFileKeys(repoFiles),
86
- ...getFileKeys(moduleFiles),
87
- // allow all workspace repo level files
88
- ...pkgs.filter((p) => p.path !== path).flatMap((p) =>
89
- getFileKeys(getFiles(p.config.workspaceRepo, workspaceRepoContent))
90
- )
91
- )
92
- } else {
93
- repoFiles = getFiles(workspaceRepo, workspaceRepoContent)
94
- moduleFiles = getFiles(workspaceModule, workspaceModuleContent)
95
- // In a workspace gitignores are relative to the workspace dir
96
- // so we should only allow added module files
97
- ignorePaths.push(...getFileKeys(moduleFiles))
98
- }
105
+ // These config items are merged betweent the root and child workspaces and only come from
106
+ // the package.json because they can be used to read configs from other the content directories
107
+ const mergedConfig = mergeConfigs(_rootConfig, _pkgConfig)
108
+
109
+ const defaultConfig = getConfig(DEFAULT_CONTENT)
110
+ const [defaultFiles, defaultDir] = getFiles(DEFAULT_CONTENT, mergedConfig)
111
+ const useDefault = mergedConfig.defaultContent && defaultConfig
112
+
113
+ const rootConfig = getConfig(_rootConfig.content, _rootConfig)
114
+ const [rootFiles, rootDir] = getFiles(_rootConfig.content, mergedConfig)
115
+
116
+ // The content config only gets set from the package we are in, it doesn't inherit
117
+ // anything from the root
118
+ const rootPkgConfig = merge(useDefault, rootConfig)
119
+ const pkgConfig = merge(useDefault, getConfig(_pkgConfig.content, _pkgConfig))
120
+ const [pkgFiles, pkgDir] = getFiles(mergedConfig.content, mergedConfig)
121
+
122
+ // Files get merged in from the default content (that template-oss provides) as well
123
+ // as any content paths provided from the root or the workspace
124
+ const fileDirs = uniq([useDefault && defaultDir, rootDir, pkgDir].filter(Boolean))
125
+ const files = merge(useDefault && defaultFiles, rootFiles, pkgFiles)
126
+ const repoFiles = isRoot ? files.rootRepo : files.workspaceRepo
127
+ const moduleFiles = isRoot ? files.rootModule : files.workspaceModule
128
+
129
+ const allowRootDirs = [
130
+ // Allways allow module files in root or workspaces
131
+ ...getAddedFiles(moduleFiles),
132
+ ...isRoot ? [
133
+ // in the root allow all repo files
134
+ ...getAddedFiles(repoFiles),
135
+ // and allow all workspace repo level files in the root
136
+ ...pkgs
137
+ .filter(p => p.path !== root && p.config.workspaceRepo !== false)
138
+ .flatMap(() => getAddedFiles(files.workspaceRepo)),
139
+ ] : [],
140
+ ]
141
+
142
+ // root only configs
143
+ const npmPath = getCmdPath('npm', { rootConfig, defaultConfig, isRoot, path, root })
144
+ const npxPath = getCmdPath('npx', { rootConfig, defaultConfig, isRoot, path, root })
145
+
146
+ // these are written to ci yml files so it needs to always use posix
147
+ const pkgPath = makePosix(relative(root, path)) || '.'
148
+
149
+ // we use the raw paths from the package.json workspaces as ignore patterns in
150
+ // some cases. the workspaces passed in have already been run through map workspaces
151
+ const workspacePaths = (pkgJson.workspaces || []).map(deglob)
99
152
 
100
153
  // all derived keys
101
154
  const derived = {
@@ -106,7 +159,8 @@ const getConfig = async ({
106
159
  // For these cases it is helpful to know if we are in a
107
160
  // monorepo since template-oss might be used only for
108
161
  // workspaces and not the root or vice versa.
109
- isMono: (isRoot && workspaces.length > 0) || !isRoot,
162
+ isRootMono: isRoot && !!workspaces.length,
163
+ isMono: !!workspaces.length,
110
164
  // repo
111
165
  repoDir: root,
112
166
  repoFiles,
@@ -116,14 +170,41 @@ const getConfig = async ({
116
170
  moduleFiles,
117
171
  applyModule: !!moduleFiles,
118
172
  // package
119
- pkgName: pkg.name,
120
- pkgNameFs: pkg.name.replace(/\//g, '-').replace(/@/g, ''),
121
- pkgRelPath: pkgRelPath,
122
- pkgPrivate: !!pkg.private,
173
+ pkgName: pkgJson.name,
174
+ pkgNameFs: pkgJson.name.replace(/\//g, '-').replace(/@/g, ''),
175
+ // paths
176
+ pkgPath,
177
+ pkgDir: posixDir(pkgPath),
178
+ pkgGlob: posixGlob(pkgPath),
179
+ pkgFlags: isRoot ? '-iwr' : `-w ${pkgJson.name}`,
180
+ allFlags: '-ws -iwr --if-present',
181
+ workspacePaths,
182
+ workspaceGlobs: workspacePaths.map(posixGlob),
123
183
  // booleans to control application of updates
124
184
  isForce,
125
185
  isDogFood,
126
186
  isLatest,
187
+ // whether to install and update npm in ci
188
+ // only do this if we aren't using a custom path to bin
189
+ updateNpm: !npmPath.isLocal,
190
+ rootNpmPath: npmPath.root,
191
+ localNpmPath: npmPath.local,
192
+ rootNpxPath: npxPath.root,
193
+ // lockfiles are only present at the root, so this only should be set for
194
+ // all workspaces based on the root
195
+ lockfile: rootPkgConfig.lockfile,
196
+ // gitignore
197
+ ignorePaths: [
198
+ ...gitignore.sort([
199
+ ...gitignore.allowRootDir(allowRootDirs),
200
+ ...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
201
+ ...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
202
+ ...(pkgConfig.ignorePaths || []),
203
+ ]),
204
+ // these cant be sorted since they rely on order
205
+ // to allow a previously ignored directoy
206
+ ...isRoot ? gitignore.allowDir(workspaces.map((p) => makePosix(relative(root, p)))) : [],
207
+ ],
127
208
  // needs update if we are dogfooding this repo, with force argv, or its
128
209
  // behind the current version
129
210
  needsUpdate: isForce || isDogFood || !isLatest,
@@ -131,55 +212,31 @@ const getConfig = async ({
131
212
  __NAME__: NAME,
132
213
  __CONFIG_KEY__: CONFIG_KEY,
133
214
  __VERSION__: LATEST_VERSION,
215
+ __PARTIAL_DIRS__: fileDirs,
134
216
  }
135
217
 
136
- // merge the rest of base and pkg content to make the
137
- // full content object
138
- const content = { ...baseContent, ...pkgConfig }
139
-
140
- // set some defaults on content that can be overwritten unlike
141
- // derived values which are calculated from other config
142
- const contentDefaults = {}
143
-
144
- if (content.npmBin && content.npmBin !== baseContent.npmBin) {
145
- // make it relative to each workspace if they did not set the config themselves
146
- if (!rawPkgConfig.npmBin) {
147
- content.npmBin = makePosix(join(relative(path, root), content.npmBin))
148
- }
149
- // a bit of a hack but allow custom node paths or no node path at all
150
- // checks if the first thing has node somewhere in it and if it doesnt
151
- // puts a system node in front of the script
152
- const execPaths = content.npmBin.split(' ')[0].split(posix.sep)
153
- if (execPaths.every(p => p !== 'node')) {
154
- content.npmBin = `node ${content.npmBin}`
155
- }
156
- }
157
- if (Array.isArray(content.ciVersions)) {
158
- const parsed = parseCIVersions(content.ciVersions)
159
- contentDefaults.engines = parsed.engines
160
- content.ciVersions = parsed.targets
161
- log.verbose('config ci', parsed)
218
+ if (pkgConfig.ciVersions) {
219
+ const versions = pkgConfig.ciVersions
220
+ const defaultVersions = defaultConfig.ciVersions
221
+ const parsed = parseCIVersions(versions === 'latest' ? defaultVersions.slice(-1) : versions)
222
+ derived.ciVersions = parsed.targets
223
+ derived.engines = pkgConfig.engines || parsed.engines
162
224
  }
163
225
 
226
+ const gitUrl = await getGitUrl(root)
164
227
  if (gitUrl) {
165
- contentDefaults.repository = {
228
+ derived.repository = {
166
229
  type: 'git',
167
230
  url: gitUrl,
168
- ...(pkgRelPath ? { directory: pkgRelPath } : {}),
231
+ ...(!isRoot ? { directory: pkgPath } : {}),
169
232
  }
170
233
  }
171
234
 
172
- contentDefaults.ignorePaths = uniq(
173
- [...ignorePaths, ...(content.distPaths || [])].map(negatePath)
174
- ).sort()
175
-
176
- log.verbose('config', 'defaults', contentDefaults)
177
-
178
235
  return {
179
- ...defaults(content, contentDefaults),
236
+ ...pkgConfig,
180
237
  ...derived,
181
238
  }
182
239
  }
183
240
 
184
- module.exports = getConfig
241
+ module.exports = getFullConfig
185
242
  module.exports.getPkgConfig = getPkgConfig
@@ -0,0 +1,29 @@
1
+ name: {{ jobName }}
2
+ if: github.repository_owner == 'npm'
3
+ strategy:
4
+ fail-fast: false
5
+ matrix:
6
+ platform:
7
+ - name: Linux
8
+ os: ubuntu-latest
9
+ shell: bash
10
+ {{#if macCI}}
11
+ - name: macOS
12
+ os: macos-latest
13
+ shell: bash
14
+ {{/if}}
15
+ {{#if windowsCI}}
16
+ - name: Windows
17
+ os: windows-latest
18
+ shell: cmd
19
+ {{/if}}
20
+ node-version:
21
+ {{#each ciVersions}}
22
+ - {{ . }}
23
+ {{/each}}
24
+ runs-on: $\{{ matrix.platform.os }}
25
+ defaults:
26
+ run:
27
+ shell: $\{{ matrix.platform.shell }}
28
+ steps:
29
+ {{> stepsSetup jobNodeMatrix=true }}
@@ -0,0 +1,8 @@
1
+ name: {{ jobName }}
2
+ if: github.repository_owner == 'npm' {{~#if jobIf}} && {{{ jobIf }}}{{/if}}
3
+ runs-on: ubuntu-latest
4
+ defaults:
5
+ run:
6
+ shell: bash
7
+ steps:
8
+ {{> stepsSetup }}
@@ -0,0 +1,30 @@
1
+ workflow_dispatch:
2
+ pull_request:
3
+ {{#if isWorkspace}}
4
+ paths:
5
+ - {{ pkgGlob }}
6
+ {{/if}}
7
+ {{#if isRootMono}}
8
+ paths-ignore:
9
+ {{#each workspaceGlob}}
10
+ - {{ . }}
11
+ {{/each}}
12
+ {{/if}}
13
+ push:
14
+ branches:
15
+ {{#each branches}}
16
+ - {{ . }}
17
+ {{/each}}
18
+ {{#if isWorkspace}}
19
+ paths:
20
+ - {{ pkgGlob }}
21
+ {{/if}}
22
+ {{#if isRootMono}}
23
+ paths-ignore:
24
+ {{#each workspaceGlob}}
25
+ - {{ . }}
26
+ {{/each}}
27
+ {{/if}}
28
+ schedule:
29
+ # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1
30
+ - cron: "0 9 * * 1"
@@ -0,0 +1,24 @@
1
+ - name: {{#if jobCheck.sha}}Create{{else}}Conclude{{/if}} Check
2
+ uses: LouisBrunner/checks-action@v1.3.1
3
+ {{#if jobCheck.sha}}
4
+ id: check
5
+ {{#if jobCheck.if}}if: {{ jobCheck.if }}{{/if}}
6
+ {{else}}
7
+ if: always()
8
+ {{/if}}
9
+ with:
10
+ token: $\{{ secrets.GITHUB_TOKEN }}
11
+ {{#if jobCheck.sha}}
12
+ status: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}in_progress{{/if}}
13
+ name: {{#if jobCheck.name}}{{ jobCheck.name }}{{else}}{{ jobName }}{{/if}}
14
+ sha: {{ jobCheck.sha }}
15
+ # XXX: this does not work when using the default GITHUB_TOKEN.
16
+ # Instead we post the main job url to the PR as a comment which
17
+ # will link to all the other checks. To work around this we would
18
+ # need to create a GitHub that would create on-demand tokens.
19
+ # https://github.com/LouisBrunner/checks-action/issues/18
20
+ # details_url:
21
+ {{else}}
22
+ conclusion: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}$\{{ job.status }}{{/if}}
23
+ check_id: {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}$\{{ steps.check.outputs.check_id }}{{/if}}
24
+ {{/if}}
@@ -0,0 +1,2 @@
1
+ - name: Install Dependencies
2
+ run: {{ rootNpmPath }} i --ignore-scripts --no-audit --no-fund {{~#if jobDepFlags}} {{ jobDepFlags }}{{/if}}
@@ -0,0 +1,12 @@
1
+ - name: Checkout
2
+ uses: actions/checkout@v3
3
+ {{#if jobCheckout}}
4
+ with:
5
+ {{#each jobCheckout}}
6
+ {{ @key }}: {{ this }}
7
+ {{/each}}
8
+ {{/if}}
9
+ - name: Setup Git User
10
+ run: |
11
+ git config --global user.email "npm-cli+bot@github.com"
12
+ git config --global user.name "npm CLI robot"
@@ -0,0 +1,4 @@
1
+ - name: Lint
2
+ run: {{ rootNpmPath }} run lint --ignore-scripts
3
+ - name: Post Lint
4
+ run: {{ rootNpmPath }} run postlint --ignore-scripts