bulk-release 2.11.7 → 2.12.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/CHANGELOG.md +5 -0
- package/README.md +10 -1
- package/package.json +1 -1
- package/src/main/js/analyze.js +8 -2
- package/src/main/js/changelog.js +1 -2
- package/src/main/js/gh.js +1 -2
- package/src/main/js/meta.js +64 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## [2.12.0](https://github.com/semrel-extra/zx-bulk-release/compare/v2.11.7...v2.12.0) (2023-09-19)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
* feat: provide `tagFormat` configuration ([c405454](https://github.com/semrel-extra/zx-bulk-release/commit/c4054545da55b430e427ab8b8684a305a1dd8360))
|
|
5
|
+
|
|
1
6
|
## [2.11.7](https://github.com/semrel-extra/zx-bulk-release/compare/v2.11.6...v2.11.7) (2023-09-19)
|
|
2
7
|
|
|
3
8
|
### Fixes & improvements
|
package/README.md
CHANGED
|
@@ -199,10 +199,19 @@ Note, [npm-package-name charset](https://www.npmjs.com/package/validate-npm-pack
|
|
|
199
199
|
'2022.6.13-examplecom.v1.0.0.ZXhhbXBsZS5jb20-f1'
|
|
200
200
|
// date name ver b64 format
|
|
201
201
|
```
|
|
202
|
+
Anyway, it's still possible to override the default config by `tagFormat` option:
|
|
203
|
+
|
|
204
|
+
| tagFormat | Example |
|
|
205
|
+
|-----------|------------------------------------------------------|
|
|
206
|
+
| f0 | 2022.6.22-qiwi.pijma-native.v1.0.0-beta.0+foo.bar-f0 |
|
|
207
|
+
| f1 | 2022.6.13-examplecom.v1.0.0.ZXhhbXBsZS5jb20-f1 |
|
|
208
|
+
| lerna | @qiwi/pijma-ssr@1.1.12 |
|
|
209
|
+
| pure | 1.2.3-my.package |
|
|
210
|
+
|
|
202
211
|
|
|
203
212
|
### Meta
|
|
204
213
|
|
|
205
|
-
Each release
|
|
214
|
+
Each release pushes its result to the `meta` branch.
|
|
206
215
|
`2022-6-26-semrel-extra-zxbr-test-c-1-3-1-f0.json`
|
|
207
216
|
```json
|
|
208
217
|
{
|
package/package.json
CHANGED
package/src/main/js/analyze.js
CHANGED
|
@@ -22,9 +22,15 @@ export const analyze = async (pkg) => {
|
|
|
22
22
|
)
|
|
23
23
|
pkg.preversion = pre && pkg.version
|
|
24
24
|
pkg.manifest.version = pkg.version
|
|
25
|
-
pkg.tag = releaseType ? formatTag({name: pkg.name, version: pkg.version}) : null
|
|
25
|
+
pkg.tag = releaseType ? formatTag({name: pkg.name, version: pkg.version, format: pkg.config.tagFormat}) : null
|
|
26
26
|
|
|
27
|
-
log({pkg})(
|
|
27
|
+
log({pkg})(
|
|
28
|
+
'semantic changes', changes,
|
|
29
|
+
'releaseType', releaseType,
|
|
30
|
+
'prevVersion', latestVersion,
|
|
31
|
+
'nextVersion', pkg.version,
|
|
32
|
+
'nextTag', pkg.tag
|
|
33
|
+
)
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
export const releaseSeverityOrder = ['major', 'minor', 'patch']
|
package/src/main/js/changelog.js
CHANGED
|
@@ -22,9 +22,8 @@ export const pushChangelog = queuefy(async (pkg) => {
|
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
export const formatReleaseNotes = async (pkg) => {
|
|
25
|
-
const {name, version, absPath: cwd, config: {ghBasicAuth: basicAuth}} = pkg
|
|
25
|
+
const {name, version, tag = formatTag({name, version}), absPath: cwd, config: {ghBasicAuth: basicAuth}} = pkg
|
|
26
26
|
const {repoPublicUrl} = await getRepo(cwd, {basicAuth})
|
|
27
|
-
const tag = formatTag({name, version})
|
|
28
27
|
const releaseDiffRef = `## [${name}@${version}](${repoPublicUrl}/compare/${pkg.latest.tag?.ref}...${tag}) (${new Date().toISOString().slice(0, 10)})`
|
|
29
28
|
const releaseDetails = Object.values(pkg.changes
|
|
30
29
|
.reduce((acc, {group, subj, short, hash}) => {
|
package/src/main/js/gh.js
CHANGED
|
@@ -14,9 +14,8 @@ export const ghRelease = async (pkg) => {
|
|
|
14
14
|
log({pkg})('create gh release')
|
|
15
15
|
|
|
16
16
|
const now = Date.now()
|
|
17
|
-
const {name, version, absPath: cwd} = pkg
|
|
17
|
+
const {name, version, absPath: cwd, tag = formatTag({name, version})} = pkg
|
|
18
18
|
const {repoName} = await getRepo(cwd, {basicAuth})
|
|
19
|
-
const tag = formatTag({name, version})
|
|
20
19
|
const releaseNotes = await formatReleaseNotes(pkg)
|
|
21
20
|
const releaseData = JSON.stringify({
|
|
22
21
|
name: tag,
|
package/src/main/js/meta.js
CHANGED
|
@@ -8,8 +8,7 @@ import {fetchRepo, pushCommit, getTags as getGitTags, pushTag} from './git.js'
|
|
|
8
8
|
import {fetchManifest} from './npm.js'
|
|
9
9
|
|
|
10
10
|
export const pushReleaseTag = async (pkg) => {
|
|
11
|
-
const {name, version, config: {gitCommitterEmail, gitCommitterName}} = pkg
|
|
12
|
-
const tag = formatTag({name, version})
|
|
11
|
+
const {name, version, tag = formatTag({name, version}),config: {gitCommitterEmail, gitCommitterName}} = pkg
|
|
13
12
|
const cwd = pkg.context.git.root
|
|
14
13
|
|
|
15
14
|
pkg.context.git.tag = tag
|
|
@@ -21,8 +20,7 @@ export const pushReleaseTag = async (pkg) => {
|
|
|
21
20
|
export const pushMeta = queuefy(async (pkg) => {
|
|
22
21
|
log({pkg})('push artifact to branch \'meta\'')
|
|
23
22
|
|
|
24
|
-
const {name, version, absPath: cwd, config: {gitCommitterEmail, gitCommitterName, ghBasicAuth: basicAuth}} = pkg
|
|
25
|
-
const tag = formatTag({name, version})
|
|
23
|
+
const {name, version, tag = formatTag({name, version}), absPath: cwd, config: {gitCommitterEmail, gitCommitterName, ghBasicAuth: basicAuth}} = pkg
|
|
26
24
|
const to = '.'
|
|
27
25
|
const branch = 'meta'
|
|
28
26
|
const msg = `chore: release meta ${name} ${version}`
|
|
@@ -53,7 +51,10 @@ export const getLatest = async (pkg) => {
|
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
53
|
|
|
54
|
+
const isSafeName = n => /^(@?[a-z0-9-]+\/)?[a-z0-9-]+$/.test(n)
|
|
55
|
+
|
|
56
56
|
const f0 = {
|
|
57
|
+
name: 'f0',
|
|
57
58
|
parse(tag) {
|
|
58
59
|
if (!tag.endsWith('-f0')) return null
|
|
59
60
|
|
|
@@ -66,10 +67,10 @@ const f0 = {
|
|
|
66
67
|
const date = parseDateTag(_date)
|
|
67
68
|
const name = _name.includes('.') ? `@${_name.replace('.', '/')}` : _name
|
|
68
69
|
|
|
69
|
-
return {date, name, version, format:
|
|
70
|
+
return {date, name, version, format: this.name, ref: tag}
|
|
70
71
|
},
|
|
71
72
|
format({name, date = new Date(), version}) {
|
|
72
|
-
if (
|
|
73
|
+
if (!isSafeName(name) || !semver.valid(version)) return null
|
|
73
74
|
|
|
74
75
|
const d = formatDateTag(date)
|
|
75
76
|
const n = name.replace('@', '').replace('/', '.')
|
|
@@ -79,6 +80,7 @@ const f0 = {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
const f1 = {
|
|
83
|
+
name: 'f1',
|
|
82
84
|
parse(tag) {
|
|
83
85
|
if (!tag.endsWith('-f1')) return null
|
|
84
86
|
|
|
@@ -91,7 +93,7 @@ const f1 = {
|
|
|
91
93
|
const date = parseDateTag(_date)
|
|
92
94
|
const name = Buffer.from(b64, 'base64url').toString('utf8')
|
|
93
95
|
|
|
94
|
-
return {date, name, version, format:
|
|
96
|
+
return {date, name, version, format: this.name, ref: tag}
|
|
95
97
|
},
|
|
96
98
|
format({name, date = new Date(), version}) {
|
|
97
99
|
if (!semver.valid(version)) return null
|
|
@@ -105,35 +107,72 @@ const f1 = {
|
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
const lerna = {
|
|
110
|
+
name: 'lerna',
|
|
108
111
|
parse(tag) {
|
|
109
112
|
const pattern = /^(@?[a-z0-9-]+(?:\/[a-z0-9-]+)?)@(v?\d+\.\d+\.\d+.*)/
|
|
110
113
|
const [, name, version] = pattern.exec(tag) || []
|
|
111
114
|
|
|
112
115
|
if (!semver.valid(version)) return null
|
|
113
116
|
|
|
114
|
-
return {name, version, format:
|
|
117
|
+
return {name, version, format: this.name, ref: tag}
|
|
115
118
|
},
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
format({name, version}) {
|
|
120
|
+
if (!semver.valid(version)) return null
|
|
121
|
+
|
|
122
|
+
return `${name}@${version}`
|
|
123
|
+
}
|
|
121
124
|
}
|
|
122
125
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
126
|
+
const pure = {
|
|
127
|
+
name: 'pure',
|
|
128
|
+
parse(tag) {
|
|
129
|
+
if (tag.endsWith('-f0') || tag.endsWith('-f1')) {
|
|
130
|
+
return null
|
|
131
|
+
}
|
|
132
|
+
const parsed = semver.parse(tag) || {}
|
|
133
|
+
const {prerelease} = parsed
|
|
134
|
+
if (!prerelease?.length) {
|
|
135
|
+
return null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const [n, o = ''] = prerelease.reverse()
|
|
139
|
+
const name = o === 'x' ? n : `@${o}/${n}`
|
|
140
|
+
const version = tag.slice(0, -1 - n.length - (o ? o.length + 1 : 0))
|
|
141
|
+
|
|
142
|
+
return {format: this.name, ref: tag, name, version}
|
|
143
|
+
},
|
|
144
|
+
format({name, version}) {
|
|
145
|
+
const parsed = semver.parse(version)
|
|
146
|
+
if (!parsed || !isSafeName(name)) {
|
|
147
|
+
return null
|
|
148
|
+
}
|
|
149
|
+
const {prerelease} = parsed
|
|
150
|
+
const [n, o] = name.slice(name[0] === '@' ? 1 : 0).split('/').reverse()
|
|
151
|
+
const extra = prerelease.length
|
|
152
|
+
? '.' + [o || 'x', n].join('.')
|
|
153
|
+
: '-' + [o, n].filter(Boolean).join('.')
|
|
154
|
+
return version + extra
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const getFormatter = (tagFormat) => {
|
|
159
|
+
if (!tagFormat) {
|
|
160
|
+
return {
|
|
161
|
+
parse() {},
|
|
162
|
+
format() {}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const formatter = [f0, f1, pure, lerna].find(f => f.name === tagFormat)
|
|
166
|
+
if (!formatter) {
|
|
167
|
+
throw new Error(`Unsupported tag format: ${tagFormat}`)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return formatter
|
|
171
|
+
}
|
|
133
172
|
|
|
134
|
-
export const parseTag = (tag) => f0.parse(tag) || f1.parse(tag) || lerna.parse(tag) || null
|
|
173
|
+
export const parseTag = (tag) => f0.parse(tag) || f1.parse(tag) || lerna.parse(tag) || pure.parse(tag) || null
|
|
135
174
|
|
|
136
|
-
export const formatTag = (tag) => f0.format(tag) || f1.format(tag) || null
|
|
175
|
+
export const formatTag = (tag, tagFormat = tag.format) => getFormatter(tagFormat).format(tag) || f0.format(tag) || f1.format(tag) || null
|
|
137
176
|
|
|
138
177
|
export const getTags = async (cwd, ref = '') =>
|
|
139
178
|
(await getGitTags(cwd, ref))
|