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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zx-bulk-release",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "zx-based alternative for multi-semantic-release",
5
5
  "type": "module",
6
6
  "exports": "./src/main/js/index.js",
@@ -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 branches = {}
6
- const META_VERSION = '1'
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 fs.readJson(path.resolve(_cwd, getArtifactPath(tag), 'meta.json'))
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, '-')}/meta.json`)).version, '1.0.1')
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()