zx-bulk-release 3.0.2 → 3.0.4

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,13 @@
1
+ ## [3.0.4](https://github.com/semrel-extra/zx-bulk-release/compare/v3.0.3...v3.0.4) (2026-04-11)
2
+
3
+ ### Fixes & improvements
4
+ * docs: update gh action examples ([0511f95](https://github.com/semrel-extra/zx-bulk-release/commit/0511f95d62999c8f9a1b42562307a71f8b62c698))
5
+
6
+ ## [3.0.3](https://github.com/semrel-extra/zx-bulk-release/compare/v3.0.2...v3.0.3) (2026-04-11)
7
+
8
+ ### Fixes & improvements
9
+ * fix: fallback ghApiUrl from config ([ac56cb0](https://github.com/semrel-extra/zx-bulk-release/commit/ac56cb014dea0bea9d3c352dd44900a0647e058f))
10
+
1
11
  ## [3.0.2](https://github.com/semrel-extra/zx-bulk-release/compare/v3.0.1...v3.0.2) (2026-04-11)
2
12
 
3
13
  ### Fixes & improvements
package/README.md CHANGED
@@ -63,7 +63,6 @@ GH_TOKEN=ghtoken GH_USER=username NPM_TOKEN=npmtoken npx zx-bulk-release [opts]
63
63
  By default, zbr runs the full pipeline in a single process. For better security isolation, split build and delivery into separate CI jobs:
64
64
 
65
65
  ```yaml
66
- # Job 1: build (minimal privileges — source code access only)
67
66
  jobs:
68
67
  pack:
69
68
  runs-on: ubuntu-latest
@@ -72,20 +71,27 @@ jobs:
72
71
  with: { fetch-depth: 0 }
73
72
  - run: npx zx-bulk-release --pack
74
73
  - uses: actions/upload-artifact@v4
75
- with: { name: parcels, path: parcels, retention-days: 1 }
74
+ with:
75
+ name: parcels
76
+ path: parcels
77
+ retention-days: 1
78
+ if-no-files-found: ignore
76
79
 
77
- # Job 2: deliver (only delivery credentials, no source code)
78
80
  deliver:
79
81
  needs: pack
80
82
  runs-on: ubuntu-latest
81
83
  steps:
82
84
  - uses: actions/download-artifact@v4
85
+ id: download
83
86
  with: { name: parcels, path: parcels }
84
- - run: npx zx-bulk-release --deliver
87
+ continue-on-error: true
88
+ - if: steps.download.outcome == 'success'
89
+ run: npx zx-bulk-release --deliver
85
90
  env:
86
91
  GH_TOKEN: ${{ secrets.GH_TOKEN }}
87
92
  NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
88
- - uses: actions/upload-artifact@v4
93
+ - if: steps.download.outcome == 'success'
94
+ uses: actions/upload-artifact@v4
89
95
  with: { name: parcels, path: parcels, overwrite: true, retention-days: 1 }
90
96
  ```
91
97
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zx-bulk-release",
3
3
  "alias": "bulk-release",
4
- "version": "3.0.2",
4
+ "version": "3.0.4",
5
5
  "description": "zx-based alternative for multi-semantic-release",
6
6
  "type": "module",
7
7
  "exports": {
@@ -1,5 +1,6 @@
1
1
  import { cosmiconfig } from 'cosmiconfig'
2
2
  import { asArray, camelize, memoizeBy } from './util.js'
3
+ import { GH_URL, resolveGhApiUrl } from './post/api/gh.js'
3
4
 
4
5
  const CONFIG_NAME = 'release'
5
6
  const CONFIG_FILES = [
@@ -58,11 +59,6 @@ export const normalizeMetaConfig = (meta) =>
58
59
  ? { type: meta } // 'commit' | 'asset' | 'tag'
59
60
  : { type: null }
60
61
 
61
- export const GH_URL = 'https://github.com'
62
-
63
- const resolveGhApiUrl = (ghUrl) =>
64
- ghUrl === GH_URL ? 'https://api.github.com' : `${ghUrl.replace(/\/$/, '')}/api/v3`
65
-
66
62
  export const parseEnv = ({GH_USER, GH_USERNAME, GH_META, GH_URL: _GH_URL, GITHUB_URL, GITHUB_USER, GITHUB_USERNAME, GH_TOKEN, GITHUB_TOKEN, NPM_TOKEN, NPM_REGISTRY, NPMRC, NPM_USERCONFIG, NPM_CONFIG_USERCONFIG, NPM_PROVENANCE, NPM_OIDC, ACTIONS_ID_TOKEN_REQUEST_URL, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL} = process.env) => {
67
63
  const ghUrl = _GH_URL || GITHUB_URL || GH_URL
68
64
  return {
@@ -3,6 +3,15 @@
3
3
  import {$, path, tempy, glob, fs, fetch} from 'zx-extra'
4
4
  import {asArray, attempt2} from '../../util.js'
5
5
 
6
+ export const GH_URL = 'https://github.com'
7
+ export const GH_API_URL = 'https://api.github.com'
8
+ export const GH_API_VERSION = '2022-11-28'
9
+ export const GH_ACCEPT = 'application/vnd.github.v3+json'
10
+
11
+ export const resolveGhApiUrl = (ghUrl) =>
12
+ ghUrl === GH_URL ? GH_API_URL : new URL('/api/v3', ghUrl).href
13
+
14
+
6
15
  export const getCommonPath = files => {
7
16
  const f0 = files[0]
8
17
  const common = files.length === 1
@@ -12,9 +21,6 @@ export const getCommonPath = files => {
12
21
  return p.endsWith('/') ? p : p.slice(0, p.lastIndexOf('/') + 1)
13
22
  }
14
23
 
15
- export const GH_API_VERSION = '2022-11-28'
16
- export const GH_ACCEPT = 'application/vnd.github.v3+json'
17
-
18
24
  export const ghFetch = (url, {ghToken, method = 'GET', headers, body} = {}) => fetch(url, {
19
25
  method,
20
26
  headers: {
@@ -75,7 +81,7 @@ export const ghPrepareAssets = async (assets, _cwd) => {
75
81
  }
76
82
 
77
83
  export const ghGetAsset = async ({repoName, tag, name, ghUrl}) => {
78
- const url = `${ghUrl || 'https://github.com'}/${repoName}/releases/download/${tag.ref || tag}/${name}`
84
+ const url = `${ghUrl}/${repoName}/releases/download/${tag.ref || tag}/${name}`
79
85
  const res = await attempt2(() => fetch(url))
80
86
  if (!res.ok) {
81
87
  throw new Error(`gh asset fetch failed for '${name}': ${res.status} ${url}`)
@@ -6,7 +6,7 @@ export const isNpmPublished = (pkg) =>
6
6
 
7
7
  export default {
8
8
  name: 'npm',
9
- requires: ['token'],
9
+ requires: (manifest) => manifest.oidc ? [] : ['token'],
10
10
  when: isNpmPublished,
11
11
  run: (manifest, dir) => npmPublish({
12
12
  name: manifest.name,
@@ -49,7 +49,8 @@ const openParcel = async (tarPath, env) => {
49
49
 
50
50
  if (!ch) return {warn: `unknown channel '${resolved.channel || '<none>'}'`}
51
51
 
52
- const missing = (ch.requires || []).filter(f => !resolved[f])
52
+ const reqs = typeof ch.requires === 'function' ? ch.requires(resolved) : (ch.requires || [])
53
+ const missing = reqs.filter(f => !resolved[f])
53
54
  if (missing.length) return {warn: `missing credentials — ${missing.join(', ')}`, tarPath}
54
55
 
55
56
  return {ch, resolved, destDir, tarPath}
@@ -24,8 +24,8 @@ const entry = {
24
24
  channel: 'gh-release',
25
25
  manifest: {
26
26
  channel: 'gh-release',
27
- tag: pkg.tag, repoName: a.repoName, releaseNotes: a.releaseNotes,
28
- token: '${{GH_TOKEN}}', apiUrl: '${{GH_API_URL}}',
27
+ tag: pkg.tag, repoHost: a.repoHost, repoName: a.repoName, releaseNotes: a.releaseNotes,
28
+ token: '${{GH_TOKEN}}', apiUrl: pkg.config.ghApiUrl,
29
29
  assets: pkg.config.ghAssets ? [...pkg.config.ghAssets] : undefined,
30
30
  },
31
31
  files: a.assetsDir ? [{name: 'assets', source: a.assetsDir}] : [],
@@ -31,7 +31,10 @@ export const run = async ({cwd = process.cwd(), env, flags = {}} = {}) => within
31
31
  if (flags.deliver) {
32
32
  const dir = typeof flags.deliver === 'string' ? flags.deliver : PARCELS_DIR
33
33
  const tars = await glob(path.join(dir, 'parcel.*.tar'))
34
- if (!tars.length) throw new Error(`no tars found in ${dir}`)
34
+ if (!tars.length) {
35
+ log.info(`deliver: no parcels in ${dir}, nothing to do`)
36
+ return
37
+ }
35
38
  const _env = {...process.env, ...env}
36
39
  log.secret(_env.GH_TOKEN, _env.GITHUB_TOKEN, _env.NPM_TOKEN)
37
40
  log.info(`deliver: ${tars.length} tar(s) from ${dir}`)
@@ -86,6 +86,7 @@ export const makePkg = (overrides = {}) => ({
86
86
  gitCommitterEmail: 'bot@test.com',
87
87
  ghBasicAuth: 'x-access-token:ghp_test',
88
88
  ghToken: 'ghp_test',
89
+ ghApiUrl: 'https://api.github.com',
89
90
  npmPublish: true,
90
91
  npmFetch: false,
91
92
  changelog: 'changelog',