@npmcli/template-oss 4.2.0 → 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.
- package/bin/release-please.js +42 -28
- package/lib/config.js +44 -26
- package/lib/content/{_setup-job-matrix.yml → _job-matrix.yml} +12 -10
- package/lib/content/_job.yml +8 -0
- package/lib/content/{_setup-ci-on.yml → _on-ci.yml} +11 -13
- package/lib/content/_step-checks.yml +24 -0
- package/lib/content/_step-deps.yml +2 -0
- package/lib/content/_step-git.yml +12 -0
- package/lib/content/_step-lint.yml +4 -0
- package/lib/content/{_setup-node.yml → _step-node.yml} +10 -9
- package/lib/content/_step-test.yml +4 -0
- package/lib/content/_steps-setup.yml +6 -0
- package/lib/content/audit.yml +3 -2
- package/lib/content/ci-release.yml +31 -0
- package/lib/content/ci.yml +6 -8
- package/lib/content/codeql-analysis.yml +10 -17
- package/lib/content/commitlintrc.js +1 -1
- package/lib/content/dependabot.yml +2 -20
- package/lib/content/eslintrc.js +3 -3
- package/lib/content/gitignore +1 -1
- package/lib/content/index.js +34 -21
- package/lib/content/npmrc +1 -1
- package/lib/content/pkg.json +25 -23
- package/lib/content/post-dependabot.yml +55 -11
- package/lib/content/pull-request.yml +11 -9
- package/lib/content/release-please-config.json +5 -5
- package/lib/content/release-please-manifest.json +1 -1
- package/lib/content/release.yml +120 -15
- package/lib/index.js +9 -12
- package/lib/release-please/index.js +26 -5
- package/lib/util/files.js +5 -3
- package/lib/util/parser.js +73 -16
- package/lib/util/template.js +8 -1
- package/package.json +1 -1
- package/lib/content/_setup-deps.yml +0 -1
- package/lib/content/_setup-git.yml +0 -11
- package/lib/content/_setup-job.yml +0 -6
- package/lib/content/release-please.yml +0 -64
package/lib/util/parser.js
CHANGED
|
@@ -8,7 +8,9 @@ const { unset } = require('lodash')
|
|
|
8
8
|
const template = require('./template.js')
|
|
9
9
|
const jsonDiff = require('./json-diff')
|
|
10
10
|
const merge = require('./merge.js')
|
|
11
|
+
|
|
11
12
|
const setFirst = (first, rest) => ({ ...first, ...rest })
|
|
13
|
+
|
|
12
14
|
const traverse = (value, visit, keys = []) => {
|
|
13
15
|
if (keys.length) {
|
|
14
16
|
const res = visit(keys, value)
|
|
@@ -23,17 +25,25 @@ const traverse = (value, visit, keys = []) => {
|
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
const fsOk = (code) => (error) => {
|
|
29
|
+
if (error.code === 'ENOENT') {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
return Object.assign(error, { code })
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
class Base {
|
|
27
36
|
static types = []
|
|
28
|
-
static header = 'This file is automatically added by {{__NAME__}}. Do not edit.'
|
|
37
|
+
static header = 'This file is automatically added by {{ __NAME__ }}. Do not edit.'
|
|
29
38
|
comment = (v) => v
|
|
30
39
|
merge = false // supply a merge function which runs on prepare for certain types
|
|
31
40
|
DELETE = template.DELETE
|
|
32
41
|
|
|
33
|
-
constructor (target, source, options) {
|
|
42
|
+
constructor (target, source, options, fileOptions) {
|
|
34
43
|
this.target = target
|
|
35
44
|
this.source = source
|
|
36
45
|
this.options = options
|
|
46
|
+
this.fileOptions = fileOptions
|
|
37
47
|
}
|
|
38
48
|
|
|
39
49
|
header () {
|
|
@@ -42,6 +52,13 @@ class Base {
|
|
|
42
52
|
}
|
|
43
53
|
}
|
|
44
54
|
|
|
55
|
+
clean () {
|
|
56
|
+
if (this.fileOptions.clean) {
|
|
57
|
+
return fs.rm(this.target).catch(fsOk())
|
|
58
|
+
}
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
|
|
45
62
|
read (s) {
|
|
46
63
|
return fs.readFile(s, { encoding: 'utf-8' })
|
|
47
64
|
}
|
|
@@ -88,13 +105,17 @@ class Base {
|
|
|
88
105
|
// XXX: everything is allowed to be overridden in base classes but we could
|
|
89
106
|
// find a different solution than making everything public
|
|
90
107
|
applyWrite () {
|
|
91
|
-
return Promise.resolve(this.
|
|
108
|
+
return Promise.resolve(this.clean())
|
|
109
|
+
.then(() => this.read(this.source))
|
|
92
110
|
// replace template vars first, this will throw for nonexistant vars
|
|
93
111
|
// because it must be parseable after this step
|
|
94
112
|
.then((s) => this.template(s))
|
|
95
113
|
// parse into whatever data structure is necessary for maniuplating
|
|
96
114
|
// diffing, merging, etc. by default its a string
|
|
97
|
-
.then((s) =>
|
|
115
|
+
.then((s) => {
|
|
116
|
+
this.sourcePreParse = s
|
|
117
|
+
return this.parse(s)
|
|
118
|
+
})
|
|
98
119
|
// prepare the source for writing and diffing, pass in current
|
|
99
120
|
// target for merging. errors parsing or preparing targets are ok here
|
|
100
121
|
.then((s) => this.applyTarget().catch(() => null).then((t) => this.prepare(s, t)))
|
|
@@ -109,14 +130,9 @@ class Base {
|
|
|
109
130
|
}
|
|
110
131
|
|
|
111
132
|
async applyDiff () {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return null
|
|
116
|
-
} else {
|
|
117
|
-
return { code: 'ETARGETERROR', error: e }
|
|
118
|
-
}
|
|
119
|
-
})
|
|
133
|
+
// handle if old does not exist
|
|
134
|
+
const targetError = 'ETARGETERROR'
|
|
135
|
+
const target = await this.applyTarget().catch(fsOk(targetError))
|
|
120
136
|
|
|
121
137
|
// no need to diff if current file does not exist
|
|
122
138
|
if (target === null) {
|
|
@@ -131,11 +147,11 @@ class Base {
|
|
|
131
147
|
|
|
132
148
|
// if there was a target error then there is no need to diff
|
|
133
149
|
// so we just show the source with an error message
|
|
134
|
-
if (target.code ===
|
|
150
|
+
if (target.code === targetError) {
|
|
135
151
|
const msg = `[${this.options.config.__NAME__} ERROR]`
|
|
136
152
|
return [
|
|
137
153
|
`${msg} There was an erroring getting the target file`,
|
|
138
|
-
`${msg} ${target
|
|
154
|
+
`${msg} ${target}`,
|
|
139
155
|
`${msg} It will be overwritten with the following source:`,
|
|
140
156
|
'-'.repeat(40),
|
|
141
157
|
this.toString(source),
|
|
@@ -175,7 +191,12 @@ class Yml extends Base {
|
|
|
175
191
|
comment = (c) => ` ${c}`
|
|
176
192
|
|
|
177
193
|
toString (s) {
|
|
178
|
-
|
|
194
|
+
try {
|
|
195
|
+
return s.toString({ lineWidth: 0, indent: 2 })
|
|
196
|
+
} catch (err) {
|
|
197
|
+
err.message = [this.target, this.sourcePreParse, ...s.errors, err.message].join('\n')
|
|
198
|
+
throw err
|
|
199
|
+
}
|
|
179
200
|
}
|
|
180
201
|
|
|
181
202
|
parse (s) {
|
|
@@ -192,6 +213,41 @@ class Yml extends Base {
|
|
|
192
213
|
}
|
|
193
214
|
}
|
|
194
215
|
|
|
216
|
+
class YmlMerge extends Yml {
|
|
217
|
+
prepare (source, t) {
|
|
218
|
+
if (t === null) {
|
|
219
|
+
// If target does not exist or is in an
|
|
220
|
+
// error state, we cant do anything but write
|
|
221
|
+
// the whole document
|
|
222
|
+
return super.prepare(source)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const key = [].concat(this.key)
|
|
226
|
+
|
|
227
|
+
const getId = (node) => {
|
|
228
|
+
const index = node.items.findIndex(p => p.key?.value === this.id)
|
|
229
|
+
return index !== -1 ? node.items[index].value?.value : node.toJSON()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const target = this.parse(t)
|
|
233
|
+
const targetNodes = target.getIn(key).items.reduce((acc, node, index) => {
|
|
234
|
+
acc[getId(node)] = { node, index }
|
|
235
|
+
return acc
|
|
236
|
+
}, {})
|
|
237
|
+
|
|
238
|
+
for (const node of source.getIn(key).items) {
|
|
239
|
+
const index = targetNodes[getId(node)]?.index
|
|
240
|
+
if (typeof index === 'number' && index !== -1) {
|
|
241
|
+
target.setIn([...key, index], node)
|
|
242
|
+
} else {
|
|
243
|
+
target.addIn(key, node)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return super.prepare(target)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
195
251
|
class Json extends Base {
|
|
196
252
|
static types = ['json']
|
|
197
253
|
// its a json comment! not really but we do add a special key
|
|
@@ -220,7 +276,7 @@ class Json extends Base {
|
|
|
220
276
|
}
|
|
221
277
|
|
|
222
278
|
class JsonMerge extends Json {
|
|
223
|
-
static header = 'This file is partially managed by {{__NAME__}}. Edits may be overwritten.'
|
|
279
|
+
static header = 'This file is partially managed by {{ __NAME__ }}. Edits may be overwritten.'
|
|
224
280
|
merge = (t, s) => merge(t, s)
|
|
225
281
|
}
|
|
226
282
|
|
|
@@ -260,6 +316,7 @@ const Parsers = {
|
|
|
260
316
|
Ini,
|
|
261
317
|
Markdown,
|
|
262
318
|
Yml,
|
|
319
|
+
YmlMerge,
|
|
263
320
|
Json,
|
|
264
321
|
JsonMerge,
|
|
265
322
|
PackageJson,
|
package/lib/util/template.js
CHANGED
|
@@ -3,12 +3,19 @@ const { basename, extname, join } = require('path')
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const DELETE = '__DELETE__'
|
|
5
5
|
|
|
6
|
+
const safeValues = (obj) => Object.entries(obj).map(([key, value]) =>
|
|
7
|
+
[key, new Handlebars.SafeString(value)])
|
|
8
|
+
|
|
6
9
|
const partialName = (s) => basename(s, extname(s)) // remove extension
|
|
7
10
|
.replace(/^_/, '') // remove leading underscore
|
|
8
11
|
.replace(/-([a-z])/g, (_, g) => g.toUpperCase()) // camelcase
|
|
9
12
|
|
|
10
13
|
const setupHandlebars = (...partialDirs) => {
|
|
11
|
-
Handlebars.registerHelper('obj', ({ hash }) => hash)
|
|
14
|
+
Handlebars.registerHelper('obj', ({ hash }) => Object.fromEntries(safeValues(hash)))
|
|
15
|
+
Handlebars.registerHelper('join', (arr, sep) => arr.join(typeof sep === 'string' ? sep : ', '))
|
|
16
|
+
Handlebars.registerHelper('pluck', (arr, key) => arr.map(a => a[key]))
|
|
17
|
+
Handlebars.registerHelper('quote', (arr) => arr.map(a => `'${a}'`))
|
|
18
|
+
Handlebars.registerHelper('last', (arr) => arr[arr.length - 1])
|
|
12
19
|
Handlebars.registerHelper('json', (c) => JSON.stringify(c))
|
|
13
20
|
Handlebars.registerHelper('del', () => JSON.stringify(DELETE))
|
|
14
21
|
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
- run: {{rootNpmPath}} i --ignore-scripts --no-audit --no-fund {{~#if flags}} {{flags}}{{/if}}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
- uses: actions/checkout@v3
|
|
2
|
-
{{#if checkout}}
|
|
3
|
-
with:
|
|
4
|
-
{{#each checkout}}
|
|
5
|
-
{{@key}}: {{this}}
|
|
6
|
-
{{/each}}
|
|
7
|
-
{{/if}}
|
|
8
|
-
- name: Setup git user
|
|
9
|
-
run: |
|
|
10
|
-
git config --global user.email "npm-cli+bot@github.com"
|
|
11
|
-
git config --global user.name "npm CLI robot"
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
name: Release Please
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
{{#each branches}}
|
|
7
|
-
- {{.}}
|
|
8
|
-
{{/each}}
|
|
9
|
-
{{#each releaseBranches}}
|
|
10
|
-
- {{.}}
|
|
11
|
-
{{/each}}
|
|
12
|
-
|
|
13
|
-
permissions:
|
|
14
|
-
contents: write
|
|
15
|
-
pull-requests: write
|
|
16
|
-
|
|
17
|
-
jobs:
|
|
18
|
-
release-please:
|
|
19
|
-
outputs:
|
|
20
|
-
pr: $\{{ steps.release.outputs.pr }}
|
|
21
|
-
release: $\{{ steps.release.outputs.release }}
|
|
22
|
-
{{> setupJob }}
|
|
23
|
-
- name: Release Please
|
|
24
|
-
id: release
|
|
25
|
-
run: npx --offline template-oss-release-please $\{{ github.ref_name }}
|
|
26
|
-
env:
|
|
27
|
-
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
|
|
28
|
-
|
|
29
|
-
post-pr:
|
|
30
|
-
needs: release-please
|
|
31
|
-
if: needs.release-please.outputs.pr
|
|
32
|
-
runs-on: ubuntu-latest
|
|
33
|
-
outputs:
|
|
34
|
-
ref: $\{{ steps.ref.outputs.branch }}
|
|
35
|
-
steps:
|
|
36
|
-
- name: Output ref
|
|
37
|
-
id: ref
|
|
38
|
-
run: echo "::set-output name=branch::$\{{ fromJSON(needs.release-please.outputs.pr).headBranchName }}"
|
|
39
|
-
{{> setupGit checkout=(obj ref="${{ steps.ref.outputs.branch }}" fetch-depth=0)}}
|
|
40
|
-
{{> setupNode}}
|
|
41
|
-
{{> setupDeps}}
|
|
42
|
-
- name: Post pull request actions
|
|
43
|
-
env:
|
|
44
|
-
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
|
|
45
|
-
run: |
|
|
46
|
-
{{rootNpmPath}} run rp-pull-request --ignore-scripts --if-present -ws -iwr
|
|
47
|
-
git commit -am "chore: post pull request" || true
|
|
48
|
-
git push
|
|
49
|
-
|
|
50
|
-
release-test:
|
|
51
|
-
needs: post-pr
|
|
52
|
-
if: needs.post-pr.outputs.ref
|
|
53
|
-
uses: ./.github/workflows/release.yml
|
|
54
|
-
with:
|
|
55
|
-
ref: $\{{ needs.post-pr.outputs.ref }}
|
|
56
|
-
|
|
57
|
-
post-release:
|
|
58
|
-
needs: release-please
|
|
59
|
-
{{> setupJob jobIf="needs.release-please.outputs.release" }}
|
|
60
|
-
- name: Post release actions
|
|
61
|
-
env:
|
|
62
|
-
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
|
|
63
|
-
run: |
|
|
64
|
-
{{rootNpmPath}} run rp-release --ignore-scripts --if-present -ws -iwr
|