@npmcli/template-oss 4.19.0 → 4.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -11
- package/bin/release-manager.js +23 -271
- package/bin/release-please.js +20 -55
- package/lib/config.js +98 -119
- package/lib/content/{_job-matrix.yml → _job-matrix-yml.hbs} +1 -1
- package/lib/content/_job-release-integration-yml.hbs +51 -0
- package/lib/content/{_job.yml → _job-yml.hbs} +1 -1
- package/lib/content/_step-node-yml.hbs +15 -0
- package/lib/content/_steps-setup-yml.hbs +15 -0
- package/lib/content/action-create-check-yml.hbs +50 -0
- package/lib/content/action-install-latest-npm-yml.hbs +55 -0
- package/lib/content/{audit.yml → audit-yml.hbs} +2 -2
- package/lib/content/ci-release-yml.hbs +49 -0
- 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 +55 -40
- package/lib/content/{pkg.json → package-json.hbs} +19 -5
- package/lib/content/{post-dependabot.yml → post-dependabot-yml.hbs} +1 -1
- package/lib/content/{pull-request.yml → pull-request-yml.hbs} +3 -5
- package/lib/content/release-integration-yml.hbs +24 -0
- package/lib/content/release-please-config-json.hbs +23 -0
- package/lib/content/release-yml.hbs +245 -0
- package/lib/content/tsconfig-json.hbs +17 -0
- package/lib/release/changelog.js +184 -0
- package/lib/release/node-workspace-format.js +107 -0
- package/lib/release/node-workspace.js +95 -0
- package/lib/release/release-manager.js +287 -0
- package/lib/release/release-please.js +180 -0
- package/lib/release/util.js +42 -0
- package/lib/util/files.js +29 -20
- package/lib/util/get-cmd-path.js +36 -0
- package/lib/util/git.js +6 -2
- package/lib/util/import-or-require.js +29 -0
- package/lib/util/parser.js +6 -1
- package/lib/util/path.js +13 -0
- package/lib/util/template.js +9 -6
- package/package.json +21 -13
- package/lib/content/_job-release-integration.yml +0 -59
- package/lib/content/_step-checks.yml +0 -54
- package/lib/content/_step-node.yml +0 -57
- package/lib/content/_steps-setup.yml +0 -6
- package/lib/content/ci-release.yml +0 -37
- package/lib/content/ci.yml +0 -13
- package/lib/content/release-please-config.json +0 -13
- package/lib/content/release.yml +0 -217
- package/lib/release-please/changelog.js +0 -92
- package/lib/release-please/github.js +0 -72
- package/lib/release-please/index.js +0 -262
- package/lib/release-please/node-workspace.js +0 -192
- package/lib/release-please/util.js +0 -14
- package/lib/release-please/version.js +0 -103
- /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-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-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
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
const RP = require('release-please')
|
|
2
|
+
const {
|
|
3
|
+
DefaultVersioningStrategy,
|
|
4
|
+
} = require('release-please/build/src/versioning-strategies/default.js')
|
|
5
|
+
const {
|
|
6
|
+
PrereleaseVersioningStrategy,
|
|
7
|
+
} = require('release-please/build/src/versioning-strategies/prerelease.js')
|
|
8
|
+
const { ROOT_PROJECT_PATH } = require('release-please/build/src/manifest.js')
|
|
9
|
+
const { CheckpointLogger, logger } = require('release-please/build/src/util/logger.js')
|
|
10
|
+
const assert = require('assert')
|
|
11
|
+
const core = require('@actions/core')
|
|
12
|
+
const omit = require('just-omit')
|
|
13
|
+
const ChangelogNotes = require('./changelog.js')
|
|
14
|
+
const NodeWorkspace = require('./node-workspace.js')
|
|
15
|
+
const NodeWorkspaceFormat = require('./node-workspace-format.js')
|
|
16
|
+
const { getPublishTag, noop } = require('./util.js')
|
|
17
|
+
|
|
18
|
+
class ReleasePlease {
|
|
19
|
+
#token
|
|
20
|
+
#owner
|
|
21
|
+
#repo
|
|
22
|
+
#branch
|
|
23
|
+
#backport
|
|
24
|
+
#defaultTag
|
|
25
|
+
#overrides
|
|
26
|
+
#silent
|
|
27
|
+
#trace
|
|
28
|
+
#info
|
|
29
|
+
|
|
30
|
+
#github
|
|
31
|
+
#octokit
|
|
32
|
+
#manifest
|
|
33
|
+
|
|
34
|
+
constructor ({
|
|
35
|
+
token,
|
|
36
|
+
repo,
|
|
37
|
+
branch,
|
|
38
|
+
backport,
|
|
39
|
+
defaultTag,
|
|
40
|
+
overrides,
|
|
41
|
+
silent,
|
|
42
|
+
trace,
|
|
43
|
+
}) {
|
|
44
|
+
assert(token, 'token is required')
|
|
45
|
+
assert(repo, 'repo is required')
|
|
46
|
+
assert(branch, 'branch is required')
|
|
47
|
+
assert(defaultTag, 'defaultTag is required')
|
|
48
|
+
|
|
49
|
+
this.#token = token
|
|
50
|
+
this.#owner = repo.split('/')[0]
|
|
51
|
+
this.#repo = repo.split('/')[1]
|
|
52
|
+
this.#branch = branch
|
|
53
|
+
this.#backport = backport
|
|
54
|
+
this.#defaultTag = defaultTag
|
|
55
|
+
this.#overrides = overrides
|
|
56
|
+
this.#silent = silent
|
|
57
|
+
this.#trace = trace
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static async run (options) {
|
|
61
|
+
const releasePlease = new ReleasePlease(options)
|
|
62
|
+
await releasePlease.init()
|
|
63
|
+
return releasePlease.run()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async init () {
|
|
67
|
+
RP.registerChangelogNotes('default', ({ github, ...o }) =>
|
|
68
|
+
new ChangelogNotes(github, o))
|
|
69
|
+
RP.registerVersioningStrategy('default', (o) =>
|
|
70
|
+
o.prerelease ? new PrereleaseVersioningStrategy(o) : new DefaultVersioningStrategy(o))
|
|
71
|
+
RP.registerPlugin('node-workspace', ({ github, targetBranch, repositoryConfig, ...o }) =>
|
|
72
|
+
new NodeWorkspace(github, targetBranch, repositoryConfig, o))
|
|
73
|
+
RP.registerPlugin('node-workspace-format', ({ github, targetBranch, repositoryConfig, ...o }) =>
|
|
74
|
+
new NodeWorkspaceFormat(github, targetBranch, repositoryConfig, o))
|
|
75
|
+
|
|
76
|
+
if (this.#silent) {
|
|
77
|
+
this.#info = noop
|
|
78
|
+
RP.setLogger(Object.entries(logger).reduce((acc, [k, v]) => {
|
|
79
|
+
if (typeof v === 'function') {
|
|
80
|
+
acc[k] = noop
|
|
81
|
+
}
|
|
82
|
+
return acc
|
|
83
|
+
}, {}))
|
|
84
|
+
} else {
|
|
85
|
+
this.#info = core.info
|
|
86
|
+
RP.setLogger(new CheckpointLogger(true, !!this.#trace))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.#github = await RP.GitHub.create({
|
|
90
|
+
owner: this.#owner,
|
|
91
|
+
repo: this.#repo,
|
|
92
|
+
token: this.#token,
|
|
93
|
+
})
|
|
94
|
+
this.#octokit = this.#github.octokit
|
|
95
|
+
this.#manifest = await RP.Manifest.fromManifest(
|
|
96
|
+
this.#github,
|
|
97
|
+
this.#branch,
|
|
98
|
+
undefined,
|
|
99
|
+
undefined,
|
|
100
|
+
this.#overrides
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async run () {
|
|
105
|
+
const rootPr = await this.#getRootPullRequest()
|
|
106
|
+
const releases = await this.#getReleases()
|
|
107
|
+
|
|
108
|
+
if (rootPr) {
|
|
109
|
+
this.#info(`root pr: ${JSON.stringify(omit(rootPr, 'body'))}`)
|
|
110
|
+
|
|
111
|
+
// release please does not guarantee that the release PR will have the latest sha,
|
|
112
|
+
// but we always need it so we can attach the relevant checks to the sha.
|
|
113
|
+
rootPr.sha = await this.#octokit.paginate(this.#octokit.rest.pulls.listCommits, {
|
|
114
|
+
owner: this.#owner,
|
|
115
|
+
repo: this.#repo,
|
|
116
|
+
pull_number: rootPr.number,
|
|
117
|
+
}).then(r => r[r.length - 1].sha)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (releases) {
|
|
121
|
+
this.#info(`found releases: ${releases.length}`)
|
|
122
|
+
|
|
123
|
+
for (const release of releases) {
|
|
124
|
+
this.#info(`release: ${JSON.stringify(omit(release, 'notes'))}`)
|
|
125
|
+
|
|
126
|
+
release.publishTag = getPublishTag(release.version, {
|
|
127
|
+
backport: this.#backport,
|
|
128
|
+
defaultTag: this.#defaultTag,
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
release.prNumber = await this.#octokit.rest.repos.listPullRequestsAssociatedWithCommit({
|
|
132
|
+
owner: this.#owner,
|
|
133
|
+
repo: this.#repo,
|
|
134
|
+
commit_sha: release.sha,
|
|
135
|
+
per_page: 1,
|
|
136
|
+
}).then(r => r.data[0]?.number)
|
|
137
|
+
|
|
138
|
+
release.pkgName = await this.#octokit.rest.repos.getContent({
|
|
139
|
+
owner: this.#owner,
|
|
140
|
+
repo: this.#repo,
|
|
141
|
+
ref: this.#branch,
|
|
142
|
+
path: `${release.path === '.' ? '' : release.path}/package.json`,
|
|
143
|
+
}).then(r => JSON.parse(Buffer.from(r.data.content, r.data.encoding)).name)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
pr: rootPr,
|
|
149
|
+
releases: releases,
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async #getRootPullRequest () {
|
|
154
|
+
// We only ever get a single pull request with our current release-please settings
|
|
155
|
+
// Update this if we start creating individual PRs per workspace release
|
|
156
|
+
const pullRequests = await this.#manifest.createPullRequests()
|
|
157
|
+
return pullRequests.filter(Boolean)[0] ?? null
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async #getReleases () {
|
|
161
|
+
// if we have a root release, always put it as the first item in the array
|
|
162
|
+
const rawReleases = await this.#manifest.createReleases().then(r => r.filter(Boolean))
|
|
163
|
+
let rootRelease = null
|
|
164
|
+
const workspaceReleases = []
|
|
165
|
+
|
|
166
|
+
for (const release of rawReleases) {
|
|
167
|
+
if (release.path === ROOT_PROJECT_PATH) {
|
|
168
|
+
assert(!rootRelease, 'Multiple root releases detected. This should never happen.')
|
|
169
|
+
rootRelease = release
|
|
170
|
+
} else {
|
|
171
|
+
workspaceReleases.push(release)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const releases = [rootRelease, ...workspaceReleases].filter(Boolean)
|
|
176
|
+
return releases.length ? releases : null
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
module.exports = ReleasePlease
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const semver = require('semver')
|
|
2
|
+
|
|
3
|
+
const SPEC = new RegExp(`([^\\s]+@${semver.src[semver.tokens.FULLPLAIN]})`, 'g')
|
|
4
|
+
const code = (c) => `\`${c}\``
|
|
5
|
+
const wrapSpecs = (str) => str.replace(SPEC, code('$1'))
|
|
6
|
+
const block = (lang) => `\`\`\`${lang ? `${lang}` : ''}`
|
|
7
|
+
const link = (text, url) => `[${text}](${url})`
|
|
8
|
+
const list = (text) => `* ${text}`
|
|
9
|
+
const formatDate = (date = new Date()) => {
|
|
10
|
+
const year = date.getFullYear()
|
|
11
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
|
12
|
+
const day = date.getDate().toString().padStart(2, '0')
|
|
13
|
+
return [year, month, day].join('-')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const getPublishTag = (v, { backport, defaultTag }) => {
|
|
17
|
+
const version = semver.parse(v)
|
|
18
|
+
return version.prerelease.length
|
|
19
|
+
? `prerelease-${version.major}`
|
|
20
|
+
: backport ? `latest-${backport}`
|
|
21
|
+
: defaultTag.replace(/{{\s*major\s*}}/, version.major)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const makeGitHubUrl = (owner, repo) =>
|
|
25
|
+
(...p) => `https://github.com/${owner}/${repo}/${p.join('/')}`
|
|
26
|
+
|
|
27
|
+
const noop = () => {}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
// we use this string a lot, its duplicated in the changelog sections but its hard
|
|
31
|
+
// to access from within release please so we keep it here also.
|
|
32
|
+
DEPS: 'deps',
|
|
33
|
+
wrapSpecs,
|
|
34
|
+
code,
|
|
35
|
+
block,
|
|
36
|
+
link,
|
|
37
|
+
list,
|
|
38
|
+
formatDate,
|
|
39
|
+
getPublishTag,
|
|
40
|
+
makeGitHubUrl,
|
|
41
|
+
noop,
|
|
42
|
+
}
|
package/lib/util/files.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { join } = require('path')
|
|
2
|
-
const { defaultsDeep, omit } = require('lodash')
|
|
2
|
+
const { defaultsDeep, omit, isPlainObject } = require('lodash')
|
|
3
3
|
const deepMapValues = require('just-deep-map-values')
|
|
4
4
|
const { glob } = require('glob')
|
|
5
5
|
const { mergeWithCustomizers, customizers } = require('./merge.js')
|
|
@@ -12,6 +12,11 @@ const FILE_KEYS = ['rootRepo', 'rootModule', 'workspaceRepo', 'workspaceModule']
|
|
|
12
12
|
|
|
13
13
|
const globify = pattern => pattern.split('\\').join('/')
|
|
14
14
|
|
|
15
|
+
const deepMapKeys = (obj, fn) => Object.entries(obj).reduce((acc, [key, value]) => {
|
|
16
|
+
acc[fn(key)] = isPlainObject(value) ? deepMapKeys(value, fn) : value
|
|
17
|
+
return acc
|
|
18
|
+
}, {})
|
|
19
|
+
|
|
15
20
|
const mergeFiles = mergeWithCustomizers((value, srcValue, key, target, source, stack) => {
|
|
16
21
|
// This will merge all files except if the src file has overwrite:false. Then
|
|
17
22
|
// the files will be turned into an array so they can be applied on top of
|
|
@@ -35,7 +40,7 @@ const fileEntries = (dir, files, options, { allowMultipleSources = true } = {})
|
|
|
35
40
|
continue
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
// target paths need to be
|
|
43
|
+
// target paths need to be joined with dir and templated
|
|
39
44
|
const target = join(dir, template(key, options))
|
|
40
45
|
|
|
41
46
|
if (Array.isArray(source)) {
|
|
@@ -66,7 +71,7 @@ const getParsers = (dir, files, options, parseOptions) => {
|
|
|
66
71
|
const clean = typeof shouldClean === 'function' ? shouldClean(options) : false
|
|
67
72
|
|
|
68
73
|
if (parser) {
|
|
69
|
-
|
|
74
|
+
// allow files to extend base parsers or create new ones
|
|
70
75
|
return new (parser(Parser.Parsers))(target, file, options, { clean })
|
|
71
76
|
}
|
|
72
77
|
|
|
@@ -105,23 +110,27 @@ const parseEach = async (dir, files, options, parseOptions, fn) => {
|
|
|
105
110
|
return res.filter(Boolean)
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
const parseConfig = (files, dir, overrides) => {
|
|
109
|
-
const normalizeFiles = (v) =>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return acc
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
113
|
+
const parseConfig = (files, dir, overrides, templateSettings) => {
|
|
114
|
+
const normalizeFiles = (v) => {
|
|
115
|
+
v = deepMapKeys(v, (s) => template(s, templateSettings))
|
|
116
|
+
return deepMapValues(v, (value, key) => {
|
|
117
|
+
if (key === RM_KEY && Array.isArray(value)) {
|
|
118
|
+
return value.reduce((acc, k) => {
|
|
119
|
+
// template files nows since they need to be normalized before merging
|
|
120
|
+
acc[template(k, templateSettings)] = true
|
|
121
|
+
return acc
|
|
122
|
+
}, {})
|
|
123
|
+
}
|
|
124
|
+
if (typeof value === 'string') {
|
|
125
|
+
const file = join(dir, value)
|
|
126
|
+
return key === 'file' ? file : { file }
|
|
127
|
+
}
|
|
128
|
+
if (value === true && FILE_KEYS.includes(key)) {
|
|
129
|
+
return {}
|
|
130
|
+
}
|
|
131
|
+
return value
|
|
132
|
+
})
|
|
133
|
+
}
|
|
125
134
|
|
|
126
135
|
const merged = mergeFiles(normalizeFiles(files), normalizeFiles(overrides))
|
|
127
136
|
const withDefaults = defaultsDeep(merged, FILE_KEYS.reduce((acc, k) => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const { join, relative } = require('path')
|
|
2
|
+
const { makePosix } = require('./path.js')
|
|
3
|
+
|
|
4
|
+
const getCmdPath = (key, { pkgConfig, rootConfig, isRoot, pkg, rootPkg }) => {
|
|
5
|
+
const result = (local, isRelative) => {
|
|
6
|
+
let root = local
|
|
7
|
+
const isLocal = local.startsWith('.') || local.startsWith('/')
|
|
8
|
+
|
|
9
|
+
if (isLocal) {
|
|
10
|
+
if (isRelative) {
|
|
11
|
+
// Make a path relative from a workspace to the root if we are in a workspace
|
|
12
|
+
local = makePosix(join(relative(pkg.path, rootPkg.path), local))
|
|
13
|
+
}
|
|
14
|
+
local = `node ${local}`
|
|
15
|
+
root = `node ${root}`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
isLocal,
|
|
20
|
+
local,
|
|
21
|
+
root,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (pkgConfig[key]) {
|
|
26
|
+
return result(pkgConfig[key])
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (rootConfig[key]) {
|
|
30
|
+
return result(rootConfig[key], !isRoot)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return result(key)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = getCmdPath
|
package/lib/util/git.js
CHANGED
|
@@ -19,9 +19,9 @@ const tryGit = async (path, ...args) => {
|
|
|
19
19
|
|
|
20
20
|
// parse a repo from a git origin into a format
|
|
21
21
|
// for a package.json#repository object
|
|
22
|
-
const
|
|
22
|
+
const getRemoteUrl = async (path, remote) => {
|
|
23
23
|
try {
|
|
24
|
-
const urlStr = await tryGit(path, 'remote', 'get-url',
|
|
24
|
+
const urlStr = await tryGit(path, 'remote', 'get-url', remote)
|
|
25
25
|
const { domain, user, project } = hgi.fromUrl(urlStr)
|
|
26
26
|
const url = new URL(`https://${domain}`)
|
|
27
27
|
url.pathname = `/${user}/${project}.git`
|
|
@@ -31,6 +31,10 @@ const getUrl = async (path) => {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
const getUrl = async (path) => {
|
|
35
|
+
return (await getRemoteUrl(path, 'upstream')) ?? (await getRemoteUrl(path, 'origin'))
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
const getBranches = async (path, branchPatterns) => {
|
|
35
39
|
let matchingBranches = new Set()
|
|
36
40
|
let matchingPatterns = new Set()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// This fixes weird behavior I was seeing where calls to require(path) would
|
|
2
|
+
// fail the first time and then fetch via dynamic import which is correct, but
|
|
3
|
+
// then subsequent requires for the same path would return an empty object. Not
|
|
4
|
+
// sure if a bug or I'm doing something wrong but since the require/imports here
|
|
5
|
+
// are short lived, it is safe to create our own cache and use that.
|
|
6
|
+
const { pathToFileURL } = require('url')
|
|
7
|
+
|
|
8
|
+
const importOrRequireCache = new Map()
|
|
9
|
+
|
|
10
|
+
const importOrRequire = async (path) => {
|
|
11
|
+
if (importOrRequireCache.has(path)) {
|
|
12
|
+
return importOrRequireCache.get(path)
|
|
13
|
+
}
|
|
14
|
+
let content = {}
|
|
15
|
+
try {
|
|
16
|
+
content = require(path)
|
|
17
|
+
} catch {
|
|
18
|
+
try {
|
|
19
|
+
content = await import(pathToFileURL(path)).then(r => r.default)
|
|
20
|
+
} catch {
|
|
21
|
+
// its ok if this fails since the content dir might only be to provide
|
|
22
|
+
// other files. the index.js is optional
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
importOrRequireCache.set(path, content)
|
|
26
|
+
return content
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = importOrRequire
|
package/lib/util/parser.js
CHANGED
|
@@ -173,7 +173,7 @@ class Gitignore extends Base {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
class Js extends Base {
|
|
176
|
-
static types = ['*.js']
|
|
176
|
+
static types = ['*.js', '*.cjs']
|
|
177
177
|
comment = (c) => `/* ${c} */`
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -306,6 +306,10 @@ class JsonMerge extends Json {
|
|
|
306
306
|
merge = (t, s) => merge(t, s)
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
class JsonMergeNoComment extends JsonMerge {
|
|
310
|
+
comment = null
|
|
311
|
+
}
|
|
312
|
+
|
|
309
313
|
class PackageJson extends JsonMerge {
|
|
310
314
|
static types = ['package.json']
|
|
311
315
|
|
|
@@ -346,6 +350,7 @@ const Parsers = {
|
|
|
346
350
|
YmlMerge,
|
|
347
351
|
Json,
|
|
348
352
|
JsonMerge,
|
|
353
|
+
JsonMergeNoComment,
|
|
349
354
|
PackageJson,
|
|
350
355
|
}
|
|
351
356
|
|
package/lib/util/path.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const { posix, win32 } = require('path')
|
|
2
|
+
|
|
3
|
+
const makePosix = (v) => v.split(win32.sep).join(posix.sep)
|
|
4
|
+
const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
|
|
5
|
+
const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
|
|
6
|
+
const posixGlob = (str) => `${posixDir(str)}**`
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
makePosix,
|
|
10
|
+
deglob,
|
|
11
|
+
posixDir,
|
|
12
|
+
posixGlob,
|
|
13
|
+
}
|
package/lib/util/template.js
CHANGED
|
@@ -31,7 +31,7 @@ const makePartials = (dir, isBase) => {
|
|
|
31
31
|
Handlebars.registerPartial(partials)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const setupHandlebars = (
|
|
34
|
+
const setupHandlebars = (dirs) => {
|
|
35
35
|
Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash)))
|
|
36
36
|
Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', '))
|
|
37
37
|
Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key]))
|
|
@@ -40,14 +40,17 @@ const setupHandlebars = (baseDir, ...otherDirs) => {
|
|
|
40
40
|
Handlebars.registerHelper('json', (c) => JSON.stringify(c))
|
|
41
41
|
Handlebars.registerHelper('del', () => JSON.stringify(DELETE))
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
makePartials(
|
|
43
|
+
if (Array.isArray(dirs)) {
|
|
44
|
+
const [baseDir, ...otherDirs] = dirs
|
|
45
|
+
makePartials(baseDir, true)
|
|
46
|
+
for (const dir of otherDirs) {
|
|
47
|
+
makePartials(dir)
|
|
48
|
+
}
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
51
|
|
|
49
|
-
const template = (str, { config, ...options }) => {
|
|
50
|
-
setupHandlebars(
|
|
52
|
+
const template = (str, { config = {}, ...options }) => {
|
|
53
|
+
setupHandlebars(config.__PARTIAL_DIRS__)
|
|
51
54
|
|
|
52
55
|
const t = Handlebars.compile(str, { strict: true })
|
|
53
56
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/template-oss",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.21.0",
|
|
4
4
|
"description": "templated files used in npm CLI team oss projects",
|
|
5
5
|
"main": "lib/content/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"template-oss-release-manager": "bin/release-manager.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"lint": "eslint \"**/*.js\"",
|
|
13
|
+
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
|
|
14
14
|
"lintfix": "npm run lint -- --fix",
|
|
15
15
|
"posttest": "npm run lint",
|
|
16
16
|
"snap": "tap",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"postlint": "template-oss-check",
|
|
20
20
|
"postinstall": "template-oss-apply",
|
|
21
21
|
"test-all": "npm run test -ws -iwr --if-present",
|
|
22
|
-
"lint-all": "npm run lint -ws -iwr --if-present"
|
|
22
|
+
"lint-all": "npm run lint -ws -iwr --if-present",
|
|
23
|
+
"test:record": "TAP_SNAPSHOT=1 NOCK_RECORD=1 tap"
|
|
23
24
|
},
|
|
24
25
|
"repository": {
|
|
25
26
|
"type": "git",
|
|
@@ -33,28 +34,31 @@
|
|
|
33
34
|
"license": "ISC",
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"@actions/core": "^1.9.1",
|
|
36
|
-
"@commitlint/cli": "^
|
|
37
|
-
"@commitlint/config-conventional": "^
|
|
37
|
+
"@commitlint/cli": "^18.2.0",
|
|
38
|
+
"@commitlint/config-conventional": "^18.1.0",
|
|
38
39
|
"@isaacs/string-locale-compare": "^1.1.0",
|
|
39
|
-
"@npmcli/arborist": "^
|
|
40
|
-
"@npmcli/git": "^
|
|
40
|
+
"@npmcli/arborist": "^7.2.1",
|
|
41
|
+
"@npmcli/git": "^5.0.3",
|
|
41
42
|
"@npmcli/map-workspaces": "^3.0.0",
|
|
42
|
-
"@npmcli/package-json": "^
|
|
43
|
+
"@npmcli/package-json": "^5.0.0",
|
|
43
44
|
"@octokit/rest": "^19.0.4",
|
|
45
|
+
"dedent": "^1.5.1",
|
|
44
46
|
"diff": "^5.0.0",
|
|
45
47
|
"glob": "^10.1.0",
|
|
46
48
|
"handlebars": "^4.7.7",
|
|
47
|
-
"hosted-git-info": "^
|
|
49
|
+
"hosted-git-info": "^7.0.1",
|
|
48
50
|
"ini": "^4.0.0",
|
|
49
51
|
"json-parse-even-better-errors": "^3.0.0",
|
|
50
52
|
"just-deep-map-values": "^1.1.1",
|
|
51
53
|
"just-diff": "^6.0.0",
|
|
54
|
+
"just-omit": "^2.2.0",
|
|
52
55
|
"lodash": "^4.17.21",
|
|
53
56
|
"minimatch": "^9.0.2",
|
|
54
|
-
"npm-package-arg": "^
|
|
57
|
+
"npm-package-arg": "^11.0.1",
|
|
55
58
|
"proc-log": "^3.0.0",
|
|
56
|
-
"release-please": "
|
|
59
|
+
"release-please": "16.3.1",
|
|
57
60
|
"semver": "^7.3.5",
|
|
61
|
+
"undici": "^5.27.2",
|
|
58
62
|
"yaml": "^2.1.1"
|
|
59
63
|
},
|
|
60
64
|
"files": [
|
|
@@ -64,6 +68,7 @@
|
|
|
64
68
|
"devDependencies": {
|
|
65
69
|
"@npmcli/eslint-config": "^4.0.0",
|
|
66
70
|
"@npmcli/template-oss": "file:./",
|
|
71
|
+
"nock": "^13.3.8",
|
|
67
72
|
"tap": "^16.0.0"
|
|
68
73
|
},
|
|
69
74
|
"tap": {
|
|
@@ -74,14 +79,17 @@
|
|
|
74
79
|
"--exclude",
|
|
75
80
|
"tap-snapshots/**"
|
|
76
81
|
],
|
|
77
|
-
"test-ignore": "^(workspace/test-workspace)/"
|
|
82
|
+
"test-ignore": "^(workspace/test-workspace)/",
|
|
83
|
+
"node-arg": [
|
|
84
|
+
"--no-experimental-fetch"
|
|
85
|
+
]
|
|
78
86
|
},
|
|
79
87
|
"templateOSS": {
|
|
80
88
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
81
89
|
"publish": true
|
|
82
90
|
},
|
|
83
91
|
"engines": {
|
|
84
|
-
"node": "^
|
|
92
|
+
"node": "^18.17.0 || >=20.5.0"
|
|
85
93
|
},
|
|
86
94
|
"workspaces": [
|
|
87
95
|
"workspace/test-workspace"
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
{{#if publish}}
|
|
2
|
-
runs-on: ubuntu-latest
|
|
3
|
-
defaults:
|
|
4
|
-
run:
|
|
5
|
-
shell: bash
|
|
6
|
-
permissions:
|
|
7
|
-
deployments: write
|
|
8
|
-
id-token: write
|
|
9
|
-
steps:
|
|
10
|
-
- name: Checkout
|
|
11
|
-
uses: actions/checkout@v3
|
|
12
|
-
with:
|
|
13
|
-
ref: $\{{ fromJSON(needs.release.outputs.release).tagName }}
|
|
14
|
-
- name: Setup Node
|
|
15
|
-
uses: actions/setup-node@v3
|
|
16
|
-
with:
|
|
17
|
-
node-version: 18.x
|
|
18
|
-
- name: Install npm@latest
|
|
19
|
-
run: |
|
|
20
|
-
npm i --prefer-online --no-fund --no-audit -g npm@latest
|
|
21
|
-
npm config set '//registry.npmjs.org/:_authToken'=\${PUBLISH_TOKEN}
|
|
22
|
-
- name: Publish
|
|
23
|
-
env:
|
|
24
|
-
PUBLISH_TOKEN: $\{{ secrets.PUBLISH_TOKEN }}
|
|
25
|
-
run: npm publish --provenance --tag={{ publishTag }}
|
|
26
|
-
{{else}}
|
|
27
|
-
runs-on: ubuntu-latest
|
|
28
|
-
defaults:
|
|
29
|
-
run:
|
|
30
|
-
shell: bash
|
|
31
|
-
steps:
|
|
32
|
-
{{> stepNode lockfile=false }}
|
|
33
|
-
- name: View in Registry
|
|
34
|
-
run: |
|
|
35
|
-
EXIT_CODE=0
|
|
36
|
-
|
|
37
|
-
function is_published {
|
|
38
|
-
if npm view "$@" --loglevel=error > /dev/null; then
|
|
39
|
-
echo 0
|
|
40
|
-
else
|
|
41
|
-
echo 1
|
|
42
|
-
fi
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
for release in $(echo '$\{{ needs.release.outputs.releases }}' | jq -r '.[] | @base64'); do
|
|
46
|
-
name=$(echo "$release" | base64 --decode | jq -r .pkgName)
|
|
47
|
-
version=$(echo "$release" | base64 --decode | jq -r .version)
|
|
48
|
-
spec="$name@$version"
|
|
49
|
-
status=$(is_published "$spec")
|
|
50
|
-
if [[ "$status" -eq 1 ]]; then
|
|
51
|
-
echo "$spec ERROR"
|
|
52
|
-
EXIT_CODE=$status
|
|
53
|
-
else
|
|
54
|
-
echo "$spec OK"
|
|
55
|
-
fi
|
|
56
|
-
done
|
|
57
|
-
|
|
58
|
-
exit $EXIT_CODE
|
|
59
|
-
{{/if}}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
{{#if jobCheck.sha}}
|
|
2
|
-
- name: Get Workflow Job
|
|
3
|
-
uses: actions/github-script@v6
|
|
4
|
-
if: {{ jobCheck.sha }}
|
|
5
|
-
id: check-output
|
|
6
|
-
env:
|
|
7
|
-
JOB_NAME: "{{#if jobName}}{{ jobName }}{{else}}{{ jobCheck.name }}{{/if}}"
|
|
8
|
-
MATRIX_NAME: "{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}"
|
|
9
|
-
with:
|
|
10
|
-
script: |
|
|
11
|
-
const { owner, repo } = context.repo
|
|
12
|
-
|
|
13
|
-
const { data } = await github.rest.actions.listJobsForWorkflowRun({
|
|
14
|
-
owner,
|
|
15
|
-
repo,
|
|
16
|
-
run_id: context.runId,
|
|
17
|
-
per_page: 100
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME
|
|
21
|
-
const job = data.jobs.find(j => j.name.endsWith(jobName))
|
|
22
|
-
const jobUrl = job?.html_url
|
|
23
|
-
|
|
24
|
-
const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/$\{{ {{ jobCheck.sha }} }}`
|
|
25
|
-
|
|
26
|
-
let summary = `This check is assosciated with ${shaUrl}\n\n`
|
|
27
|
-
|
|
28
|
-
if (jobUrl) {
|
|
29
|
-
summary += `For run logs, click here: ${jobUrl}`
|
|
30
|
-
} else {
|
|
31
|
-
summary += `Run logs could not be found for a job with name: "${jobName}"`
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return { summary }
|
|
35
|
-
{{/if}}
|
|
36
|
-
- name: {{#if jobCheck.sha}}Create{{else}}Conclude{{/if}} Check
|
|
37
|
-
uses: LouisBrunner/checks-action@v1.6.0
|
|
38
|
-
{{#if jobCheck.sha}}
|
|
39
|
-
id: check
|
|
40
|
-
if: {{ jobCheck.sha }}
|
|
41
|
-
{{else}}
|
|
42
|
-
if: {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}steps.check.outputs.check_id{{/if}} && always()
|
|
43
|
-
{{/if}}
|
|
44
|
-
with:
|
|
45
|
-
token: $\{{ secrets.GITHUB_TOKEN }}
|
|
46
|
-
{{#if jobCheck.sha}}
|
|
47
|
-
status: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}in_progress{{/if}}
|
|
48
|
-
name: {{#if jobCheck.name}}{{ jobCheck.name }}{{else}}{{ jobName }}{{/if}}{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}
|
|
49
|
-
sha: $\{{ {{ jobCheck.sha }} }}
|
|
50
|
-
output: $\{{ steps.check-output.outputs.result }}
|
|
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}} }}
|
|
54
|
-
{{/if}}
|