bulk-release 2.20.0 → 2.21.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 +20 -0
- package/README.md +47 -74
- package/package.json +3 -3
- package/src/main/js/index.js +0 -6
- package/src/main/js/processor/api/gh.js +111 -0
- package/src/main/js/{api → processor/api}/git.js +17 -26
- package/src/main/js/{api → processor/api}/npm.js +70 -28
- package/src/main/js/processor/deps.js +1 -1
- package/src/main/js/processor/exec.js +4 -4
- package/src/main/js/processor/generators/meta.js +80 -0
- package/src/main/js/{api/changelog.js → processor/generators/notes.js} +3 -21
- package/src/main/js/processor/{meta.js → generators/tag.js} +3 -109
- package/src/main/js/processor/log.js +86 -0
- package/src/main/js/processor/publishers/changelog.js +26 -0
- package/src/main/js/processor/publishers/cmd.js +6 -0
- package/src/main/js/processor/publishers/gh-pages.js +32 -0
- package/src/main/js/processor/publishers/gh-release.js +41 -0
- package/src/main/js/processor/publishers/meta.js +58 -0
- package/src/main/js/processor/publishers/npm.js +15 -0
- package/src/main/js/processor/release.js +71 -66
- package/src/main/js/{steps → processor/steps}/analyze.js +18 -24
- package/src/main/js/processor/steps/build.js +20 -0
- package/src/main/js/processor/steps/clean.js +7 -0
- package/src/main/js/processor/steps/contextify.js +49 -0
- package/src/main/js/processor/steps/publish.js +39 -0
- package/src/main/js/processor/steps/teardown.js +58 -0
- package/src/main/js/processor/steps/test.js +10 -0
- package/src/main/js/util.js +32 -77
- package/src/main/js/api/gh.js +0 -131
- package/src/main/js/log.js +0 -63
- package/src/main/js/steps/build.js +0 -23
- package/src/main/js/steps/clean.js +0 -7
- package/src/main/js/steps/contextify.js +0 -154
- package/src/main/js/steps/publish.js +0 -47
- package/src/main/js/steps/test.js +0 -16
package/src/main/js/api/gh.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import {queuefy} from 'queuefy'
|
|
2
|
-
import {$, path, tempy, glob, fs, fetch} from 'zx-extra'
|
|
3
|
-
import {log} from '../log.js'
|
|
4
|
-
import {getRepo, pushCommit} from './git.js'
|
|
5
|
-
import {formatTag} from '../processor/meta.js'
|
|
6
|
-
import {formatReleaseNotes} from './changelog.js'
|
|
7
|
-
import {asArray, getCommonPath, msgJoin} from '../util.js'
|
|
8
|
-
|
|
9
|
-
// https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release
|
|
10
|
-
export const ghRelease = async (pkg) => {
|
|
11
|
-
const {ghBasicAuth: basicAuth, ghToken, ghAssets, ghApiUrl} = pkg.config
|
|
12
|
-
if (!ghToken) return null
|
|
13
|
-
|
|
14
|
-
log({pkg})('create gh release')
|
|
15
|
-
|
|
16
|
-
const now = Date.now()
|
|
17
|
-
const {name, version, absPath: cwd, tag = formatTag({name, version})} = pkg
|
|
18
|
-
const {repoName} = await getRepo(cwd, {basicAuth})
|
|
19
|
-
const releaseNotes = await formatReleaseNotes(pkg)
|
|
20
|
-
const releaseData = JSON.stringify({
|
|
21
|
-
name: tag,
|
|
22
|
-
tag_name: tag,
|
|
23
|
-
body: releaseNotes
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
const res = await (await fetch(`${ghApiUrl}/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()
|
|
35
|
-
|
|
36
|
-
if (!res.upload_url) {
|
|
37
|
-
throw new Error(`gh release failed: ${JSON.stringify(res)}`)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (ghAssets?.length) {
|
|
41
|
-
// Lol. GH API literally returns pseudourl `...releases/110103594/assets{?name,label}` as shown in the docs
|
|
42
|
-
const uploadUrl = res.upload_url.slice(0, res.upload_url.indexOf('{'))
|
|
43
|
-
await ghUploadAssets({ghToken, ghAssets, uploadUrl, cwd})
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
log({pkg})(`duration gh release: ${Date.now() - now}`)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export const ghPages = queuefy(async (pkg) => {
|
|
50
|
-
const {config: {ghPages: opts, gitCommitterEmail, gitCommitterName, ghBasicAuth: basicAuth}} = pkg
|
|
51
|
-
if (!opts) return
|
|
52
|
-
|
|
53
|
-
const [branch = 'gh-pages', from = 'docs', to = '.', ..._msg] = typeof opts === 'string'
|
|
54
|
-
? opts.split(' ')
|
|
55
|
-
: [opts.branch, opts.from, opts.to, opts.msg]
|
|
56
|
-
const msg = msgJoin(_msg, pkg, 'docs: update docs ${{name}} ${{version}}')
|
|
57
|
-
|
|
58
|
-
log({pkg})(`publish docs to ${branch}`)
|
|
59
|
-
|
|
60
|
-
await pushCommit({
|
|
61
|
-
cwd: path.join(pkg.absPath, from),
|
|
62
|
-
from: '.',
|
|
63
|
-
to,
|
|
64
|
-
branch,
|
|
65
|
-
msg,
|
|
66
|
-
gitCommitterEmail,
|
|
67
|
-
gitCommitterName,
|
|
68
|
-
basicAuth
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
// https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#upload-a-release-asset8
|
|
73
|
-
export const ghPrepareAssets = async (assets, _cwd) => {
|
|
74
|
-
const temp = tempy.temporaryDirectory()
|
|
75
|
-
|
|
76
|
-
await Promise.all(assets.map(async ({name, contents, source = 'target/**/*', zip, cwd = _cwd, strip = true}) => {
|
|
77
|
-
const target = path.join(temp, name)
|
|
78
|
-
|
|
79
|
-
if (contents) {
|
|
80
|
-
await fs.outputFile(target, contents, 'utf8')
|
|
81
|
-
return
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const patterns = asArray(source)
|
|
85
|
-
if (patterns.some(s => s.includes('*'))) {
|
|
86
|
-
zip = true
|
|
87
|
-
}
|
|
88
|
-
const files = await glob(patterns, {cwd, absolute: false, onlyFiles: true})
|
|
89
|
-
|
|
90
|
-
if (files.length === 0) {
|
|
91
|
-
throw new Error(`gh asset not found: ${name} ${source}`)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!zip && files.length === 1) {
|
|
95
|
-
await fs.copy(path.join(cwd, files[0]), target)
|
|
96
|
-
return
|
|
97
|
-
}
|
|
98
|
-
const prefix = getCommonPath(files)
|
|
99
|
-
|
|
100
|
-
return $.raw`tar -C ${path.join(cwd, prefix)} -cv${zip ? 'z' : ''}f ${target} ${files.map(f => f.slice(prefix.length)).join(' ')}`
|
|
101
|
-
}))
|
|
102
|
-
|
|
103
|
-
return temp
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export const ghUploadAssets = async ({ghToken, ghAssets, uploadUrl, cwd}) => {
|
|
107
|
-
const temp = await ghPrepareAssets(ghAssets, cwd)
|
|
108
|
-
|
|
109
|
-
return Promise.all(ghAssets.map(async ({name}) => {
|
|
110
|
-
const url = `${uploadUrl}?name=${name}`
|
|
111
|
-
// 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}'`
|
|
112
|
-
return fetch(url, {
|
|
113
|
-
method: 'POST',
|
|
114
|
-
headers: {
|
|
115
|
-
'Content-Type': 'application/octet-stream',
|
|
116
|
-
Accept: 'application/vnd.github.v3+json',
|
|
117
|
-
Authorization: `token ${ghToken}`,
|
|
118
|
-
'X-GitHub-Api-Version': '2022-11-28'
|
|
119
|
-
},
|
|
120
|
-
body: await fs.readFile(path.join(temp, name))
|
|
121
|
-
})
|
|
122
|
-
}))
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export const ghGetAsset = async ({repoName, tag, name, ghUrl}) => {
|
|
126
|
-
return (await fetch(`${ghUrl || 'https://github.com'}/${repoName}/releases/download/${tag.ref || tag}/${name}`, {
|
|
127
|
-
headers: {
|
|
128
|
-
// Accept: 'application/vnd.github.v3+json'
|
|
129
|
-
}
|
|
130
|
-
})).text()
|
|
131
|
-
}
|
package/src/main/js/log.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import {$, fs} from 'zx-extra'
|
|
2
|
-
import {get, set, tpl} from './util.js'
|
|
3
|
-
|
|
4
|
-
export const log = (ctx) =>
|
|
5
|
-
$.report
|
|
6
|
-
? $.report.log(ctx)
|
|
7
|
-
: console.log
|
|
8
|
-
|
|
9
|
-
export const createReport = ({logger = console, packages = {}, queue = [], flags} = {}) => ({
|
|
10
|
-
logger,
|
|
11
|
-
flags,
|
|
12
|
-
file: flags.report || flags.file,
|
|
13
|
-
status: 'initial',
|
|
14
|
-
events: [],
|
|
15
|
-
queue,
|
|
16
|
-
packages: Object.entries(packages).reduce((acc, [name, {manifest: {version}, absPath, relPath}]) => {
|
|
17
|
-
acc[name] = {
|
|
18
|
-
status: 'initial',
|
|
19
|
-
name,
|
|
20
|
-
version,
|
|
21
|
-
path: absPath,
|
|
22
|
-
relPath
|
|
23
|
-
}
|
|
24
|
-
return acc
|
|
25
|
-
}, {}),
|
|
26
|
-
get(key, pkgName) {
|
|
27
|
-
return get(
|
|
28
|
-
pkgName ? this.packages[pkgName] : this,
|
|
29
|
-
key
|
|
30
|
-
)
|
|
31
|
-
},
|
|
32
|
-
set(key, value, pkgName) {
|
|
33
|
-
set(
|
|
34
|
-
pkgName ? this.packages[pkgName] : this,
|
|
35
|
-
key,
|
|
36
|
-
value
|
|
37
|
-
)
|
|
38
|
-
return this
|
|
39
|
-
},
|
|
40
|
-
setStatus(status, name) {
|
|
41
|
-
this.set('status', status, name)
|
|
42
|
-
this.save()
|
|
43
|
-
return this
|
|
44
|
-
},
|
|
45
|
-
getStatus(status, name) {
|
|
46
|
-
return this.get('status', name)
|
|
47
|
-
},
|
|
48
|
-
log(ctx = {}) {
|
|
49
|
-
return function (...chunks) {
|
|
50
|
-
const {pkg, scope = pkg?.name || $.scope || '~', level = 'info'} = ctx
|
|
51
|
-
const msg = chunks.map(c => typeof c === 'string' ? tpl(c, ctx) : c)
|
|
52
|
-
const event = {msg, scope, date: Date.now(), level}
|
|
53
|
-
this.events.push(event)
|
|
54
|
-
logger[level](`[${scope}]`, ...msg)
|
|
55
|
-
|
|
56
|
-
return this
|
|
57
|
-
}.bind(this)
|
|
58
|
-
},
|
|
59
|
-
save() {
|
|
60
|
-
this.file && fs.outputJsonSync(this.file, this)
|
|
61
|
-
return this
|
|
62
|
-
}
|
|
63
|
-
})
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import {memoizeBy} from '../util.js'
|
|
2
|
-
import {$, within} from 'zx-extra'
|
|
3
|
-
import {fetchPkg} from '../api/npm.js'
|
|
4
|
-
import {traverseDeps} from '../processor/deps.js'
|
|
5
|
-
import {exec} from '../processor/exec.js'
|
|
6
|
-
|
|
7
|
-
export const build = memoizeBy(async (pkg, run = exec, flags = {}, self = build) => within(async () => {
|
|
8
|
-
$.scope = pkg.name
|
|
9
|
-
|
|
10
|
-
await Promise.all([
|
|
11
|
-
traverseDeps({pkg, packages: pkg.context.packages, cb: async({pkg}) => self(pkg, run, flags, self)}),
|
|
12
|
-
pkg.manifest.private !== true && pkg.changes.length === 0 && pkg.config.npmFetch && flags.npmFetch !== false
|
|
13
|
-
? fetchPkg(pkg)
|
|
14
|
-
: Promise.resolve()
|
|
15
|
-
])
|
|
16
|
-
|
|
17
|
-
if (!pkg.fetched) {
|
|
18
|
-
await run(pkg, 'buildCmd')
|
|
19
|
-
// await run(pkg, 'testCmd')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pkg.built = true
|
|
23
|
-
}))
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import {getPkgConfig} from '../config.js'
|
|
2
|
-
import {getLatest, getArtifactPath} from '../processor/meta.js'
|
|
3
|
-
import {getRoot, getSha, getRepo, deleteRemoteTag, fetchRepo, pushCommit} from '../api/git.js'
|
|
4
|
-
import {fetchManifest} from '../api/npm.js'
|
|
5
|
-
import {log} from '../log.js'
|
|
6
|
-
import {$, fs, path, fetch} from 'zx-extra'
|
|
7
|
-
|
|
8
|
-
// Inspired by https://docs.github.com/en/actions/learn-github-actions/contexts
|
|
9
|
-
export const contextify = async (pkg, {packages, root, flags, env}) => {
|
|
10
|
-
pkg.config = await getPkgConfig([pkg.absPath, root.absPath], env)
|
|
11
|
-
pkg.latest = await getLatest(pkg)
|
|
12
|
-
pkg.context = {
|
|
13
|
-
git: {
|
|
14
|
-
sha: await getSha(pkg.absPath),
|
|
15
|
-
root: await getRoot(pkg.absPath)
|
|
16
|
-
},
|
|
17
|
-
env: $.env,
|
|
18
|
-
flags,
|
|
19
|
-
packages
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Rollback a release that failed mid-publish (called inline from publish.js).
|
|
24
|
-
// Unlike `recover`, this uses the current release tag (pkg.context.git.tag)
|
|
25
|
-
// and skips the npm existence check — we already know the release failed.
|
|
26
|
-
export const rollbackRelease = async (pkg) => {
|
|
27
|
-
const tag = pkg.context.git.tag
|
|
28
|
-
if (!tag) return
|
|
29
|
-
|
|
30
|
-
const cwd = pkg.context.git.root
|
|
31
|
-
const {ghBasicAuth: basicAuth, ghToken, ghApiUrl, gitCommitterName, gitCommitterEmail} = pkg.config
|
|
32
|
-
if (!basicAuth) throw new Error('rollback requires git credentials (GH_TOKEN)')
|
|
33
|
-
const {repoName} = await getRepo(cwd, {basicAuth})
|
|
34
|
-
|
|
35
|
-
log({pkg})(`rollback: cleaning up failed release for tag '${tag}'`)
|
|
36
|
-
|
|
37
|
-
// 1. Delete GitHub release
|
|
38
|
-
if (ghToken) {
|
|
39
|
-
try {
|
|
40
|
-
const res = await fetch(`${ghApiUrl}/repos/${repoName}/releases/tags/${tag}`, {
|
|
41
|
-
headers: {Authorization: `token ${ghToken}`, 'X-GitHub-Api-Version': '2022-11-28'}
|
|
42
|
-
})
|
|
43
|
-
if (res.ok) {
|
|
44
|
-
const {id} = await res.json()
|
|
45
|
-
await fetch(`${ghApiUrl}/repos/${repoName}/releases/${id}`, {
|
|
46
|
-
method: 'DELETE',
|
|
47
|
-
headers: {Authorization: `token ${ghToken}`, 'X-GitHub-Api-Version': '2022-11-28'}
|
|
48
|
-
})
|
|
49
|
-
log({pkg})(`rollback: deleted gh release for '${tag}'`)
|
|
50
|
-
}
|
|
51
|
-
} catch (e) {
|
|
52
|
-
log({pkg, level: 'warn'})('rollback: failed to delete gh release', e)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// 2. Remove meta entry from meta branch
|
|
57
|
-
try {
|
|
58
|
-
const metaBranch = 'meta'
|
|
59
|
-
const metaCwd = await fetchRepo({cwd, branch: metaBranch, basicAuth})
|
|
60
|
-
const artifactPath = getArtifactPath(tag)
|
|
61
|
-
const candidates = [
|
|
62
|
-
path.resolve(metaCwd, `${artifactPath}.json`),
|
|
63
|
-
path.resolve(metaCwd, artifactPath)
|
|
64
|
-
]
|
|
65
|
-
let removed = false
|
|
66
|
-
for (const p of candidates) {
|
|
67
|
-
if (fs.existsSync(p)) {
|
|
68
|
-
await fs.remove(p)
|
|
69
|
-
removed = true
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (removed) {
|
|
73
|
-
await pushCommit({cwd, branch: metaBranch, msg: `chore: rollback ${pkg.name} ${pkg.version}`, gitCommitterName, gitCommitterEmail, basicAuth})
|
|
74
|
-
log({pkg})(`rollback: removed meta for '${tag}'`)
|
|
75
|
-
}
|
|
76
|
-
} catch (e) {
|
|
77
|
-
log({pkg, level: 'warn'})('rollback: failed to clean meta branch', e)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// 3. Delete git tag
|
|
81
|
-
await deleteRemoteTag({cwd, tag})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Rollback a partially failed release: delete orphan tag, meta, changelog, gh release.
|
|
85
|
-
export const recover = async (pkg) => {
|
|
86
|
-
const needsNpm = !pkg.manifest.private && pkg.config.npmPublish !== false
|
|
87
|
-
if (!needsNpm) return false
|
|
88
|
-
|
|
89
|
-
const {tag} = pkg.latest
|
|
90
|
-
if (!tag) return false
|
|
91
|
-
|
|
92
|
-
const manifest = await fetchManifest({
|
|
93
|
-
name: pkg.name,
|
|
94
|
-
version: tag.version,
|
|
95
|
-
config: pkg.config,
|
|
96
|
-
}, {nothrow: true})
|
|
97
|
-
|
|
98
|
-
if (manifest) return false
|
|
99
|
-
|
|
100
|
-
const cwd = await getRoot(pkg.absPath)
|
|
101
|
-
const {ghBasicAuth: basicAuth, ghToken, ghApiUrl, gitCommitterName, gitCommitterEmail} = pkg.config
|
|
102
|
-
if (!basicAuth) throw new Error('recover requires git credentials (GH_TOKEN)')
|
|
103
|
-
const {repoName} = await getRepo(cwd, {basicAuth})
|
|
104
|
-
|
|
105
|
-
log({pkg})(`recover: tag '${tag.ref}' exists but ${pkg.name}@${tag.version} not found on npm, rolling back failed release`)
|
|
106
|
-
|
|
107
|
-
// 1. Delete GitHub release (also removes attached meta assets)
|
|
108
|
-
if (ghToken) {
|
|
109
|
-
try {
|
|
110
|
-
const res = await fetch(`${ghApiUrl}/repos/${repoName}/releases/tags/${tag.ref}`, {
|
|
111
|
-
headers: {Authorization: `token ${ghToken}`, 'X-GitHub-Api-Version': '2022-11-28'}
|
|
112
|
-
})
|
|
113
|
-
if (res.ok) {
|
|
114
|
-
const {id} = await res.json()
|
|
115
|
-
await fetch(`${ghApiUrl}/repos/${repoName}/releases/${id}`, {
|
|
116
|
-
method: 'DELETE',
|
|
117
|
-
headers: {Authorization: `token ${ghToken}`, 'X-GitHub-Api-Version': '2022-11-28'}
|
|
118
|
-
})
|
|
119
|
-
log({pkg})(`recover: deleted gh release for '${tag.ref}'`)
|
|
120
|
-
}
|
|
121
|
-
} catch (e) {
|
|
122
|
-
log({pkg, level: 'warn'})('recover: failed to delete gh release', e)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// 2. Remove meta entry from meta branch
|
|
127
|
-
try {
|
|
128
|
-
const metaBranch = 'meta'
|
|
129
|
-
const metaCwd = await fetchRepo({cwd, branch: metaBranch, basicAuth})
|
|
130
|
-
const artifactPath = getArtifactPath(tag.ref)
|
|
131
|
-
const candidates = [
|
|
132
|
-
path.resolve(metaCwd, `${artifactPath}.json`),
|
|
133
|
-
path.resolve(metaCwd, artifactPath)
|
|
134
|
-
]
|
|
135
|
-
let removed = false
|
|
136
|
-
for (const p of candidates) {
|
|
137
|
-
if (fs.existsSync(p)) {
|
|
138
|
-
await fs.remove(p)
|
|
139
|
-
removed = true
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (removed) {
|
|
143
|
-
await pushCommit({cwd, branch: metaBranch, msg: `chore: recover ${pkg.name} ${tag.version}`, gitCommitterName, gitCommitterEmail, basicAuth})
|
|
144
|
-
log({pkg})(`recover: removed meta for '${tag.ref}'`)
|
|
145
|
-
}
|
|
146
|
-
} catch (e) {
|
|
147
|
-
log({pkg, level: 'warn'})('recover: failed to clean meta branch', e)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// 3. Delete orphan git tag
|
|
151
|
-
await deleteRemoteTag({cwd, tag: tag.ref})
|
|
152
|
-
|
|
153
|
-
return true
|
|
154
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import {memoizeBy} from '../util.js'
|
|
2
|
-
import {exec} from '../processor/exec.js'
|
|
3
|
-
import {$, within} from 'zx-extra'
|
|
4
|
-
import {npmPersist, npmPublish} from '../api/npm.js'
|
|
5
|
-
import {prepareMeta, pushMeta, pushReleaseTag} from '../processor/meta.js'
|
|
6
|
-
import {pushChangelog} from '../api/changelog.js'
|
|
7
|
-
import {ghPages, ghRelease} from '../api/gh.js'
|
|
8
|
-
import {rollbackRelease} from './contextify.js'
|
|
9
|
-
|
|
10
|
-
export const publish = memoizeBy(async (pkg, run = exec) => within(async () => {
|
|
11
|
-
$.scope = pkg.name
|
|
12
|
-
|
|
13
|
-
if (pkg.version !== pkg.manifest.version) {
|
|
14
|
-
throw new Error('package.json version not synced')
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
await npmPersist(pkg)
|
|
18
|
-
await prepareMeta(pkg)
|
|
19
|
-
|
|
20
|
-
if (pkg.context.flags.snapshot) {
|
|
21
|
-
await Promise.all([
|
|
22
|
-
npmPublish(pkg),
|
|
23
|
-
run(pkg, 'publishCmd')
|
|
24
|
-
])
|
|
25
|
-
} else {
|
|
26
|
-
await pushReleaseTag(pkg)
|
|
27
|
-
try {
|
|
28
|
-
await Promise.all([
|
|
29
|
-
pushMeta(pkg),
|
|
30
|
-
pushChangelog(pkg),
|
|
31
|
-
npmPublish(pkg),
|
|
32
|
-
ghRelease(pkg),
|
|
33
|
-
ghPages(pkg),
|
|
34
|
-
run(pkg, 'publishCmd')
|
|
35
|
-
])
|
|
36
|
-
} catch (e) {
|
|
37
|
-
// Rollback the entire failed release for npm-published packages.
|
|
38
|
-
// Git-tag-only packages (private or npmPublish: false) keep their tag — it IS the release.
|
|
39
|
-
const needsNpm = !pkg.manifest.private && pkg.config.npmPublish !== false
|
|
40
|
-
if (needsNpm) {
|
|
41
|
-
await rollbackRelease(pkg)
|
|
42
|
-
}
|
|
43
|
-
throw e
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
pkg.published = true
|
|
47
|
-
}))
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {$, within} from 'zx-extra'
|
|
2
|
-
import {memoizeBy} from '../util.js'
|
|
3
|
-
import {exec} from '../processor/exec.js'
|
|
4
|
-
// import {traverseDeps} from "../processor/deps.js";
|
|
5
|
-
|
|
6
|
-
export const test = memoizeBy(async (pkg, run = exec, flags = {}, self = test) => within(async () => {
|
|
7
|
-
$.scope = pkg.name
|
|
8
|
-
|
|
9
|
-
// await traverseDeps({pkg, packages: pkg.context.packages, cb: async({pkg}) => self(pkg, run, flags, self)})
|
|
10
|
-
|
|
11
|
-
if (!pkg.fetched) {
|
|
12
|
-
await run(pkg, 'testCmd')
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
pkg.tested = true
|
|
16
|
-
}))
|