zx-bulk-release 1.4.0 → 1.5.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 +15 -0
- package/package.json +1 -1
- package/src/main/js/publish.js +102 -86
- package/src/test/js/integration.test.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [1.5.0](https://github.com/semrel-extra/zx-bulk-release/compare/v1.4.2...v1.5.0) (2022-06-21)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
* feat: add commit-ish to meta ([9092a4d](https://github.com/semrel-extra/zx-bulk-release/commit/9092a4d41f51fb58a9d7cb1696bb9ee3f07c9133))
|
|
5
|
+
|
|
6
|
+
## [1.4.2](https://github.com/semrel-extra/zx-bulk-release/compare/v1.4.1...v1.4.2) (2022-06-21)
|
|
7
|
+
|
|
8
|
+
### Fixes & improvements
|
|
9
|
+
* refactor: use common iface for push internals ([e614e42](https://github.com/semrel-extra/zx-bulk-release/commit/e614e42d8b323749082b94611f4552fdacebe1f5))
|
|
10
|
+
|
|
11
|
+
## [1.4.1](https://github.com/semrel-extra/zx-bulk-release/compare/v1.4.0...v1.4.1) (2022-06-21)
|
|
12
|
+
|
|
13
|
+
### Fixes & improvements
|
|
14
|
+
* fix: fix commits refs in release data ([1ddd2e9](https://github.com/semrel-extra/zx-bulk-release/commit/1ddd2e99e88e245bf5d6b477adb6fca0d2c4c663))
|
|
15
|
+
|
|
1
16
|
## [1.4.0](https://github.com/semrel-extra/zx-bulk-release/compare/v1.3.0...v1.4.0) (2022-06-21)
|
|
2
17
|
|
|
3
18
|
### Features
|
package/package.json
CHANGED
package/src/main/js/publish.js
CHANGED
|
@@ -2,8 +2,101 @@ import {formatTag, getLatestTag} from './tag.js'
|
|
|
2
2
|
import {tempy, ctx, fs, path} from 'zx-extra'
|
|
3
3
|
import {copydir} from 'git-glob-cp'
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
5
|
+
export const publish = async (pkg) => {
|
|
6
|
+
await pushTag(pkg)
|
|
7
|
+
await pushMeta(pkg)
|
|
8
|
+
await npmPublish(pkg)
|
|
9
|
+
await createGhRelease(pkg)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const pushTag = (pkg) => ctx(async ($) => {
|
|
13
|
+
const {absPath: cwd, name, version} = pkg
|
|
14
|
+
const tag = formatTag({name, version})
|
|
15
|
+
const {gitCommitterEmail, gitCommitterName} = parseEnv($.env)
|
|
16
|
+
$.cwd = cwd
|
|
17
|
+
|
|
18
|
+
console.log(`push release tag ${tag}`)
|
|
19
|
+
|
|
20
|
+
await $`git config user.name ${gitCommitterName}`
|
|
21
|
+
await $`git config user.email ${gitCommitterEmail}`
|
|
22
|
+
await $`git tag -m ${tag} ${tag}`
|
|
23
|
+
await $`git push origin ${tag}`
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
export const pushMeta = (pkg) => ctx(async ($) => {
|
|
27
|
+
console.log('push artifact to branch `meta`')
|
|
28
|
+
|
|
29
|
+
const cwd = pkg.absPath
|
|
30
|
+
const {name, version} = pkg
|
|
31
|
+
const tag = formatTag({name, version})
|
|
32
|
+
const to = '.'
|
|
33
|
+
const branch = 'meta'
|
|
34
|
+
const msg = `chore: release meta ${name} ${version}`
|
|
35
|
+
|
|
36
|
+
$.cwd = cwd
|
|
37
|
+
const hash = (await $`git rev-parse HEAD`).toString().trim()
|
|
38
|
+
const meta = {
|
|
39
|
+
META_VERSION: '1',
|
|
40
|
+
name: pkg.name,
|
|
41
|
+
hash,
|
|
42
|
+
version: pkg.version,
|
|
43
|
+
dependencies: pkg.dependencies,
|
|
44
|
+
devDependencies: pkg.devDependencies,
|
|
45
|
+
peerDependencies: pkg.peerDependencies,
|
|
46
|
+
optionalDependencies: pkg.optionalDependencies,
|
|
47
|
+
}
|
|
48
|
+
const files = [{relpath: `${getArtifactPath(tag)}.json`, contents: meta}]
|
|
49
|
+
|
|
50
|
+
await push({cwd, to, branch, msg, files})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
export const npmPublish = ({absPath: cwd}) => ctx(async ($) => {
|
|
54
|
+
const {npmRegistry, npmToken, npmConfig} = parseEnv($.env)
|
|
55
|
+
const npmrc = npmConfig ? npmConfig : path.resolve(cwd, '.npmrc')
|
|
56
|
+
|
|
57
|
+
console.log(`publish npm package to ${npmRegistry}`)
|
|
58
|
+
$.cwd = cwd
|
|
59
|
+
if (!npmConfig) {
|
|
60
|
+
await $.raw`echo ${npmRegistry.replace(/https?:/, '')}/:_authToken=${npmToken} >> ${npmrc}`
|
|
61
|
+
}
|
|
62
|
+
await $`npm publish --no-git-tag-version --registry=${npmRegistry} --userconfig ${npmrc} --no-workspaces`
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
export const createGhRelease = (pkg) => ctx(async ($) => {
|
|
66
|
+
console.log('create gh release')
|
|
67
|
+
|
|
68
|
+
const cwd = pkg.absPath
|
|
69
|
+
const {name, version} = pkg
|
|
70
|
+
const {ghUser, ghToken} = parseEnv($.env)
|
|
71
|
+
const {repoName, repoPublicUrl} = await parseRepo(cwd)
|
|
72
|
+
|
|
73
|
+
if (!ghToken || !ghUser) return null
|
|
74
|
+
|
|
75
|
+
const tag = formatTag({name, version})
|
|
76
|
+
const releaseDiffRef = `## [${name}@${version}](${repoPublicUrl}/compare/${pkg.latest.tag?.ref}...${tag}) (${new Date().toISOString().slice(0, 10)})`
|
|
77
|
+
const releaseDetails = Object.values(pkg.changes
|
|
78
|
+
.reduce((acc, {group, subj, short, hash}) => {
|
|
79
|
+
const {commits} = acc[group] || (acc[group] = {commits: [], group})
|
|
80
|
+
const commitRef = `* ${subj}${short ? ` [${short}](${repoPublicUrl}/commit/${hash})` : ''}`
|
|
81
|
+
|
|
82
|
+
commits.push(commitRef)
|
|
83
|
+
|
|
84
|
+
return acc
|
|
85
|
+
}, {}))
|
|
86
|
+
.map(({group, commits}) => `
|
|
87
|
+
### ${group}
|
|
88
|
+
${commits.join('\n')}`).join('\n')
|
|
89
|
+
|
|
90
|
+
const releaseNotes = releaseDiffRef + '\n' + releaseDetails + '\n'
|
|
91
|
+
const releaseData = JSON.stringify({
|
|
92
|
+
name: tag,
|
|
93
|
+
tag_name: tag,
|
|
94
|
+
body: releaseNotes
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
$.cwd = cwd
|
|
98
|
+
await $`curl -u ${ghUser}:${ghToken} -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${repoName}/releases -d ${releaseData}`
|
|
99
|
+
})
|
|
7
100
|
|
|
8
101
|
export const getOrigin = (cwd) => ctx(async ($) => {
|
|
9
102
|
$.cwd = cwd
|
|
@@ -16,6 +109,7 @@ export const getOrigin = (cwd) => ctx(async ($) => {
|
|
|
16
109
|
: originUrl
|
|
17
110
|
})
|
|
18
111
|
|
|
112
|
+
const branches = {}
|
|
19
113
|
export const fetch = async ({cwd: _cwd, branch, origin: _origin}) => ctx(async ($) => {
|
|
20
114
|
let cwd = branches[branch]
|
|
21
115
|
if (cwd) return cwd
|
|
@@ -55,33 +149,6 @@ export const push = async ({cwd, from, to, branch, origin, msg, ignoreFiles, fil
|
|
|
55
149
|
await $.raw`git push origin HEAD:refs/heads/${branch}`
|
|
56
150
|
})
|
|
57
151
|
|
|
58
|
-
export const publish = async (pkg, env) => ctx(async ($) => {
|
|
59
|
-
const {name, version} = pkg.manifest
|
|
60
|
-
const tag = formatTag({name, version})
|
|
61
|
-
const cwd = pkg.absPath
|
|
62
|
-
const {gitCommitterEmail, gitCommitterName, npmRegistry} = parseEnv(env)
|
|
63
|
-
|
|
64
|
-
$.cwd = cwd
|
|
65
|
-
$.env = env
|
|
66
|
-
|
|
67
|
-
console.log(`push release tag ${tag}`)
|
|
68
|
-
await $`git config user.name ${gitCommitterName}`
|
|
69
|
-
await $`git config user.email ${gitCommitterEmail}`
|
|
70
|
-
await $`git tag -m ${tag} ${tag}`
|
|
71
|
-
await $`git push origin ${tag}`
|
|
72
|
-
|
|
73
|
-
console.log('push artifact to branch `meta`')
|
|
74
|
-
await pushMeta(pkg)
|
|
75
|
-
|
|
76
|
-
console.log(`publish npm package to ${npmRegistry}`)
|
|
77
|
-
const npmrc = path.resolve(cwd, '.npmrc')
|
|
78
|
-
await $.raw`echo ${npmRegistry.replace(/https?:/, '')}/:_authToken=${$.env.NPM_TOKEN} >> ${npmrc}`
|
|
79
|
-
await $`npm publish --no-git-tag-version --registry=${npmRegistry} --userconfig ${npmrc} --no-workspaces`
|
|
80
|
-
|
|
81
|
-
console.log('create gh release')
|
|
82
|
-
await createGhRelease(pkg)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
152
|
export const getArtifactPath = (tag) => tag.toLowerCase().replace(/[^a-z0-9-]/g, '-')
|
|
86
153
|
|
|
87
154
|
export const getLatestMeta = async (cwd, tag) => {
|
|
@@ -89,33 +156,15 @@ export const getLatestMeta = async (cwd, tag) => {
|
|
|
89
156
|
|
|
90
157
|
try {
|
|
91
158
|
const _cwd = await fetch({cwd, branch: 'meta'})
|
|
92
|
-
return await
|
|
159
|
+
return await Promise.any([
|
|
160
|
+
fs.readJson(path.resolve(_cwd, `${getArtifactPath(tag)}.json`)),
|
|
161
|
+
fs.readJson(path.resolve(_cwd, getArtifactPath(tag), 'meta.json'))
|
|
162
|
+
])
|
|
93
163
|
} catch {}
|
|
94
164
|
|
|
95
165
|
return null
|
|
96
166
|
}
|
|
97
167
|
|
|
98
|
-
export const pushMeta = async (pkg) => {
|
|
99
|
-
const cwd = pkg.absPath
|
|
100
|
-
const {name, version} = pkg
|
|
101
|
-
const tag = formatTag({name, version})
|
|
102
|
-
const to = getArtifactPath(tag)
|
|
103
|
-
const branch = 'meta'
|
|
104
|
-
const msg = `chore: release meta ${name} ${version}`
|
|
105
|
-
const meta = {
|
|
106
|
-
META_VERSION,
|
|
107
|
-
name: pkg.name,
|
|
108
|
-
version: pkg.version,
|
|
109
|
-
dependencies: pkg.dependencies,
|
|
110
|
-
devDependencies: pkg.devDependencies,
|
|
111
|
-
peerDependencies: pkg.peerDependencies,
|
|
112
|
-
optionalDependencies: pkg.optionalDependencies,
|
|
113
|
-
}
|
|
114
|
-
const files = [{relpath: 'meta.json', contents: meta}]
|
|
115
|
-
|
|
116
|
-
await push({cwd, to, branch, msg, files})
|
|
117
|
-
}
|
|
118
|
-
|
|
119
168
|
export const getLatest = async (cwd, name) => {
|
|
120
169
|
const tag = await getLatestTag(cwd, name)
|
|
121
170
|
const meta = await getLatestMeta(cwd, tag?.ref)
|
|
@@ -127,11 +176,12 @@ export const getLatest = async (cwd, name) => {
|
|
|
127
176
|
}
|
|
128
177
|
|
|
129
178
|
export const parseEnv = (env = process.env) => {
|
|
130
|
-
const {GH_USER, GH_USERNAME, GITHUB_USER, GITHUB_USERNAME, GH_TOKEN, GITHUB_TOKEN, NPM_TOKEN, NPM_REGISTRY, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL} = env
|
|
179
|
+
const {GH_USER, GH_USERNAME, GITHUB_USER, GITHUB_USERNAME, GH_TOKEN, GITHUB_TOKEN, NPM_TOKEN, NPM_REGISTRY, NPMRC, NPM_USERCONFIG, NPM_CONFIG_USERCONFIG, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL} = env
|
|
131
180
|
|
|
132
181
|
return {
|
|
133
182
|
ghUser: GH_USER || GH_USERNAME || GITHUB_USER || GITHUB_USERNAME,
|
|
134
183
|
ghToken: GH_TOKEN || GITHUB_TOKEN,
|
|
184
|
+
npmConfig: NPMRC || NPM_USERCONFIG || NPM_CONFIG_USERCONFIG,
|
|
135
185
|
npmToken: NPM_TOKEN,
|
|
136
186
|
npmRegistry: NPM_REGISTRY || 'https://registry.npmjs.org',
|
|
137
187
|
gitCommitterName: GIT_COMMITTER_NAME || 'Semrel Extra Bot',
|
|
@@ -151,37 +201,3 @@ export const parseRepo = (cwd, origin) => ctx(async ($) => {
|
|
|
151
201
|
repoPublicUrl
|
|
152
202
|
}
|
|
153
203
|
})
|
|
154
|
-
|
|
155
|
-
export const createGhRelease = (pkg) => ctx(async ($) => {
|
|
156
|
-
const cwd = pkg.absPath
|
|
157
|
-
const {name, version} = pkg
|
|
158
|
-
const {ghUser, ghToken} = parseEnv($.env)
|
|
159
|
-
const {repoName, repoPublicUrl} = await parseRepo(cwd)
|
|
160
|
-
|
|
161
|
-
if (!ghToken || !ghUser) return null
|
|
162
|
-
|
|
163
|
-
const tag = formatTag({name, version})
|
|
164
|
-
const releaseDiffRef = `## [${name}@${version}](${repoPublicUrl}/compare/${pkg.latest.tag?.ref}...${tag}) (${new Date().toISOString().slice(0, 10)})`
|
|
165
|
-
const releaseDetails = Object.values(pkg.changes
|
|
166
|
-
.reduce((acc, {group, change, short, hash}) => {
|
|
167
|
-
const {commits} = acc[group] || (acc[group] = {commits: [], group})
|
|
168
|
-
const commitRef = `* ${change} ([${short}](${repoPublicUrl}/commit/${hash}))`
|
|
169
|
-
|
|
170
|
-
commits.push(commitRef)
|
|
171
|
-
|
|
172
|
-
return acc
|
|
173
|
-
}, {}))
|
|
174
|
-
.map(({group, commits}) => `
|
|
175
|
-
### ${group}
|
|
176
|
-
${commits.join('\n')}`).join('\n')
|
|
177
|
-
|
|
178
|
-
const releaseNotes = releaseDiffRef + '\n' + releaseDetails + '\n'
|
|
179
|
-
const releaseData = JSON.stringify({
|
|
180
|
-
name: tag,
|
|
181
|
-
tag_name: tag,
|
|
182
|
-
body: releaseNotes
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
$.cwd = cwd
|
|
186
|
-
await $`curl -u ${ghUser}:${ghToken} -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${repoName}/releases -d ${releaseData}`
|
|
187
|
-
})
|
|
@@ -121,7 +121,7 @@ test('run()', async () => {
|
|
|
121
121
|
const meta = tempy.temporaryDirectory()
|
|
122
122
|
|
|
123
123
|
await $`git clone --single-branch --branch meta --depth 1 ${origin} ${meta}`
|
|
124
|
-
assert.is((await fs.readJson(`${meta}/${tag.toLowerCase().replace(/[^a-z0-9-]/g, '-')}
|
|
124
|
+
assert.is((await fs.readJson(`${meta}/${tag.toLowerCase().replace(/[^a-z0-9-]/g, '-')}.json`)).version, '1.0.1')
|
|
125
125
|
})
|
|
126
126
|
|
|
127
127
|
await registry.stop()
|