@npmcli/template-oss 4.22.0 → 4.23.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/bin/apply.js +2 -5
- package/bin/check.js +2 -4
- package/bin/release-manager.js +1 -1
- package/bin/release-please.js +22 -18
- package/lib/apply/apply-files.js +14 -19
- package/lib/apply/apply-version.js +1 -5
- package/lib/apply/index.js +1 -4
- package/lib/check/check-apply.js +38 -38
- package/lib/check/check-changelog.js +1 -4
- package/lib/check/check-engines.js +5 -6
- package/lib/check/check-gitignore.js +14 -14
- package/lib/check/check-required.js +13 -15
- package/lib/check/check-unwanted.js +2 -3
- package/lib/check/index.js +9 -8
- package/lib/config.js +86 -35
- package/lib/content/SECURITY-md.hbs +1 -1
- package/lib/content/_job-release-integration-yml.hbs +2 -0
- package/lib/content/action-create-check-yml.hbs +1 -1
- package/lib/content/action-install-latest-npm-yml.hbs +1 -1
- package/lib/content/ci-release-yml.hbs +2 -2
- package/lib/content/eslintrc-js.hbs +4 -5
- package/lib/content/gitignore.hbs +0 -3
- package/lib/content/index.js +33 -32
- package/lib/content/package-json.hbs +12 -2
- package/lib/content/post-dependabot-yml.hbs +2 -3
- package/lib/content/prettier-js.hbs +6 -0
- package/lib/content/prettierignore.hbs +3 -0
- package/lib/index.js +3 -3
- package/lib/release/changelog.js +28 -31
- package/lib/release/node-workspace-format.js +12 -12
- package/lib/release/release-manager.js +61 -76
- package/lib/release/release-please.js +50 -58
- package/lib/release/util.js +11 -8
- package/lib/util/ci-versions.js +3 -3
- package/lib/util/dependabot.js +2 -2
- package/lib/util/files.js +25 -22
- package/lib/util/git.js +7 -4
- package/lib/util/gitignore.js +13 -11
- package/lib/util/has-package.js +7 -12
- package/lib/util/import-or-require.js +1 -1
- package/lib/util/json-diff.js +22 -21
- package/lib/util/merge.js +19 -16
- package/lib/util/output.js +8 -5
- package/lib/util/parser.js +77 -70
- package/lib/util/path.js +4 -4
- package/lib/util/template.js +11 -10
- package/package.json +12 -7
|
@@ -21,17 +21,7 @@ class ReleaseManager {
|
|
|
21
21
|
|
|
22
22
|
#info
|
|
23
23
|
|
|
24
|
-
constructor ({
|
|
25
|
-
token,
|
|
26
|
-
repo,
|
|
27
|
-
cwd = process.cwd(),
|
|
28
|
-
pr,
|
|
29
|
-
backport,
|
|
30
|
-
defaultTag,
|
|
31
|
-
lockfile,
|
|
32
|
-
publish,
|
|
33
|
-
silent,
|
|
34
|
-
}) {
|
|
24
|
+
constructor({ token, repo, cwd = process.cwd(), pr, backport, defaultTag, lockfile, publish, silent }) {
|
|
35
25
|
assert(token, 'GITHUB_TOKEN is required')
|
|
36
26
|
assert(repo, 'GITHUB_REPOSITORY is required')
|
|
37
27
|
assert(cwd, 'cwd is required')
|
|
@@ -51,12 +41,12 @@ class ReleaseManager {
|
|
|
51
41
|
this.#info = silent ? noop : core.info
|
|
52
42
|
}
|
|
53
43
|
|
|
54
|
-
static async run
|
|
44
|
+
static async run(options) {
|
|
55
45
|
const manager = new ReleaseManager(options)
|
|
56
46
|
return manager.run()
|
|
57
47
|
}
|
|
58
48
|
|
|
59
|
-
async run
|
|
49
|
+
async run() {
|
|
60
50
|
const { data: pullRequest } = await this.#octokit.rest.pulls.get({
|
|
61
51
|
owner: this.#owner,
|
|
62
52
|
repo: this.#repo,
|
|
@@ -84,51 +74,55 @@ class ReleaseManager {
|
|
|
84
74
|
return `### Release Checklist for ${release.tag}\n\n${checklist}`
|
|
85
75
|
}
|
|
86
76
|
|
|
87
|
-
async #getPrReleases
|
|
77
|
+
async #getPrReleases({ pullRequest }) {
|
|
88
78
|
return /<details><summary>.*<\/summary>/.test(pullRequest.body)
|
|
89
79
|
? await this.#getPrMonoRepoReleases({ pullRequest })
|
|
90
80
|
: [this.#getPrRootRelease({ pullRequest }), []]
|
|
91
81
|
}
|
|
92
82
|
|
|
93
|
-
async #getPrMonoRepoReleases
|
|
83
|
+
async #getPrMonoRepoReleases({ pullRequest }) {
|
|
94
84
|
const releases = pullRequest.body.match(/<details><summary>.*<\/summary>/g)
|
|
95
85
|
this.#info(`Found ${releases.length} releases`)
|
|
96
86
|
|
|
97
|
-
const workspacesComponents = [
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
87
|
+
const workspacesComponents = [
|
|
88
|
+
...(await mapWorkspaces({
|
|
89
|
+
cwd: this.#cwd,
|
|
90
|
+
pkg: require(join(this.#cwd, 'package.json')),
|
|
91
|
+
})),
|
|
92
|
+
].reduce((acc, [k]) => {
|
|
93
|
+
const wsComponentName = k.startsWith('@') ? k.split('/')[1] : k
|
|
94
|
+
acc[wsComponentName] = k
|
|
95
|
+
return acc
|
|
96
|
+
}, {})
|
|
106
97
|
|
|
107
98
|
const MONO_VERSIONS = /<details><summary>(?:(.*?):\s)?(.*?)<\/summary>/
|
|
108
99
|
|
|
109
|
-
return releases.reduce(
|
|
110
|
-
|
|
100
|
+
return releases.reduce(
|
|
101
|
+
(acc, r) => {
|
|
102
|
+
const [, name, version] = r.match(MONO_VERSIONS)
|
|
111
103
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
104
|
+
const release = this.#getPrReleaseInfo({
|
|
105
|
+
pullRequest,
|
|
106
|
+
name,
|
|
107
|
+
version,
|
|
108
|
+
workspaces: workspacesComponents,
|
|
109
|
+
})
|
|
118
110
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
111
|
+
if (release.isRoot) {
|
|
112
|
+
this.#info(`Found root: ${JSON.stringify(release)}`)
|
|
113
|
+
acc[0] = release
|
|
114
|
+
} else {
|
|
115
|
+
this.#info(`Found workspace: ${JSON.stringify(release)}`)
|
|
116
|
+
acc[1].push(release)
|
|
117
|
+
}
|
|
126
118
|
|
|
127
|
-
|
|
128
|
-
|
|
119
|
+
return acc
|
|
120
|
+
},
|
|
121
|
+
[null, []],
|
|
122
|
+
)
|
|
129
123
|
}
|
|
130
124
|
|
|
131
|
-
#getPrRootRelease
|
|
125
|
+
#getPrRootRelease({ pullRequest }) {
|
|
132
126
|
this.#info('Found no monorepo, checking for single root version')
|
|
133
127
|
|
|
134
128
|
const match = pullRequest.body.match(/\n##\s\[(.*?)\]/)
|
|
@@ -140,7 +134,7 @@ class ReleaseManager {
|
|
|
140
134
|
return this.#getPrReleaseInfo({ pullRequest, version })
|
|
141
135
|
}
|
|
142
136
|
|
|
143
|
-
#getPrReleaseInfo
|
|
137
|
+
#getPrReleaseInfo({ pullRequest, workspaces = {}, name = null, version: rawVersion }) {
|
|
144
138
|
const version = semver.parse(rawVersion)
|
|
145
139
|
const prerelease = !!version.prerelease.length
|
|
146
140
|
const tag = `${name ? `${name}-` : ''}v${rawVersion}`
|
|
@@ -156,51 +150,47 @@ class ReleaseManager {
|
|
|
156
150
|
version: rawVersion,
|
|
157
151
|
major: version.major,
|
|
158
152
|
url: `https://github.com/${pullRequest.base.repo.full_name}/releases/tag/${tag}`,
|
|
159
|
-
flags: [
|
|
160
|
-
workspaces[name] ? `-w ${workspaces[name]}` : null,
|
|
161
|
-
`--tag=${publishTag}`,
|
|
162
|
-
].filter(Boolean).join(' '),
|
|
153
|
+
flags: [workspaces[name] ? `-w ${workspaces[name]}` : null, `--tag=${publishTag}`].filter(Boolean).join(' '),
|
|
163
154
|
}
|
|
164
155
|
}
|
|
165
156
|
|
|
166
|
-
async #getReleaseProcess
|
|
157
|
+
async #getReleaseProcess({ release, workspaces }) {
|
|
167
158
|
const RELEASE_LIST_ITEM = /^\d+\.\s/gm
|
|
168
159
|
|
|
169
160
|
this.#info(`Fetching release process from repo wiki: ${this.#owner}/${this.#repo}`)
|
|
170
161
|
|
|
171
162
|
const releaseProcess = await fetch(
|
|
172
|
-
`https://raw.githubusercontent.com/wiki/${this.#owner}/${this.#repo}/Release-Process.md
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
})
|
|
163
|
+
`https://raw.githubusercontent.com/wiki/${this.#owner}/${this.#repo}/Release-Process.md`,
|
|
164
|
+
).then(r => {
|
|
165
|
+
// If the url fails with anything but a 404 we want the process to blow
|
|
166
|
+
// up because that means something is very wrong. This is a rare edge
|
|
167
|
+
// case that isn't worth testing.
|
|
168
|
+
/* istanbul ignore else */
|
|
169
|
+
if (r.statusCode === 200) {
|
|
170
|
+
this.#info('Found release process from wiki')
|
|
171
|
+
return r.body.text()
|
|
172
|
+
} else if (r.statusCode === 404) {
|
|
173
|
+
this.#info('No release process found in wiki, falling back to default process')
|
|
174
|
+
return this.#getReleaseSteps()
|
|
175
|
+
} else {
|
|
176
|
+
throw new Error(`Release process fetch failed with status: ${r.statusCode}`)
|
|
177
|
+
}
|
|
178
|
+
})
|
|
189
179
|
|
|
190
180
|
// XXX: the release steps need to always be the last thing in the doc for this to work
|
|
191
181
|
const releaseLines = releaseProcess.split('\n')
|
|
192
|
-
const releaseStartLine = releaseLines.reduce((acc, l, i) => l.match(/^#+\s/) ? i : acc, 0)
|
|
182
|
+
const releaseStartLine = releaseLines.reduce((acc, l, i) => (l.match(/^#+\s/) ? i : acc), 0)
|
|
193
183
|
const section = releaseLines.slice(releaseStartLine).join('\n')
|
|
194
184
|
|
|
195
185
|
return section
|
|
196
186
|
.split({
|
|
197
|
-
[Symbol.split]:
|
|
187
|
+
[Symbol.split]: str => {
|
|
198
188
|
const [, ...matches] = str.split(RELEASE_LIST_ITEM)
|
|
199
189
|
this.#info(`Found ${matches.length} release items`)
|
|
200
|
-
return matches.map(
|
|
190
|
+
return matches.map(m => `- [ ] <STEP_INDEX>. ${m}`.trim())
|
|
201
191
|
},
|
|
202
192
|
})
|
|
203
|
-
.filter(
|
|
193
|
+
.filter(item => {
|
|
204
194
|
if (release.prerelease && item.includes('> NOT FOR PRERELEASE')) {
|
|
205
195
|
return false
|
|
206
196
|
}
|
|
@@ -214,7 +204,7 @@ class ReleaseManager {
|
|
|
214
204
|
.map((item, index) => item.replace('<STEP_INDEX>', index + 1))
|
|
215
205
|
}
|
|
216
206
|
|
|
217
|
-
#getReleaseSteps
|
|
207
|
+
#getReleaseSteps() {
|
|
218
208
|
const R = `-R ${this.#owner}/${this.#repo}`
|
|
219
209
|
|
|
220
210
|
const manualSteps = `
|
|
@@ -275,12 +265,7 @@ class ReleaseManager {
|
|
|
275
265
|
`
|
|
276
266
|
/* eslint-enable max-len */
|
|
277
267
|
|
|
278
|
-
return [
|
|
279
|
-
this.#publish ? autoSteps : manualSteps,
|
|
280
|
-
alwaysSteps,
|
|
281
|
-
]
|
|
282
|
-
.map(v => dedent(v))
|
|
283
|
-
.join('\n\n')
|
|
268
|
+
return [this.#publish ? autoSteps : manualSteps, alwaysSteps].map(v => dedent(v)).join('\n\n')
|
|
284
269
|
}
|
|
285
270
|
}
|
|
286
271
|
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
const RP = require('release-please')
|
|
2
|
-
const {
|
|
3
|
-
|
|
4
|
-
} = require('release-please/build/src/versioning-strategies/default.js')
|
|
5
|
-
const {
|
|
6
|
-
PrereleaseVersioningStrategy,
|
|
7
|
-
} = require('release-please/build/src/versioning-strategies/prerelease.js')
|
|
2
|
+
const { DefaultVersioningStrategy } = require('release-please/build/src/versioning-strategies/default.js')
|
|
3
|
+
const { PrereleaseVersioningStrategy } = require('release-please/build/src/versioning-strategies/prerelease.js')
|
|
8
4
|
const { ROOT_PROJECT_PATH } = require('release-please/build/src/manifest.js')
|
|
9
5
|
const { CheckpointLogger, logger } = require('release-please/build/src/util/logger.js')
|
|
10
6
|
const assert = require('assert')
|
|
@@ -31,16 +27,7 @@ class ReleasePlease {
|
|
|
31
27
|
#octokit
|
|
32
28
|
#manifest
|
|
33
29
|
|
|
34
|
-
constructor
|
|
35
|
-
token,
|
|
36
|
-
repo,
|
|
37
|
-
branch,
|
|
38
|
-
backport,
|
|
39
|
-
defaultTag,
|
|
40
|
-
overrides,
|
|
41
|
-
silent,
|
|
42
|
-
trace,
|
|
43
|
-
}) {
|
|
30
|
+
constructor({ token, repo, branch, backport, defaultTag, overrides, silent, trace }) {
|
|
44
31
|
assert(token, 'token is required')
|
|
45
32
|
assert(repo, 'repo is required')
|
|
46
33
|
assert(branch, 'branch is required')
|
|
@@ -57,28 +44,33 @@ class ReleasePlease {
|
|
|
57
44
|
this.#trace = trace
|
|
58
45
|
}
|
|
59
46
|
|
|
60
|
-
static async run
|
|
47
|
+
static async run(options) {
|
|
61
48
|
const releasePlease = new ReleasePlease(options)
|
|
62
49
|
await releasePlease.init()
|
|
63
50
|
return releasePlease.run()
|
|
64
51
|
}
|
|
65
52
|
|
|
66
|
-
async init
|
|
67
|
-
RP.registerChangelogNotes('default', ({ github, ...o }) =>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
RP.registerPlugin(
|
|
72
|
-
|
|
53
|
+
async init() {
|
|
54
|
+
RP.registerChangelogNotes('default', ({ github, ...o }) => new ChangelogNotes(github, o))
|
|
55
|
+
RP.registerVersioningStrategy('default', o =>
|
|
56
|
+
o.prerelease ? new PrereleaseVersioningStrategy(o) : new DefaultVersioningStrategy(o),
|
|
57
|
+
)
|
|
58
|
+
RP.registerPlugin(
|
|
59
|
+
'node-workspace-format',
|
|
60
|
+
({ github, targetBranch, repositoryConfig, ...o }) =>
|
|
61
|
+
new NodeWorkspaceFormat(github, targetBranch, repositoryConfig, o),
|
|
62
|
+
)
|
|
73
63
|
|
|
74
64
|
if (this.#silent) {
|
|
75
65
|
this.#info = noop
|
|
76
|
-
RP.setLogger(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
RP.setLogger(
|
|
67
|
+
Object.entries(logger).reduce((acc, [k, v]) => {
|
|
68
|
+
if (typeof v === 'function') {
|
|
69
|
+
acc[k] = noop
|
|
70
|
+
}
|
|
71
|
+
return acc
|
|
72
|
+
}, {}),
|
|
73
|
+
)
|
|
82
74
|
} else {
|
|
83
75
|
this.#info = core.info
|
|
84
76
|
RP.setLogger(new CheckpointLogger(true, !!this.#trace))
|
|
@@ -90,16 +82,10 @@ class ReleasePlease {
|
|
|
90
82
|
token: this.#token,
|
|
91
83
|
})
|
|
92
84
|
this.#octokit = this.#github.octokit
|
|
93
|
-
this.#manifest = await RP.Manifest.fromManifest(
|
|
94
|
-
this.#github,
|
|
95
|
-
this.#branch,
|
|
96
|
-
undefined,
|
|
97
|
-
undefined,
|
|
98
|
-
this.#overrides
|
|
99
|
-
)
|
|
85
|
+
this.#manifest = await RP.Manifest.fromManifest(this.#github, this.#branch, undefined, undefined, this.#overrides)
|
|
100
86
|
}
|
|
101
87
|
|
|
102
|
-
async run
|
|
88
|
+
async run() {
|
|
103
89
|
const rootPr = await this.#getRootPullRequest()
|
|
104
90
|
const releases = await this.#getReleases()
|
|
105
91
|
|
|
@@ -108,11 +94,13 @@ class ReleasePlease {
|
|
|
108
94
|
|
|
109
95
|
// release please does not guarantee that the release PR will have the latest sha,
|
|
110
96
|
// but we always need it so we can attach the relevant checks to the sha.
|
|
111
|
-
rootPr.sha = await this.#octokit
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
97
|
+
rootPr.sha = await this.#octokit
|
|
98
|
+
.paginate(this.#octokit.rest.pulls.listCommits, {
|
|
99
|
+
owner: this.#owner,
|
|
100
|
+
repo: this.#repo,
|
|
101
|
+
pull_number: rootPr.number,
|
|
102
|
+
})
|
|
103
|
+
.then(r => r[r.length - 1].sha)
|
|
116
104
|
}
|
|
117
105
|
|
|
118
106
|
if (releases) {
|
|
@@ -126,19 +114,23 @@ class ReleasePlease {
|
|
|
126
114
|
defaultTag: this.#defaultTag,
|
|
127
115
|
})
|
|
128
116
|
|
|
129
|
-
release.prNumber = await this.#octokit.rest.repos
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
117
|
+
release.prNumber = await this.#octokit.rest.repos
|
|
118
|
+
.listPullRequestsAssociatedWithCommit({
|
|
119
|
+
owner: this.#owner,
|
|
120
|
+
repo: this.#repo,
|
|
121
|
+
commit_sha: release.sha,
|
|
122
|
+
per_page: 1,
|
|
123
|
+
})
|
|
124
|
+
.then(r => r.data[0]?.number)
|
|
125
|
+
|
|
126
|
+
release.pkgName = await this.#octokit.rest.repos
|
|
127
|
+
.getContent({
|
|
128
|
+
owner: this.#owner,
|
|
129
|
+
repo: this.#repo,
|
|
130
|
+
ref: this.#branch,
|
|
131
|
+
path: `${release.path === '.' ? '' : release.path}/package.json`,
|
|
132
|
+
})
|
|
133
|
+
.then(r => JSON.parse(Buffer.from(r.data.content, r.data.encoding)).name)
|
|
142
134
|
}
|
|
143
135
|
}
|
|
144
136
|
|
|
@@ -148,14 +140,14 @@ class ReleasePlease {
|
|
|
148
140
|
}
|
|
149
141
|
}
|
|
150
142
|
|
|
151
|
-
async #getRootPullRequest
|
|
143
|
+
async #getRootPullRequest() {
|
|
152
144
|
// We only ever get a single pull request with our current release-please settings
|
|
153
145
|
// Update this if we start creating individual PRs per workspace release
|
|
154
146
|
const pullRequests = await this.#manifest.createPullRequests()
|
|
155
147
|
return pullRequests.filter(Boolean)[0] ?? null
|
|
156
148
|
}
|
|
157
149
|
|
|
158
|
-
async #getReleases
|
|
150
|
+
async #getReleases() {
|
|
159
151
|
// if we have a root release, always put it as the first item in the array
|
|
160
152
|
const rawReleases = await this.#manifest.createReleases().then(r => r.filter(Boolean))
|
|
161
153
|
let rootRelease = null
|
package/lib/release/util.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const semver = require('semver')
|
|
2
2
|
|
|
3
3
|
const SPEC = new RegExp(`([^\\s]+@${semver.src[semver.tokens.FULLPLAIN]})`, 'g')
|
|
4
|
-
const code =
|
|
5
|
-
const wrapSpecs =
|
|
6
|
-
const block =
|
|
4
|
+
const code = c => `\`${c}\``
|
|
5
|
+
const wrapSpecs = str => str.replace(SPEC, code('$1'))
|
|
6
|
+
const block = lang => `\`\`\`${lang ? `${lang}` : ''}`
|
|
7
7
|
const link = (text, url) => `[${text}](${url})`
|
|
8
|
-
const list =
|
|
8
|
+
const list = text => `* ${text}`
|
|
9
9
|
const formatDate = (date = new Date()) => {
|
|
10
10
|
const year = date.getFullYear()
|
|
11
11
|
const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
|
@@ -17,12 +17,15 @@ const getPublishTag = (v, { backport, defaultTag }) => {
|
|
|
17
17
|
const version = semver.parse(v)
|
|
18
18
|
return version.prerelease.length
|
|
19
19
|
? `prerelease-${version.major}`
|
|
20
|
-
: backport
|
|
21
|
-
|
|
20
|
+
: backport
|
|
21
|
+
? `latest-${backport}`
|
|
22
|
+
: defaultTag.replace(/{{\s*major\s*}}/, version.major)
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
const makeGitHubUrl =
|
|
25
|
-
(
|
|
25
|
+
const makeGitHubUrl =
|
|
26
|
+
(owner, repo) =>
|
|
27
|
+
(...p) =>
|
|
28
|
+
`https://github.com/${owner}/${repo}/${p.join('/')}`
|
|
26
29
|
|
|
27
30
|
const noop = () => {}
|
|
28
31
|
|
package/lib/util/ci-versions.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
const { uniq, range, isPlainObject } = require('lodash')
|
|
2
2
|
const semver = require('semver')
|
|
3
3
|
|
|
4
|
-
const parseCiVersions =
|
|
4
|
+
const parseCiVersions = ciVersions => {
|
|
5
5
|
if (Array.isArray(ciVersions)) {
|
|
6
|
-
return Object.fromEntries(ciVersions.map(
|
|
6
|
+
return Object.fromEntries(ciVersions.map(v => [v, true]))
|
|
7
7
|
}
|
|
8
8
|
if (isPlainObject(ciVersions)) {
|
|
9
9
|
return ciVersions
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const getLowerBounds =
|
|
13
|
+
const getLowerBounds = sRange => {
|
|
14
14
|
return new semver.Range(sRange).set.map(c => c[0])
|
|
15
15
|
}
|
|
16
16
|
|
package/lib/util/dependabot.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { name: NAME } = require('../../package.json')
|
|
2
2
|
const { minimatch } = require('minimatch')
|
|
3
3
|
|
|
4
|
-
const parseDependabotConfig =
|
|
4
|
+
const parseDependabotConfig = v => (typeof v === 'string' ? { strategy: v } : (v ?? {}))
|
|
5
5
|
|
|
6
6
|
module.exports = (config, defaultConfig, branches) => {
|
|
7
7
|
const { dependabot } = config
|
|
@@ -12,7 +12,7 @@ module.exports = (config, defaultConfig, branches) => {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
return branches
|
|
15
|
-
.filter(
|
|
15
|
+
.filter(b => dependabot[b] !== false)
|
|
16
16
|
.map(branch => {
|
|
17
17
|
const isReleaseBranch = minimatch(branch, config.releaseBranch)
|
|
18
18
|
return {
|
package/lib/util/files.js
CHANGED
|
@@ -12,21 +12,17 @@ const FILE_KEYS = ['rootRepo', 'rootModule', 'workspaceRepo', 'workspaceModule']
|
|
|
12
12
|
|
|
13
13
|
const globify = pattern => pattern.split('\\').join('/')
|
|
14
14
|
|
|
15
|
-
const deepMapKeys = (obj, fn) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const deepMapKeys = (obj, fn) =>
|
|
16
|
+
Object.entries(obj).reduce((acc, [key, value]) => {
|
|
17
|
+
acc[fn(key)] = isPlainObject(value) ? deepMapKeys(value, fn) : value
|
|
18
|
+
return acc
|
|
19
|
+
}, {})
|
|
19
20
|
|
|
20
21
|
const mergeFiles = mergeWithCustomizers((value, srcValue, key, target, source, stack) => {
|
|
21
22
|
// This will merge all files except if the src file has overwrite:false. Then
|
|
22
23
|
// the files will be turned into an array so they can be applied on top of
|
|
23
24
|
// each other in the parser.
|
|
24
|
-
if (
|
|
25
|
-
stack[0] === ADD_KEY &&
|
|
26
|
-
FILE_KEYS.includes(stack[1]) &&
|
|
27
|
-
value?.file &&
|
|
28
|
-
srcValue?.overwrite === false
|
|
29
|
-
) {
|
|
25
|
+
if (stack[0] === ADD_KEY && FILE_KEYS.includes(stack[1]) && value?.file && srcValue?.overwrite === false) {
|
|
30
26
|
return [value, omit(srcValue, 'overwrite')]
|
|
31
27
|
}
|
|
32
28
|
}, customizers.overwriteArrays)
|
|
@@ -47,10 +43,14 @@ const fileEntries = (dir, files, options) => {
|
|
|
47
43
|
// applied or diffed against the target. This is how overwrite:false
|
|
48
44
|
// works and they are merged.
|
|
49
45
|
const source = Array.isArray(value)
|
|
50
|
-
? value.reduce(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
? value.reduce(
|
|
47
|
+
(acc, { file, ...rest }) => {
|
|
48
|
+
acc.file.push(file)
|
|
49
|
+
return Object.assign(acc, rest)
|
|
50
|
+
},
|
|
51
|
+
{ file: [] },
|
|
52
|
+
)
|
|
53
|
+
: value
|
|
54
54
|
|
|
55
55
|
results.push([target, source])
|
|
56
56
|
}
|
|
@@ -110,12 +110,12 @@ const parseEach = async (dir, files, options, parseOptions, fn) => {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
const parseConfig = (files, dir, overrides, templateSettings) => {
|
|
113
|
-
const normalizeFiles =
|
|
114
|
-
v = deepMapKeys(v,
|
|
113
|
+
const normalizeFiles = v => {
|
|
114
|
+
v = deepMapKeys(v, s => template(s, templateSettings))
|
|
115
115
|
return deepMapValues(v, (value, key) => {
|
|
116
116
|
if (key === RM_KEY && Array.isArray(value)) {
|
|
117
117
|
return value.reduce((acc, k) => {
|
|
118
|
-
|
|
118
|
+
// template files nows since they need to be normalized before merging
|
|
119
119
|
acc[template(k, templateSettings)] = true
|
|
120
120
|
return acc
|
|
121
121
|
}, {})
|
|
@@ -132,15 +132,18 @@ const parseConfig = (files, dir, overrides, templateSettings) => {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
const merged = mergeFiles(normalizeFiles(files), normalizeFiles(overrides))
|
|
135
|
-
const withDefaults = defaultsDeep(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
const withDefaults = defaultsDeep(
|
|
136
|
+
merged,
|
|
137
|
+
FILE_KEYS.reduce((acc, k) => {
|
|
138
|
+
acc[k] = { [ADD_KEY]: {}, [RM_KEY]: {} }
|
|
139
|
+
return acc
|
|
140
|
+
}, {}),
|
|
141
|
+
)
|
|
139
142
|
|
|
140
143
|
return withDefaults
|
|
141
144
|
}
|
|
142
145
|
|
|
143
|
-
const getAddedFiles =
|
|
146
|
+
const getAddedFiles = files => (files ? Object.keys(files[ADD_KEY] || {}) : [])
|
|
144
147
|
|
|
145
148
|
module.exports = {
|
|
146
149
|
rmEach,
|
package/lib/util/git.js
CHANGED
|
@@ -5,7 +5,7 @@ const { minimatch } = require('minimatch')
|
|
|
5
5
|
const cache = new Map()
|
|
6
6
|
|
|
7
7
|
const tryGit = async (path, ...args) => {
|
|
8
|
-
if (!await git.is({ cwd: path })) {
|
|
8
|
+
if (!(await git.is({ cwd: path }))) {
|
|
9
9
|
throw new Error('no git')
|
|
10
10
|
}
|
|
11
11
|
const key = [path, ...args].join(',')
|
|
@@ -31,7 +31,7 @@ const getRemoteUrl = async (path, remote) => {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const getUrl = async
|
|
34
|
+
const getUrl = async path => {
|
|
35
35
|
return (await getRemoteUrl(path, 'upstream')) ?? (await getRemoteUrl(path, 'origin'))
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -41,7 +41,10 @@ const getBranches = async (path, branchPatterns) => {
|
|
|
41
41
|
|
|
42
42
|
try {
|
|
43
43
|
const res = await tryGit(path, 'ls-remote', '--heads', 'origin').then(r => r.split('\n'))
|
|
44
|
-
const remotes = res
|
|
44
|
+
const remotes = res
|
|
45
|
+
.map(h => h.match(/refs\/heads\/(.*)$/))
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
.map(h => h[1])
|
|
45
48
|
for (const branch of remotes) {
|
|
46
49
|
for (const pattern of branchPatterns) {
|
|
47
50
|
if (minimatch(branch, pattern)) {
|
|
@@ -61,7 +64,7 @@ const getBranches = async (path, branchPatterns) => {
|
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
const defaultBranch = async
|
|
67
|
+
const defaultBranch = async path => {
|
|
65
68
|
try {
|
|
66
69
|
const remotes = await tryGit(path, 'remote', 'show', 'origin')
|
|
67
70
|
return remotes.match(/HEAD branch: (.*)$/m)?.[1]
|
package/lib/util/gitignore.js
CHANGED
|
@@ -4,17 +4,19 @@ const localeCompare = require('@isaacs/string-locale-compare')('en')
|
|
|
4
4
|
|
|
5
5
|
const sortGitPaths = (a, b) => localeCompare(a.replace(/^!/g, ''), b.replace(/^!/g, ''))
|
|
6
6
|
|
|
7
|
-
const allowDir =
|
|
7
|
+
const allowDir = p => {
|
|
8
8
|
const parts = p.split(posix.sep)
|
|
9
|
-
return parts
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
return parts
|
|
10
|
+
.flatMap((part, index, list) => {
|
|
11
|
+
const prev = list.slice(0, index)
|
|
12
|
+
const isLast = index === list.length - 1
|
|
13
|
+
const ignorePart = ['', ...prev, part, ''].join(posix.sep)
|
|
14
|
+
return [`!${ignorePart}`, !isLast && `${ignorePart}*`]
|
|
15
|
+
})
|
|
16
|
+
.filter(Boolean)
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
const allowRootDir =
|
|
19
|
+
const allowRootDir = p => {
|
|
18
20
|
// This negates the first part of each path for the gitignore
|
|
19
21
|
// files. It should be used to allow directories where everything
|
|
20
22
|
// should be allowed inside such as .github/. It shouldn't be used on
|
|
@@ -26,9 +28,9 @@ const allowRootDir = (p) => {
|
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
const gitignore = {
|
|
29
|
-
allowDir:
|
|
30
|
-
allowRootDir:
|
|
31
|
-
sort:
|
|
31
|
+
allowDir: dirs => uniq(dirs.map(allowDir).flat()),
|
|
32
|
+
allowRootDir: dirs => dirs.map(allowRootDir).map(p => `!${posix.sep}${p}`),
|
|
33
|
+
sort: arr => uniq(arr.sort(sortGitPaths)),
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
module.exports = gitignore
|