zx-bulk-release 2.12.1 → 2.13.0-beta.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,9 @@
1
+ ## [2.12.2](https://github.com/semrel-extra/zx-bulk-release/compare/v2.12.1...v2.12.2) (2023-11-20)
2
+
3
+ ### Fixes & improvements
4
+ * fix: fetch latest npm manifest by default ([e7e6c0d](https://github.com/semrel-extra/zx-bulk-release/commit/e7e6c0dfe0aef34c0cf6a6936cca1057aef8c746))
5
+ * fix: fix `pure` tag parser ([41b961d](https://github.com/semrel-extra/zx-bulk-release/commit/41b961d7eed99061fcc851b7b8ed7fc72813ef46))
6
+
1
7
  ## [2.12.1](https://github.com/semrel-extra/zx-bulk-release/compare/v2.12.0...v2.12.1) (2023-11-02)
2
8
 
3
9
  ### Fixes & improvements
package/README.md CHANGED
@@ -25,8 +25,8 @@
25
25
  * macOS / linux
26
26
  * Node.js >= 16.0.0
27
27
  * npm >=7 / yarn >= 3
28
- * wget
29
- * tar
28
+ * ~~wget~~
29
+ * ~~tar~~
30
30
  * git
31
31
 
32
32
  ## Usage
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zx-bulk-release",
3
3
  "alias": "bulk-release",
4
- "version": "2.12.1",
4
+ "version": "2.13.0-beta.0",
5
5
  "description": "zx-based alternative for multi-semantic-release",
6
6
  "type": "module",
7
7
  "exports": {
@@ -20,18 +20,20 @@
20
20
  "scripts": {
21
21
  "test": "NPM_REGISTRY='http://localhost:4873' NPM_TOKEN='mRv6eIuiaggXGb9ZDFCtBA==' c8 uvu ./src/test -i fixtures -i utils && c8 report -r lcov",
22
22
  "test:it": "NPM_REGISTRY='http://localhost:4873' NPM_TOKEN='mRv6eIuiaggXGb9ZDFCtBA==' node ./src/test/js/integration.test.js",
23
- "docs": "mkdir -p docs && cp ./README.md ./docs/README.md"
23
+ "docs": "mkdir -p docs && cp ./README.md ./docs/README.md",
24
+ "publish:beta": "npm publish --tag beta --no-git-tag-version"
24
25
  },
25
26
  "dependencies": {
26
27
  "@semrel-extra/topo": "^1.14.0",
27
28
  "cosmiconfig": "^8.3.6",
28
29
  "queuefy": "^1.2.1",
29
- "zx-extra": "^2.5.5"
30
+ "tar-stream": "^3.1.6",
31
+ "zx-extra": "^2.6.4"
30
32
  },
31
33
  "devDependencies": {
32
34
  "c8": "^8.0.1",
33
35
  "uvu": "^0.5.6",
34
- "verdaccio": "^5.26.3"
36
+ "verdaccio": "^5.27.0"
35
37
  },
36
38
  "publishConfig": {
37
39
  "access": "public"
package/src/main/js/gh.js CHANGED
@@ -23,8 +23,15 @@ export const ghRelease = async (pkg) => {
23
23
  body: releaseNotes
24
24
  })
25
25
 
26
- const {stdout} = await $.o({cwd})`curl -H 'Authorization: token ${ghToken}' -H 'Accept: application/vnd.github.v3+json' https://api.github.com/repos/${repoName}/releases -d ${releaseData}`
27
- const res = JSON.parse(stdout.toString().trim())
26
+ const res = await (await fetch(`https://api.github.com/repos/${repoName}/releases`, {
27
+ method: 'POST',
28
+ headers: {
29
+ Accept: 'application/vnd.github.v3+json',
30
+ Authorization: `token ${ghToken}`,
31
+ 'X-GitHub-Api-Version': '2022-11-28'
32
+ },
33
+ body: releaseData
34
+ })).json()
28
35
 
29
36
  if (ghAssets) {
30
37
  // Lol. GH API literally returns pseudourl `...releases/110103594/assets{?name,label}` as shown in the docs
@@ -86,7 +93,17 @@ export const ghUploadAssets = async ({ghToken, ghAssets, uploadUrl, cwd}) => {
86
93
 
87
94
  return Promise.all(ghAssets.map(async ({name}) => {
88
95
  const url = `${uploadUrl}?name=${name}`
89
- return $.o({cwd: temp})`curl -H 'Authorization: token ${ghToken}' -H 'Accept: application/vnd.github.v3+json' -H 'Content-Type: application/octet-stream' ${url} --data-binary '@${name}'`
96
+ // return $.o({cwd: temp})`curl -H 'Authorization: token ${ghToken}' -H 'Accept: application/vnd.github.v3+json' -H 'Content-Type: application/octet-stream' ${url} --data-binary '@${name}'`
97
+ return fetch(url, {
98
+ method: 'POST',
99
+ headers: {
100
+ 'Content-Type': 'application/octet-stream',
101
+ Accept: 'application/vnd.github.v3+json',
102
+ Authorization: `token ${ghToken}`,
103
+ 'X-GitHub-Api-Version': '2022-11-28'
104
+ },
105
+ body: await fs.readFile(path.join(temp, name))
106
+ })
90
107
  }))
91
108
  }
92
109
 
@@ -136,7 +136,7 @@ const pure = {
136
136
  }
137
137
 
138
138
  const [n, o = ''] = prerelease.reverse()
139
- const name = o === 'x' ? n : `@${o}/${n}`
139
+ const name = (!o || o === 'x') ? n : `@${o}/${n}`
140
140
  const version = tag.slice(0, -1 - n.length - (o ? o.length + 1 : 0))
141
141
 
142
142
  return {format: this.name, ref: tag, name, version}
@@ -1,5 +1,8 @@
1
1
  import {log} from './log.js'
2
2
  import {$, fs, INI, fetch, tempy} from 'zx-extra'
3
+ import {unzip} from './util.js'
4
+
5
+ // https://stackoverflow.com/questions/19978452/how-to-extract-single-file-from-tar-gz-archive-using-node-js
3
6
 
4
7
  export const fetchPkg = async (pkg) => {
5
8
  const id = `${pkg.name}@${pkg.version}`
@@ -10,9 +13,20 @@ export const fetchPkg = async (pkg) => {
10
13
  const {npmRegistry, npmToken, npmConfig} = pkg.config
11
14
  const tarballUrl = getTarballUrl(npmRegistry, pkg.name, pkg.version)
12
15
  const bearerToken = getBearerToken(npmRegistry, npmToken, npmConfig)
13
- const authorization = bearerToken ? `--header='Authorization: ${bearerToken}'` : ''
16
+ const headers = bearerToken ? {Authorization: bearerToken} : {}
14
17
  log({pkg})(`fetching '${id}' from ${npmRegistry}`)
15
- await $.raw`wget --timeout=15 --connect-timeout=5 ${authorization} -qO- ${tarballUrl} | tar -xvz --strip-components=1 --exclude='package.json' -C ${cwd}`
18
+
19
+ // https://stackoverflow.com/questions/46946380/fetch-api-request-timeout
20
+ const controller = new AbortController()
21
+ const timeoutId = setTimeout(() => controller.abort(), 15_000)
22
+ const tarball = await fetch(tarballUrl, {
23
+ method: 'GET',
24
+ headers,
25
+ signal: controller.signal
26
+ })
27
+ clearTimeout(timeoutId)
28
+
29
+ await unzip(tarball.body, {cwd, strip: 1, omit: ['package.json']})
16
30
 
17
31
  log({pkg})(`fetch duration '${id}': ${Date.now() - now}`)
18
32
  pkg.fetched = true
@@ -24,7 +38,7 @@ export const fetchPkg = async (pkg) => {
24
38
  export const fetchManifest = async (pkg, {nothrow} = {}) => {
25
39
  const {npmRegistry, npmToken, npmConfig} = pkg.config
26
40
  const bearerToken = getBearerToken(npmRegistry, npmToken, npmConfig)
27
- const url = getManifestUrl(npmRegistry, pkg.name, pkg.version)
41
+ const url = getManifestUrl(npmRegistry, pkg.name, pkg.version || 'latest')
28
42
  const reqOpts = bearerToken ? {headers: {authorization: bearerToken}} : {}
29
43
 
30
44
  try {
@@ -1,3 +1,8 @@
1
+ import zlib from 'node:zlib'
2
+ import fs from 'node:fs/promises'
3
+ import path from 'node:path'
4
+ import tar from 'tar-stream'
5
+
1
6
  export const tpl = (str, context) =>
2
7
  str?.replace(/\$\{\{\s*([.a-z0-9]+)\s*}}/gi, (matched, key) => get(context, key) ?? '')
3
8
 
@@ -60,3 +65,50 @@ export const getCommonPath = files => {
60
65
 
61
66
  return p.slice(0, p.lastIndexOf('/') + 1)
62
67
  }
68
+
69
+ // https://stackoverflow.com/questions/19978452/how-to-extract-single-file-from-tar-gz-archive-using-node-js
70
+ export const unzip = (stream, {pick, omit, cwd = process.cwd(), strip = 0} = {}) => new Promise((resolve, reject) => {
71
+ const extract = tar.extract()
72
+ const results = []
73
+
74
+ extract.on('entry', ({name, type}, stream, cb)=> {
75
+ const _name = strip ? name.split('/').slice(strip).join('/') : name
76
+ const fp = path.join(cwd, _name)
77
+
78
+ let data = ''
79
+ stream.on('data', (chunk) => {
80
+ if (type !== 'file') {
81
+ return
82
+ }
83
+ if (omit?.includes(_name)) {
84
+ return
85
+ }
86
+ if (pick && !pick.includes(_name)) {
87
+ return
88
+ }
89
+
90
+ data +=chunk
91
+ })
92
+
93
+ stream.on('end', () => {
94
+ if (data) {
95
+ results.push(
96
+ fs.mkdir(path.dirname(fp), {recursive: true})
97
+ .then(() => fs.writeFile(fp, data, 'utf8'))
98
+ )
99
+ }
100
+ cb()
101
+ })
102
+
103
+ stream.resume()
104
+ })
105
+
106
+ extract.on('finish', ()=> {
107
+ resolve(Promise.all(results))
108
+ })
109
+
110
+ // fs.createReadStream('archive.tar.gz')
111
+ stream
112
+ .pipe(zlib.createGunzip())
113
+ .pipe(extract)
114
+ })