zx-bulk-release 1.13.0 → 1.14.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 +11 -7
- package/package.json +1 -1
- package/src/main/js/build.js +9 -16
- package/src/main/js/config.js +11 -5
- package/src/main/js/publish.js +11 -13
- package/src/test/js/integration.test.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## [1.14.0](https://github.com/semrel-extra/zx-bulk-release/compare/v1.13.0...v1.14.0) (2022-06-27)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
* feat: add config normalizer ([80afee7](https://github.com/semrel-extra/zx-bulk-release/commit/80afee796e71aef6288943b2c6276b6f172192c5))
|
|
5
|
+
|
|
1
6
|
## [1.13.0](https://github.com/semrel-extra/zx-bulk-release/compare/v1.12.0...v1.13.0) (2022-06-27)
|
|
2
7
|
|
|
3
8
|
### Features
|
package/README.md
CHANGED
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
## Roadmap
|
|
11
11
|
* [x] [Conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#specification) trigger semantic releases.
|
|
12
12
|
* [x] Predictable [toposort](https://githib.com/semrel-extra/topo)-driven flow.
|
|
13
|
-
* [x] No blocking (no release commits).
|
|
14
|
-
* [
|
|
15
|
-
* [x]
|
|
13
|
+
* [x] No default branch blocking (no release commits).
|
|
14
|
+
* [x] Pkg changelogs go to `changelog` branch (configurable).
|
|
15
|
+
* [x] Docs are published to `gh-pages` branch (configurable).
|
|
16
|
+
* [x] No extra builds. The required deps are fetched from the pkg registry (`npmFetch` flag).
|
|
16
17
|
|
|
17
18
|
## Requirements
|
|
18
19
|
* macOS / linux
|
|
@@ -42,10 +43,13 @@ await run({
|
|
|
42
43
|
|
|
43
44
|
### Config
|
|
44
45
|
Any [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) compliant format: `.releaserc`, `.release.json`, `.release.yaml`, etc.
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"cmd": "yarn && yarn build && yarn test",
|
|
49
|
+
"npmFetch": true,
|
|
50
|
+
"changelog": "changelog",
|
|
51
|
+
"ghPages": "gh-pages"
|
|
52
|
+
}
|
|
49
53
|
```
|
|
50
54
|
|
|
51
55
|
## Implementation notes
|
package/package.json
CHANGED
package/src/main/js/build.js
CHANGED
|
@@ -1,36 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {tempy, fs, $} from 'zx-extra'
|
|
2
2
|
import {copy} from 'git-glob-cp'
|
|
3
3
|
import ini from 'ini'
|
|
4
4
|
import {traverseDeps} from './deps.js'
|
|
5
5
|
import {parseEnv} from './publish.js'
|
|
6
6
|
|
|
7
|
-
export const build = (pkg, packages) =>
|
|
7
|
+
export const build = async (pkg, packages) => {
|
|
8
8
|
if (pkg.built) return true
|
|
9
9
|
|
|
10
10
|
await traverseDeps(pkg, packages, async (_, {pkg}) => build(pkg, packages))
|
|
11
11
|
|
|
12
12
|
const {config} = pkg
|
|
13
13
|
|
|
14
|
-
if (config.
|
|
15
|
-
if (pkg.changes.length === 0 && config.
|
|
16
|
-
|
|
14
|
+
if (config.cmd) {
|
|
15
|
+
if (pkg.changes.length === 0 && config.npmFetch) await fetchPkg(pkg)
|
|
17
16
|
if (!pkg.fetched) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
await $.raw`${config.buildCmd}`
|
|
21
|
-
|
|
22
|
-
if (config.testCmd) {
|
|
23
|
-
console.log(`[${pkg.name}] test`)
|
|
24
|
-
await $.raw`${config.testCmd}`
|
|
25
|
-
}
|
|
17
|
+
console.log(`[${pkg.name}] run cmd '${config.cmd}'`)
|
|
18
|
+
await $.o({cwd: pkg.absPath, quote: v => v})`${config.cmd}`
|
|
26
19
|
}
|
|
27
20
|
}
|
|
28
21
|
|
|
29
22
|
pkg.built = true
|
|
30
23
|
return true
|
|
31
|
-
}
|
|
24
|
+
}
|
|
32
25
|
|
|
33
|
-
const fetchPkg =
|
|
26
|
+
const fetchPkg = async (pkg) => {
|
|
34
27
|
try {
|
|
35
28
|
const cwd = pkg.absPath
|
|
36
29
|
const {npmRegistry, npmToken, npmConfig} = parseEnv($.env)
|
|
@@ -49,7 +42,7 @@ const fetchPkg = (pkg) => ctx(async ($) => {
|
|
|
49
42
|
} catch (e) {
|
|
50
43
|
console.log(`[${pkg.name}] fetching '${pkg.name}@${pkg.version}' failed`, e)
|
|
51
44
|
}
|
|
52
|
-
}
|
|
45
|
+
}
|
|
53
46
|
|
|
54
47
|
// NOTE registry-auth-token does not work with localhost:4873
|
|
55
48
|
const getAuthToken = (registry, npmrc) =>
|
package/src/main/js/config.js
CHANGED
|
@@ -14,13 +14,19 @@ const CONFIG_FILES = [
|
|
|
14
14
|
]
|
|
15
15
|
|
|
16
16
|
export const defaultConfig = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
cmd: 'yarn && yarn build && yarn test',
|
|
18
|
+
npmFetch: true,
|
|
19
|
+
changelog: 'changelog',
|
|
20
|
+
ghPages: 'gh-pages'
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export const getConfig = async (...cwds) =>
|
|
23
|
-
(await Promise.all(cwds.map(
|
|
24
|
+
normalizeConfig((await Promise.all(cwds.map(
|
|
24
25
|
cwd => cosmiconfig(CONFIG_NAME, { searchPlaces: CONFIG_FILES }).search(cwd).then(r => r?.config)
|
|
25
|
-
))).find(Boolean) || defaultConfig
|
|
26
|
+
))).find(Boolean) || defaultConfig)
|
|
26
27
|
|
|
28
|
+
export const normalizeConfig = config => ({
|
|
29
|
+
...config,
|
|
30
|
+
npmFetch: config.npmFetch || config.fetch || config.fetchPkg,
|
|
31
|
+
cmd: config.cmd || (config.buildCmd ? `${config.buildCmd}${config.testCmd ? ` && ${config.testCmd}` : ''}` : '')
|
|
32
|
+
})
|
package/src/main/js/publish.js
CHANGED
|
@@ -15,17 +15,17 @@ export const pushTag = (pkg) => ctx(async ($) => {
|
|
|
15
15
|
const {absPath: cwd, name, version} = pkg
|
|
16
16
|
const tag = formatTag({name, version})
|
|
17
17
|
const {gitCommitterEmail, gitCommitterName} = parseEnv($.env)
|
|
18
|
-
$.cwd = cwd
|
|
19
18
|
|
|
20
19
|
console.log(`[${name}] push release tag ${tag}`)
|
|
21
20
|
|
|
21
|
+
$.cwd = cwd
|
|
22
22
|
await $`git config user.name ${gitCommitterName}`
|
|
23
23
|
await $`git config user.email ${gitCommitterEmail}`
|
|
24
24
|
await $`git tag -m ${tag} ${tag}`
|
|
25
25
|
await $`git push origin ${tag}`
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
-
export const pushMeta =
|
|
28
|
+
export const pushMeta = async (pkg) => {
|
|
29
29
|
console.log(`[${pkg.name}] push artifact to branch 'meta'`)
|
|
30
30
|
|
|
31
31
|
const cwd = pkg.absPath
|
|
@@ -34,9 +34,7 @@ export const pushMeta = (pkg) => ctx(async ($) => {
|
|
|
34
34
|
const to = '.'
|
|
35
35
|
const branch = 'meta'
|
|
36
36
|
const msg = `chore: release meta ${name} ${version}`
|
|
37
|
-
|
|
38
|
-
$.cwd = cwd
|
|
39
|
-
const hash = (await $`git rev-parse HEAD`).toString().trim()
|
|
37
|
+
const hash = (await $.o({cwd})`git rev-parse HEAD`).toString().trim()
|
|
40
38
|
const meta = {
|
|
41
39
|
META_VERSION: '1',
|
|
42
40
|
name: pkg.name,
|
|
@@ -50,7 +48,7 @@ export const pushMeta = (pkg) => ctx(async ($) => {
|
|
|
50
48
|
const files = [{relpath: `${getArtifactPath(tag)}.json`, contents: meta}]
|
|
51
49
|
|
|
52
50
|
await push({cwd, to, branch, msg, files})
|
|
53
|
-
}
|
|
51
|
+
}
|
|
54
52
|
|
|
55
53
|
export const npmPublish = (pkg) => ctx(async ($) => {
|
|
56
54
|
const {absPath: cwd, name, version} = pkg
|
|
@@ -124,10 +122,11 @@ const ghPages = async (pkg) => {
|
|
|
124
122
|
const {config: {ghPages: opts}} = pkg
|
|
125
123
|
if (!opts) return
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
const [from, branch = 'gh-pages', to = '.', msg = `docs: update docs ${pkg.name} ${pkg.version}`] = typeof opts === 'string'
|
|
125
|
+
const [branch = 'gh-pages', from = 'docs', to = '.', msg = `docs: update docs ${pkg.name} ${pkg.version}`] = typeof opts === 'string'
|
|
129
126
|
? opts.split(' ')
|
|
130
|
-
: [opts.
|
|
127
|
+
: [opts.branch, opts.from, opts.to, opts.msg]
|
|
128
|
+
|
|
129
|
+
console.log(`[${pkg.name}] publish docs to ${branch}`)
|
|
131
130
|
|
|
132
131
|
await push({
|
|
133
132
|
cwd: path.resolve(pkg.absPath, from),
|
|
@@ -224,10 +223,9 @@ export const parseEnv = (env = process.env) => {
|
|
|
224
223
|
}
|
|
225
224
|
}
|
|
226
225
|
|
|
227
|
-
export const parseRepo =
|
|
228
|
-
$.cwd = cwd
|
|
226
|
+
export const parseRepo = async (cwd) => {
|
|
229
227
|
const {ghToken, ghUser} = parseEnv($.env)
|
|
230
|
-
const originUrl = (await
|
|
228
|
+
const originUrl = (await $.o({cwd})`git config --get remote.origin.url`).toString().trim()
|
|
231
229
|
const [,,repoHost, repoName] = originUrl.replace(':', '/').replace(/\.git/, '').match(/.+(@|\/\/)([^/]+)\/(.+)$/) || []
|
|
232
230
|
const repoPublicUrl = `https://${repoHost}/${repoName}`
|
|
233
231
|
const repoAuthedUrl = ghToken && ghUser && repoHost && repoName?
|
|
@@ -241,4 +239,4 @@ export const parseRepo = (cwd) => ctx(async ($) => {
|
|
|
241
239
|
repoAuthedUrl,
|
|
242
240
|
originUrl,
|
|
243
241
|
}
|
|
244
|
-
}
|
|
242
|
+
}
|
|
@@ -52,7 +52,7 @@ const cwd = await createFakeRepo({
|
|
|
52
52
|
buildCmd: 'yarn && yarn build',
|
|
53
53
|
testCmd: 'yarn test',
|
|
54
54
|
fetch: true,
|
|
55
|
-
changelog:
|
|
55
|
+
changelog: 'changelog'
|
|
56
56
|
},
|
|
57
57
|
exports: {
|
|
58
58
|
'.': {
|
|
@@ -115,7 +115,7 @@ const cwd = await createFakeRepo({
|
|
|
115
115
|
buildCmd: 'yarn && yarn build',
|
|
116
116
|
testCmd: 'yarn test',
|
|
117
117
|
fetch: true,
|
|
118
|
-
ghPages: '
|
|
118
|
+
ghPages: 'gh-pages docs b'
|
|
119
119
|
},
|
|
120
120
|
exports: {
|
|
121
121
|
'.': {
|