@npmcli/template-oss 4.18.1 → 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.
- package/README.md +15 -11
- package/bin/release-manager.js +6 -0
- package/lib/config.js +112 -136
- package/lib/content/{_job-matrix.yml → _job-matrix-yml.hbs} +1 -1
- package/lib/content/{_job-release-integration.yml → _job-release-integration-yml.hbs} +2 -2
- package/lib/content/{_job.yml → _job-yml.hbs} +1 -1
- package/lib/content/_step-node-yml.hbs +60 -0
- package/lib/content/_steps-setup-yml.hbs +6 -0
- package/lib/content/{audit.yml → audit-yml.hbs} +2 -2
- package/lib/content/{ci-release.yml → ci-release-yml.hbs} +7 -7
- package/lib/content/ci-yml.hbs +13 -0
- package/lib/content/{codeql-analysis.yml → codeql-analysis-yml.hbs} +1 -1
- package/lib/content/{eslintrc.js → eslintrc-js.hbs} +11 -1
- package/lib/content/{gitignore → gitignore.hbs} +2 -0
- package/lib/content/index.js +47 -42
- package/lib/content/{pkg.json → package-json.hbs} +8 -9
- package/lib/content/{post-dependabot.yml → post-dependabot-yml.hbs} +1 -1
- package/lib/content/{pull-request.yml → pull-request-yml.hbs} +1 -1
- package/lib/content/{release.yml → release-yml.hbs} +10 -10
- package/lib/content/tsconfig-json.hbs +17 -0
- package/lib/util/ci-versions.js +80 -0
- package/lib/util/files.js +29 -20
- package/lib/util/get-cmd-path.js +36 -0
- package/lib/util/git.js +6 -11
- package/lib/util/import-or-require.js +29 -0
- package/lib/util/merge.js +0 -1
- package/lib/util/parser.js +6 -1
- package/lib/util/path.js +13 -0
- package/lib/util/template.js +9 -6
- package/package.json +10 -10
- package/lib/content/_step-node.yml +0 -57
- package/lib/content/_steps-setup.yml +0 -6
- package/lib/content/ci.yml +0 -13
- package/lib/util/parse-ci-versions.js +0 -78
- /package/lib/content/{CODEOWNERS → CODEOWNERS.hbs} +0 -0
- /package/lib/content/{CODE_OF_CONDUCT.md → CODE_OF_CONDUCT-md.hbs} +0 -0
- /package/lib/content/{CONTRIBUTING.md → CONTRIBUTING-md.hbs} +0 -0
- /package/lib/content/{LICENSE.md → LICENSE-md.hbs} +0 -0
- /package/lib/content/{SECURITY.md → SECURITY-md.hbs} +0 -0
- /package/lib/content/{_on-ci.yml → _on-ci-yml.hbs} +0 -0
- /package/lib/content/{_step-audit.yml → _step-audit-yml.hbs} +0 -0
- /package/lib/content/{_step-checks.yml → _step-checks-yml.hbs} +0 -0
- /package/lib/content/{_step-deps.yml → _step-deps-yml.hbs} +0 -0
- /package/lib/content/{_step-git.yml → _step-git-yml.hbs} +0 -0
- /package/lib/content/{_step-lint.yml → _step-lint-yml.hbs} +0 -0
- /package/lib/content/{_step-test.yml → _step-test-yml.hbs} +0 -0
- /package/lib/content/{bug.yml → bug-yml.hbs} +0 -0
- /package/lib/content/{commitlintrc.js → commitlintrc-js.hbs} +0 -0
- /package/lib/content/{config.yml → config-yml.hbs} +0 -0
- /package/lib/content/{dependabot.yml → dependabot-yml.hbs} +0 -0
- /package/lib/content/{npmrc → npmrc.hbs} +0 -0
- /package/lib/content/{release-please-config.json → release-please-config-json.hbs} +0 -0
- /package/lib/content/{release-please-manifest.json → release-please-manifest-json.hbs} +0 -0
- /package/lib/content/{settings.yml → settings-yml.hbs} +0 -0
- /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
|
-
|
|
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`
|
|
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
|
-
|
|
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
|
-
|
|
73
|
-
config (with some derived values generated in [`config.js`](./lib/config.js)
|
|
74
|
-
|
|
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
|
-
|
|
77
|
-
|
|
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
|
|
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 `
|
|
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
|
|
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
|
|
package/bin/release-manager.js
CHANGED
|
@@ -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,42 +1,31 @@
|
|
|
1
|
-
const { relative, dirname, join, extname
|
|
2
|
-
const { defaults, pick, omit, uniq } = require('lodash')
|
|
1
|
+
const { relative, dirname, join, extname } = require('path')
|
|
2
|
+
const { defaults, defaultsDeep, pick, omit, uniq, isPlainObject } = require('lodash')
|
|
3
3
|
const semver = require('semver')
|
|
4
|
-
const
|
|
4
|
+
const ciVersions = require('./util/ci-versions.js')
|
|
5
5
|
const parseDependabot = require('./util/dependabot.js')
|
|
6
6
|
const git = require('./util/git.js')
|
|
7
7
|
const gitignore = require('./util/gitignore.js')
|
|
8
|
-
const {
|
|
8
|
+
const { mergeWithCustomizers, customizers } = require('./util/merge.js')
|
|
9
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')
|
|
10
15
|
|
|
11
16
|
const CONFIG_KEY = 'templateOSS'
|
|
12
|
-
const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {}
|
|
13
|
-
|
|
14
|
-
const { name: NAME, version: LATEST_VERSION } = require('../package.json')
|
|
15
|
-
const { minimatch } = require('minimatch')
|
|
16
17
|
const MERGE_KEYS = [...FILE_KEYS, 'defaultContent', 'content']
|
|
17
18
|
const DEFAULT_CONTENT = require.resolve(NAME)
|
|
19
|
+
const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {}
|
|
18
20
|
|
|
19
|
-
const merge =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const getCmdPath = (key, { rootConfig, defaultConfig, isRoot, pkg, rootPkg }) => {
|
|
27
|
-
// Make a path relative from a workspace to the root if we are in a workspace
|
|
28
|
-
const wsToRoot = (p) => isRoot ? p : makePosix(join(relative(pkg.path, rootPkg.path), p))
|
|
29
|
-
|
|
30
|
-
const rootPath = rootConfig[key]
|
|
31
|
-
const defaultPath = defaultConfig[key]
|
|
32
|
-
const isLocal = rootPath && rootPath !== defaultPath
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
isLocal,
|
|
36
|
-
root: !isLocal ? defaultPath : `node ${rootPath}`,
|
|
37
|
-
local: !isLocal ? defaultPath : `node ${wsToRoot(rootPath)}`,
|
|
21
|
+
const merge = mergeWithCustomizers(
|
|
22
|
+
customizers.mergeArrays('branches', 'distPaths', 'allowPaths', 'ignorePaths'),
|
|
23
|
+
(value, srcValue, key) => {
|
|
24
|
+
if (key === 'ciVersions' && (Array.isArray(srcValue) || isPlainObject(srcValue))) {
|
|
25
|
+
return { ...ciVersions.parse(value), ...ciVersions.parse(srcValue) }
|
|
26
|
+
}
|
|
38
27
|
}
|
|
39
|
-
|
|
28
|
+
)
|
|
40
29
|
|
|
41
30
|
const mergeConfigs = (...configs) => {
|
|
42
31
|
const mergedConfig = merge(...configs.map(c => pick(c, MERGE_KEYS)))
|
|
@@ -50,37 +39,33 @@ const mergeConfigs = (...configs) => {
|
|
|
50
39
|
})
|
|
51
40
|
}
|
|
52
41
|
|
|
53
|
-
const readContentPath = (path) => {
|
|
42
|
+
const readContentPath = async (path) => {
|
|
54
43
|
if (!path) {
|
|
55
44
|
return {}
|
|
56
45
|
}
|
|
57
46
|
|
|
58
|
-
let content = {}
|
|
59
47
|
const index = extname(path) === '.js' ? path : join(path, 'index.js')
|
|
60
48
|
const dir = dirname(index)
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
content = require(index)
|
|
64
|
-
} catch {
|
|
65
|
-
// its ok if this fails since the content dir
|
|
66
|
-
// might only be to provide other files. the
|
|
67
|
-
// index.js is optional
|
|
68
|
-
}
|
|
49
|
+
const content = await importOrRequire(index)
|
|
69
50
|
|
|
70
51
|
return { content, dir }
|
|
71
52
|
}
|
|
72
53
|
|
|
73
|
-
const getConfig = (path, rawConfig) => {
|
|
74
|
-
const
|
|
54
|
+
const getConfig = async (path, rawConfig) => {
|
|
55
|
+
const { content } = await readContentPath(path)
|
|
56
|
+
const config = omit(content, FILE_KEYS)
|
|
75
57
|
return merge(config, rawConfig ? omit(rawConfig, FILE_KEYS) : {})
|
|
76
58
|
}
|
|
77
59
|
|
|
78
|
-
const getFiles = (path, rawConfig) => {
|
|
79
|
-
const { content, dir } = readContentPath(path)
|
|
60
|
+
const getFiles = async (path, rawConfig, templateSettings) => {
|
|
61
|
+
const { content, dir } = await readContentPath(path)
|
|
80
62
|
if (!dir) {
|
|
81
63
|
return []
|
|
82
64
|
}
|
|
83
|
-
return [
|
|
65
|
+
return [
|
|
66
|
+
parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS), templateSettings),
|
|
67
|
+
dir,
|
|
68
|
+
]
|
|
84
69
|
}
|
|
85
70
|
|
|
86
71
|
const getFullConfig = async ({
|
|
@@ -105,43 +90,18 @@ const getFullConfig = async ({
|
|
|
105
90
|
// These config items are merged betweent the root and child workspaces and only come from
|
|
106
91
|
// the package.json because they can be used to read configs from other the content directories
|
|
107
92
|
const mergedConfig = mergeConfigs(rootPkg.config, pkg.config)
|
|
108
|
-
|
|
109
|
-
const defaultConfig = getConfig(DEFAULT_CONTENT)
|
|
110
|
-
const [defaultFiles, defaultDir] = getFiles(DEFAULT_CONTENT, mergedConfig)
|
|
93
|
+
const defaultConfig = await getConfig(DEFAULT_CONTENT)
|
|
111
94
|
const useDefault = mergedConfig.defaultContent && defaultConfig
|
|
112
95
|
|
|
113
|
-
const rootConfig = getConfig(rootPkg.config.content, rootPkg.config)
|
|
114
|
-
const [rootFiles, rootDir] = getFiles(rootPkg.config.content, mergedConfig)
|
|
96
|
+
const rootConfig = await getConfig(rootPkg.config.content, rootPkg.config)
|
|
115
97
|
|
|
116
98
|
// The content config only gets set from the package we are in, it doesn't inherit
|
|
117
99
|
// anything from the root
|
|
118
100
|
const rootPkgConfig = merge(useDefault, rootConfig)
|
|
119
|
-
const pkgConfig = merge(useDefault, getConfig(pkg.config.content, pkg.config))
|
|
120
|
-
const [pkgFiles, pkgDir] = getFiles(mergedConfig.content, mergedConfig)
|
|
101
|
+
const pkgConfig = merge(useDefault, await getConfig(pkg.config.content, pkg.config))
|
|
121
102
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const fileDirs = uniq([useDefault && defaultDir, rootDir, pkgDir].filter(Boolean))
|
|
125
|
-
const files = mergeFiles(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 !== rootPkg.path && p.config.workspaceRepo !== false)
|
|
138
|
-
.flatMap(() => getAddedFiles(files.workspaceRepo)),
|
|
139
|
-
] : [],
|
|
140
|
-
]
|
|
141
|
-
|
|
142
|
-
// root only configs
|
|
143
|
-
const npmPath = getCmdPath('npm', { rootConfig, defaultConfig, isRoot, pkg, rootPkg })
|
|
144
|
-
const npxPath = getCmdPath('npx', { rootConfig, defaultConfig, isRoot, pkg, rootPkg })
|
|
103
|
+
const npmPath = getCmdPath('npm', { pkgConfig, rootConfig, isRoot, pkg, rootPkg })
|
|
104
|
+
const npxPath = getCmdPath('npx', { pkgConfig, rootConfig, isRoot, pkg, rootPkg })
|
|
145
105
|
|
|
146
106
|
// these are written to ci yml files so it needs to always use posix
|
|
147
107
|
const pkgPath = makePosix(relative(rootPkg.path, pkg.path)) || '.'
|
|
@@ -157,9 +117,14 @@ const getFullConfig = async ({
|
|
|
157
117
|
|
|
158
118
|
const branches = uniq([...pkgConfig.branches ?? [], pkgConfig.releaseBranch]).filter(Boolean)
|
|
159
119
|
const gitBranches = await git.getBranches(rootPkg.path, branches)
|
|
160
|
-
const currentBranch = await git.currentBranch(rootPkg.path)
|
|
161
|
-
const isReleaseBranch = currentBranch ? minimatch(currentBranch, pkgConfig.releaseBranch) : false
|
|
162
120
|
const defaultBranch = await git.defaultBranch(rootPkg.path) ?? 'main'
|
|
121
|
+
const isReleaseBranch = !!pkgConfig.backport
|
|
122
|
+
const publishTag = isReleaseBranch ? `next-${pkgConfig.backport}` : 'latest'
|
|
123
|
+
const releaseBranch = isReleaseBranch
|
|
124
|
+
? pkgConfig.releaseBranch.replace(/\*/g, pkgConfig.backport)
|
|
125
|
+
: defaultBranch
|
|
126
|
+
|
|
127
|
+
const esm = pkg.pkgJson?.type === 'module' || !!pkgConfig.typescript || !!pkgConfig.esm
|
|
163
128
|
|
|
164
129
|
// all derived keys
|
|
165
130
|
const derived = {
|
|
@@ -179,25 +144,17 @@ const getFullConfig = async ({
|
|
|
179
144
|
// controls whether we are in a monorepo with any public workspaces
|
|
180
145
|
isMonoPublic: isMono && !!publicPkgs.filter(p => p.path !== rootPkg.path).length,
|
|
181
146
|
// git
|
|
182
|
-
defaultBranch,
|
|
183
|
-
baseBranch: isReleaseBranch ? currentBranch : defaultBranch,
|
|
184
147
|
branches: gitBranches.branches,
|
|
185
148
|
branchPatterns: gitBranches.patterns,
|
|
186
149
|
isReleaseBranch,
|
|
187
|
-
|
|
150
|
+
releaseBranch,
|
|
151
|
+
publishTag,
|
|
188
152
|
dependabot: parseDependabot(pkgConfig, defaultConfig, gitBranches.branches),
|
|
189
|
-
//
|
|
153
|
+
// paths
|
|
190
154
|
repoDir: rootPkg.path,
|
|
191
|
-
repoFiles,
|
|
192
|
-
applyRepo: !!repoFiles,
|
|
193
|
-
// module
|
|
194
155
|
moduleDir: pkg.path,
|
|
195
|
-
moduleFiles,
|
|
196
|
-
applyModule: !!moduleFiles,
|
|
197
|
-
// package
|
|
198
156
|
pkgName: pkg.pkgJson.name,
|
|
199
157
|
pkgNameFs: pkg.pkgJson.name.replace(/\//g, '-').replace(/@/g, ''),
|
|
200
|
-
// paths
|
|
201
158
|
pkgPath,
|
|
202
159
|
pkgDir: posixDir(pkgPath),
|
|
203
160
|
pkgGlob: posixGlob(pkgPath),
|
|
@@ -205,6 +162,12 @@ const getFullConfig = async ({
|
|
|
205
162
|
allFlags: isMono ? '-ws -iwr --if-present' : '',
|
|
206
163
|
workspacePaths,
|
|
207
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,
|
|
208
171
|
// booleans to control application of updates
|
|
209
172
|
isForce,
|
|
210
173
|
isDogFood,
|
|
@@ -218,20 +181,8 @@ const getFullConfig = async ({
|
|
|
218
181
|
// lockfiles are only present at the root, so this only should be set for
|
|
219
182
|
// all workspaces based on the root
|
|
220
183
|
lockfile: rootPkgConfig.lockfile,
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
...gitignore.sort([
|
|
224
|
-
...gitignore.allowRootDir(allowRootDirs),
|
|
225
|
-
...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
|
|
226
|
-
...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
|
|
227
|
-
...(pkgConfig.ignorePaths || []),
|
|
228
|
-
]),
|
|
229
|
-
// these cant be sorted since they rely on order
|
|
230
|
-
// to allow a previously ignored directoy
|
|
231
|
-
...isRoot
|
|
232
|
-
? gitignore.allowDir(wsPkgs.map((p) => makePosix(relative(rootPkg.path, p.path))))
|
|
233
|
-
: [],
|
|
234
|
-
],
|
|
184
|
+
// ci versions / engines
|
|
185
|
+
ciVersions: ciVersions.get(pkg.pkgJson.engines?.node, pkgConfig),
|
|
235
186
|
// needs update if we are dogfooding this repo, with force argv, or its
|
|
236
187
|
// behind the current version
|
|
237
188
|
needsUpdate: isForce || isDogFood || !isLatest,
|
|
@@ -239,42 +190,22 @@ const getFullConfig = async ({
|
|
|
239
190
|
__NAME__: NAME,
|
|
240
191
|
__CONFIG_KEY__: CONFIG_KEY,
|
|
241
192
|
__VERSION__: LATEST_VERSION,
|
|
242
|
-
__PARTIAL_DIRS__: fileDirs,
|
|
243
193
|
}
|
|
244
194
|
|
|
245
|
-
if (pkgConfig.
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const { ciVersions } = [isWorkspace ? rootPkgConfig : {}, defaultConfig]
|
|
249
|
-
.find(c => Array.isArray(c.ciVersions))
|
|
250
|
-
const defaultLatest = ciVersions[ciVersions.length - 1]
|
|
251
|
-
versions = [].concat(versions).map(v => v === 'latest' ? defaultLatest : v)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const { targets, engines } = parseCIVersions(versions)
|
|
255
|
-
|
|
256
|
-
// get just a list of the target versions (not ranges)
|
|
257
|
-
// these are used for the node version when doing engines checks
|
|
258
|
-
// since we want to test in the lowest version of each major
|
|
259
|
-
let targetVersions = targets.filter(t => semver.valid(t))
|
|
260
|
-
// if the versions are all ranges then convert them to the lower bound of each range
|
|
261
|
-
if (!targetVersions.length) {
|
|
262
|
-
targetVersions = targets.filter(t => semver.validRange(t)).map(t => {
|
|
263
|
-
return new semver.Range(t).set[0][0].semver.version
|
|
264
|
-
})
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
derived.ciVersions = targets
|
|
268
|
-
derived.baseCiVersions = targetVersions
|
|
269
|
-
derived.engines = pkgConfig.engines || engines
|
|
195
|
+
if (!pkgConfig.eslint && Array.isArray(pkgConfig.requiredPackages?.devDependencies)) {
|
|
196
|
+
pkgConfig.requiredPackages.devDependencies =
|
|
197
|
+
pkgConfig.requiredPackages.devDependencies.filter(p => !p.includes('eslint'))
|
|
270
198
|
}
|
|
271
199
|
|
|
272
|
-
if (
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
+
)
|
|
278
209
|
}
|
|
279
210
|
|
|
280
211
|
const gitUrl = await git.getUrl(rootPkg.path)
|
|
@@ -286,10 +217,55 @@ const getFullConfig = async ({
|
|
|
286
217
|
}
|
|
287
218
|
}
|
|
288
219
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
|
293
269
|
}
|
|
294
270
|
|
|
295
271
|
module.exports = getFullConfig
|
|
@@ -22,14 +22,14 @@ steps:
|
|
|
22
22
|
- name: Publish
|
|
23
23
|
env:
|
|
24
24
|
PUBLISH_TOKEN: $\{{ secrets.PUBLISH_TOKEN }}
|
|
25
|
-
run: npm publish --provenance
|
|
25
|
+
run: npm publish --provenance --tag={{ publishTag }}
|
|
26
26
|
{{else}}
|
|
27
27
|
runs-on: ubuntu-latest
|
|
28
28
|
defaults:
|
|
29
29
|
run:
|
|
30
30
|
shell: bash
|
|
31
31
|
steps:
|
|
32
|
-
{{>
|
|
32
|
+
{{> stepNodeYml lockfile=false }}
|
|
33
33
|
- name: View in Registry
|
|
34
34
|
run: |
|
|
35
35
|
EXIT_CODE=0
|
|
@@ -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}}
|
|
@@ -7,7 +7,7 @@ on:
|
|
|
7
7
|
ref:
|
|
8
8
|
required: true
|
|
9
9
|
type: string
|
|
10
|
-
default: {{
|
|
10
|
+
default: {{ releaseBranch }}
|
|
11
11
|
workflow_call:
|
|
12
12
|
inputs:
|
|
13
13
|
ref:
|
|
@@ -19,19 +19,19 @@ on:
|
|
|
19
19
|
|
|
20
20
|
jobs:
|
|
21
21
|
lint-all:
|
|
22
|
-
{{>
|
|
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
|
-
{{>
|
|
28
|
-
{{>
|
|
27
|
+
{{> stepLintYml jobRunFlags=allFlags }}
|
|
28
|
+
{{> stepChecksYml jobCheck=true }}
|
|
29
29
|
|
|
30
30
|
test-all:
|
|
31
|
-
{{>
|
|
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
|
-
{{>
|
|
37
|
-
{{>
|
|
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 }}
|
|
@@ -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',
|