@jsenv/package-publish 1.6.1 → 1.7.2
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/main.js +8 -0
- package/package.json +27 -33
- package/readme.md +19 -26
- package/src/internal/fetchLatestInRegistry.js +14 -9
- package/src/internal/needsPublish.js +22 -17
- package/src/internal/publish.js +160 -117
- package/src/internal/readProjectPackage.js +1 -3
- package/src/publishPackage.js +132 -134
- package/dist/commonjs/jsenv_package_publish.cjs +0 -501
- package/dist/commonjs/jsenv_package_publish.cjs.map +0 -174
- package/index.js +0 -1
package/main.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is the entry point of this codebase
|
|
3
|
+
* - It is responsible to export the documented API
|
|
4
|
+
* - It should be kept simple (just re-export) to help reader to
|
|
5
|
+
* discover codebase progressively
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { publishPackage } from "./src/publishPackage.js"
|
package/package.json
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/package-publish",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "Publish package to one or many registry.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "dmail",
|
|
8
|
+
"email": "dmaillard06@gmail.com",
|
|
9
|
+
"url": "https://twitter.com/damienmaillard"
|
|
10
|
+
},
|
|
6
11
|
"repository": {
|
|
7
12
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/jsenv/
|
|
13
|
+
"url": "https://github.com/jsenv/workflow",
|
|
14
|
+
"directory": "packages/jsenv-package-publish"
|
|
9
15
|
},
|
|
10
16
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
17
|
+
"node": ">=16.13.0"
|
|
12
18
|
},
|
|
13
19
|
"publishConfig": {
|
|
14
20
|
"access": "public",
|
|
@@ -17,49 +23,37 @@
|
|
|
17
23
|
"type": "module",
|
|
18
24
|
"exports": {
|
|
19
25
|
".": {
|
|
20
|
-
"import": "./
|
|
21
|
-
"require": "./dist/commonjs/jsenv_package_publish.cjs"
|
|
26
|
+
"import": "./main.js"
|
|
22
27
|
},
|
|
23
28
|
"./*": "./*"
|
|
24
29
|
},
|
|
25
|
-
"main": "
|
|
30
|
+
"main": "./main.js",
|
|
26
31
|
"files": [
|
|
27
|
-
"/dist/",
|
|
28
32
|
"/src/",
|
|
29
|
-
"/
|
|
33
|
+
"/main.js"
|
|
30
34
|
],
|
|
31
35
|
"scripts": {
|
|
32
|
-
"eslint
|
|
33
|
-
"
|
|
36
|
+
"eslint": "npx eslint . --ext=.js,.mjs",
|
|
37
|
+
"importmap": "node ./script/importmap/importmap.mjs",
|
|
38
|
+
"test": "node --experimental-json-modules ./script/test/test.mjs",
|
|
34
39
|
"test-with-coverage": "npm run test -- --coverage",
|
|
35
|
-
"
|
|
36
|
-
"dist": "npm run build",
|
|
37
|
-
"prettier-format": "node ./script/prettier-format/prettier-format.js",
|
|
38
|
-
"prettier-format-stage": "npm run prettier-format -- --staged",
|
|
39
|
-
"prettier-check": "npm run prettier-format -- --dry-run",
|
|
40
|
-
"upload-coverage": "node ./script/upload-coverage/upload-coverage.js",
|
|
41
|
-
"build": "node --experimental-import-meta-resolve ./script/build/build.js",
|
|
42
|
-
"prepublishOnly": "node ./script/transform-package/remove-postinstall.js && npm run dist",
|
|
43
|
-
"postpublish": "node ./script/transform-package/restore-postinstall.js"
|
|
40
|
+
"prettier": "prettier --write ."
|
|
44
41
|
},
|
|
45
42
|
"dependencies": {
|
|
46
|
-
"@jsenv/
|
|
43
|
+
"@jsenv/filesystem": "2.7.1",
|
|
47
44
|
"@jsenv/logger": "4.0.1",
|
|
48
|
-
"
|
|
49
|
-
"@jsenv/
|
|
45
|
+
"node-fetch": "2.6.7",
|
|
46
|
+
"@jsenv/log": "1.5.0",
|
|
50
47
|
"semver": "7.3.5"
|
|
51
48
|
},
|
|
52
49
|
"devDependencies": {
|
|
53
|
-
"@jsenv/assert": "2.
|
|
54
|
-
"@jsenv/
|
|
55
|
-
"@jsenv/
|
|
56
|
-
"@jsenv/eslint-
|
|
57
|
-
"@jsenv/
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"eslint": "7.26.0",
|
|
62
|
-
"eslint-plugin-import": "2.23.2",
|
|
63
|
-
"prettier": "2.3.0"
|
|
50
|
+
"@jsenv/assert": "2.4.1",
|
|
51
|
+
"@jsenv/core": "25.3.0",
|
|
52
|
+
"@jsenv/eslint-config": "16.0.9",
|
|
53
|
+
"@jsenv/importmap-eslint-resolver": "5.2.5",
|
|
54
|
+
"@jsenv/importmap-node-module": "5.1.3",
|
|
55
|
+
"eslint": "8.7.0",
|
|
56
|
+
"eslint-plugin-import": "2.25.4",
|
|
57
|
+
"prettier": "2.5.1"
|
|
64
58
|
}
|
|
65
59
|
}
|
package/readme.md
CHANGED
|
@@ -1,30 +1,19 @@
|
|
|
1
|
-
# Package publish
|
|
1
|
+
# Package publish [](https://www.npmjs.com/package/@jsenv/package-publish)
|
|
2
2
|
|
|
3
3
|
Publish package to one or many registry.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@jsenv/package-publish)
|
|
6
|
-
[](https://github.com/jsenv/jsenv-package-publish/actions?workflow=ci)
|
|
7
|
-
[](https://codecov.io/gh/jsenv/jsenv-package-publish)
|
|
8
|
-
|
|
9
|
-
# Table of contents
|
|
10
|
-
|
|
11
|
-
- [Presentation](#Presentation)
|
|
12
|
-
- [Installation](#installation)
|
|
13
|
-
- [Documentation](#Documentation)
|
|
14
|
-
- [publishPackage](#publishPackage)
|
|
15
|
-
|
|
16
5
|
# Presentation
|
|
17
6
|
|
|
18
|
-
|
|
7
|
+
- Can be used to automate "npm publish" during a workflow
|
|
8
|
+
- Allows to publish on many registries: both npm and github registries for instance.
|
|
19
9
|
|
|
20
|
-
You can use it inside a
|
|
10
|
+
You can use it inside a GitHub workflow or inside any other continuous environment like Travis or Jenkins.
|
|
21
11
|
|
|
22
12
|
Screenshot taken inside a github workflow when the package.json version is already published: 
|
|
23
13
|
|
|
24
14
|
Screenshot taken inside a github workflow when the package.json version is not published: 
|
|
25
15
|
|
|
26
|
-
This package
|
|
27
|
-
— see [.github/workflows/ci.yml#publish-package](https://github.com/jsenv/jsenv-package-publish/blob/9bc6af39afa8825ff7fcdc475c3ede8e900c7475/.github/workflows/ci.yml#L39)
|
|
16
|
+
This package is using itself to be published on NPM. It is done during ["publish package" step](https://github.com/jsenv/package-publish/blob/0170a5c859c4732203ff2f3e70b85e705396ccc7/.github/workflows/main.yml#L70-L74) in GitHub worflow.
|
|
28
17
|
|
|
29
18
|
# Installation
|
|
30
19
|
|
|
@@ -34,15 +23,15 @@ npm install --save-dev @jsenv/package-publish
|
|
|
34
23
|
|
|
35
24
|
# Documentation
|
|
36
25
|
|
|
37
|
-
The api consist into one function called
|
|
26
|
+
The api consist into one function called _publishPackage_.
|
|
38
27
|
|
|
39
|
-
|
|
28
|
+
_publishPackage_ is an async function publishing a package on one or many registries.
|
|
40
29
|
|
|
41
30
|
```js
|
|
42
31
|
import { publishPackage } from "@jsenv/package-publish"
|
|
43
32
|
|
|
44
33
|
const publishReport = await publishPackage({
|
|
45
|
-
projectDirectoryUrl:
|
|
34
|
+
projectDirectoryUrl: new URL('./', import.meta.url)
|
|
46
35
|
registriesConfig: {
|
|
47
36
|
"https://registry.npmjs.org": {
|
|
48
37
|
token: process.env.NPM_TOKEN,
|
|
@@ -54,18 +43,22 @@ const publishReport = await publishPackage({
|
|
|
54
43
|
})
|
|
55
44
|
```
|
|
56
45
|
|
|
57
|
-
|
|
46
|
+
## projectDirectoryUrl
|
|
47
|
+
|
|
48
|
+
_projectDirectoryUrl_ parameter is a string leading to a directory containing the package.json.
|
|
49
|
+
|
|
50
|
+
This parameter is **required**.
|
|
58
51
|
|
|
59
|
-
|
|
52
|
+
## registriesConfig
|
|
60
53
|
|
|
61
|
-
|
|
54
|
+
_registriesConfig_ parameter is an object configuring on which registries you want to publish your package.
|
|
62
55
|
|
|
63
|
-
|
|
56
|
+
This parameter is **required**.
|
|
64
57
|
|
|
65
|
-
|
|
58
|
+
## logLevel
|
|
66
59
|
|
|
67
|
-
|
|
60
|
+
_logLevel_ parameter is a string controlling verbosity of logs during the function execution.
|
|
68
61
|
|
|
69
|
-
|
|
62
|
+
This parameter is optional.
|
|
70
63
|
|
|
71
64
|
— see also https://github.com/jsenv/jsenv-logger#loglevel
|
|
@@ -2,25 +2,31 @@
|
|
|
2
2
|
// https://github.com/npm/registry-issue-archive/issues/34
|
|
3
3
|
// https://stackoverflow.com/questions/53212849/querying-information-about-specific-version-of-scoped-npm-package
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import nodeFetch from "node-fetch"
|
|
6
6
|
|
|
7
|
-
export const fetchLatestInRegistry = async ({
|
|
7
|
+
export const fetchLatestInRegistry = async ({
|
|
8
|
+
registryUrl,
|
|
9
|
+
packageName,
|
|
10
|
+
token,
|
|
11
|
+
}) => {
|
|
8
12
|
const requestUrl = `${registryUrl}/${packageName}`
|
|
9
|
-
const response = await
|
|
13
|
+
const response = await nodeFetch(requestUrl, {
|
|
10
14
|
method: "GET",
|
|
11
15
|
headers: {
|
|
12
16
|
// "user-agent": "jsenv",
|
|
13
|
-
accept:
|
|
14
|
-
|
|
17
|
+
accept:
|
|
18
|
+
"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*",
|
|
19
|
+
...(token
|
|
20
|
+
? {
|
|
21
|
+
authorization: `token ${token}`,
|
|
22
|
+
}
|
|
23
|
+
: {}),
|
|
15
24
|
},
|
|
16
25
|
})
|
|
17
|
-
|
|
18
26
|
const responseStatus = response.status
|
|
19
|
-
|
|
20
27
|
if (responseStatus === 404) {
|
|
21
28
|
return null
|
|
22
29
|
}
|
|
23
|
-
|
|
24
30
|
if (responseStatus !== 200) {
|
|
25
31
|
throw new Error(
|
|
26
32
|
writeUnexpectedResponseStatus({
|
|
@@ -30,7 +36,6 @@ export const fetchLatestInRegistry = async ({ registryUrl, packageName, token })
|
|
|
30
36
|
}),
|
|
31
37
|
)
|
|
32
38
|
}
|
|
33
|
-
|
|
34
39
|
const packageObject = await response.json()
|
|
35
40
|
return packageObject.versions[packageObject["dist-tags"].latest]
|
|
36
41
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { createRequire } from "module"
|
|
1
|
+
import { createRequire } from "node:module"
|
|
2
2
|
|
|
3
3
|
const require = createRequire(import.meta.url)
|
|
4
4
|
// https://github.com/npm/node-semver#readme
|
|
5
|
-
const {
|
|
5
|
+
const {
|
|
6
|
+
gt: versionGreaterThan,
|
|
7
|
+
prerelease: versionToPrerelease,
|
|
8
|
+
} = require("semver")
|
|
6
9
|
|
|
7
10
|
export const PUBLISH_BECAUSE_NEVER_PUBLISHED = "never-published"
|
|
8
11
|
export const PUBLISH_BECAUSE_LATEST_LOWER = "latest-lower"
|
|
@@ -15,43 +18,45 @@ export const needsPublish = ({ registryLatestVersion, packageVersion }) => {
|
|
|
15
18
|
if (registryLatestVersion === null) {
|
|
16
19
|
return PUBLISH_BECAUSE_NEVER_PUBLISHED
|
|
17
20
|
}
|
|
18
|
-
|
|
19
21
|
if (registryLatestVersion === packageVersion) {
|
|
20
22
|
return NOTHING_BECAUSE_ALREADY_PUBLISHED
|
|
21
23
|
}
|
|
22
|
-
|
|
23
24
|
if (versionGreaterThan(registryLatestVersion, packageVersion)) {
|
|
24
25
|
return NOTHING_BECAUSE_LATEST_HIGHER
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
const registryLatestVersionPrerelease = versionToPrerelease(
|
|
28
|
+
registryLatestVersion,
|
|
29
|
+
)
|
|
28
30
|
const packageVersionPrerelease = versionToPrerelease(packageVersion)
|
|
29
|
-
if (
|
|
31
|
+
if (
|
|
32
|
+
registryLatestVersionPrerelease === null &&
|
|
33
|
+
packageVersionPrerelease === null
|
|
34
|
+
) {
|
|
30
35
|
return PUBLISH_BECAUSE_LATEST_LOWER
|
|
31
36
|
}
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
if (
|
|
38
|
+
registryLatestVersionPrerelease === null &&
|
|
39
|
+
packageVersionPrerelease !== null
|
|
40
|
+
) {
|
|
34
41
|
return PUBLISH_BECAUSE_LATEST_LOWER
|
|
35
42
|
}
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
if (
|
|
44
|
+
registryLatestVersionPrerelease !== null &&
|
|
45
|
+
packageVersionPrerelease === null
|
|
46
|
+
) {
|
|
38
47
|
return PUBLISH_BECAUSE_LATEST_LOWER
|
|
39
48
|
}
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
const [registryReleaseTag, registryPrereleaseVersion] =
|
|
50
|
+
registryLatestVersionPrerelease
|
|
42
51
|
const [packageReleaseTag, packagePreReleaseVersion] = packageVersionPrerelease
|
|
43
|
-
|
|
44
52
|
if (registryReleaseTag !== packageReleaseTag) {
|
|
45
53
|
return PUBLISH_BECAUSE_TAG_DIFFERS
|
|
46
54
|
}
|
|
47
|
-
|
|
48
55
|
if (registryPrereleaseVersion === packagePreReleaseVersion) {
|
|
49
56
|
return NOTHING_BECAUSE_ALREADY_PUBLISHED
|
|
50
57
|
}
|
|
51
|
-
|
|
52
58
|
if (registryPrereleaseVersion > packagePreReleaseVersion) {
|
|
53
59
|
return NOTHING_BECAUSE_LATEST_HIGHER
|
|
54
60
|
}
|
|
55
|
-
|
|
56
61
|
return PUBLISH_BECAUSE_LATEST_LOWER
|
|
57
62
|
}
|
package/src/internal/publish.js
CHANGED
|
@@ -1,140 +1,181 @@
|
|
|
1
|
-
import { exec } from "child_process"
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { exec } from "node:child_process"
|
|
2
|
+
import {
|
|
3
|
+
resolveUrl,
|
|
4
|
+
urlToFileSystemPath,
|
|
5
|
+
readFile,
|
|
6
|
+
writeFile,
|
|
7
|
+
removeFileSystemNode,
|
|
8
|
+
} from "@jsenv/filesystem"
|
|
9
|
+
import { UNICODE } from "@jsenv/log"
|
|
4
10
|
|
|
5
11
|
import { setNpmConfig } from "./setNpmConfig.js"
|
|
6
12
|
|
|
7
13
|
export const publish = async ({
|
|
8
14
|
logger,
|
|
15
|
+
packageSlug,
|
|
9
16
|
logNpmPublishOutput,
|
|
10
17
|
projectDirectoryUrl,
|
|
11
18
|
registryUrl,
|
|
12
19
|
token,
|
|
13
20
|
}) => {
|
|
14
|
-
|
|
15
|
-
const promises = []
|
|
16
|
-
|
|
17
|
-
const previousValue = process.env.NODE_AUTH_TOKEN
|
|
18
|
-
const restoreProcessEnv = () => {
|
|
19
|
-
process.env.NODE_AUTH_TOKEN = previousValue
|
|
20
|
-
}
|
|
21
|
-
process.env.NODE_AUTH_TOKEN = token
|
|
22
|
-
|
|
23
|
-
const projectPackageFileUrl = resolveUrl("./package.json", projectDirectoryUrl)
|
|
24
|
-
const projectPackageString = await readFile(projectPackageFileUrl)
|
|
25
|
-
const restoreProjectPackageFile = () => writeFile(projectPackageFileUrl, projectPackageString)
|
|
26
|
-
const projectPackageObject = JSON.parse(projectPackageString)
|
|
27
|
-
projectPackageObject.publishConfig = projectPackageObject.publishConfig || {}
|
|
28
|
-
projectPackageObject.publishConfig.registry = registryUrl
|
|
29
|
-
promises.push(
|
|
30
|
-
writeFile(projectPackageFileUrl, JSON.stringify(projectPackageObject, null, " ")),
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
const projectNpmConfigFileUrl = resolveUrl("./.npmrc", projectDirectoryUrl)
|
|
34
|
-
let projectNpmConfigString
|
|
21
|
+
const getResult = async () => {
|
|
35
22
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
} else {
|
|
41
|
-
throw e
|
|
23
|
+
const promises = []
|
|
24
|
+
const previousValue = process.env.NODE_AUTH_TOKEN
|
|
25
|
+
const restoreProcessEnv = () => {
|
|
26
|
+
process.env.NODE_AUTH_TOKEN = previousValue
|
|
42
27
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
28
|
+
process.env.NODE_AUTH_TOKEN = token
|
|
29
|
+
const projectPackageFileUrl = resolveUrl(
|
|
30
|
+
"./package.json",
|
|
31
|
+
projectDirectoryUrl,
|
|
32
|
+
)
|
|
33
|
+
const projectPackageString = await readFile(projectPackageFileUrl)
|
|
34
|
+
const restoreProjectPackageFile = () =>
|
|
35
|
+
writeFile(projectPackageFileUrl, projectPackageString)
|
|
36
|
+
const projectPackageObject = JSON.parse(projectPackageString)
|
|
37
|
+
projectPackageObject.publishConfig =
|
|
38
|
+
projectPackageObject.publishConfig || {}
|
|
39
|
+
projectPackageObject.publishConfig.registry = registryUrl
|
|
40
|
+
promises.push(
|
|
41
|
+
writeFile(
|
|
42
|
+
projectPackageFileUrl,
|
|
43
|
+
JSON.stringify(projectPackageObject, null, " "),
|
|
44
|
+
),
|
|
45
|
+
)
|
|
46
|
+
const projectNpmConfigFileUrl = resolveUrl(
|
|
47
|
+
"./.npmrc",
|
|
48
|
+
projectDirectoryUrl,
|
|
49
|
+
)
|
|
50
|
+
let restoreProjectNpmConfigFile
|
|
51
|
+
let projectNpmConfigString
|
|
52
|
+
try {
|
|
53
|
+
projectNpmConfigString = await readFile(projectNpmConfigFileUrl)
|
|
54
|
+
restoreProjectNpmConfigFile = () =>
|
|
55
|
+
writeFile(projectNpmConfigFileUrl, projectNpmConfigString)
|
|
56
|
+
} catch (e) {
|
|
57
|
+
if (e.code === "ENOENT") {
|
|
58
|
+
restoreProjectNpmConfigFile = () =>
|
|
59
|
+
removeFileSystemNode(projectNpmConfigFileUrl)
|
|
60
|
+
projectNpmConfigString = ""
|
|
61
|
+
} else {
|
|
62
|
+
throw e
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
promises.push(
|
|
66
|
+
writeFile(
|
|
67
|
+
projectNpmConfigFileUrl,
|
|
68
|
+
setNpmConfig(projectNpmConfigString, {
|
|
69
|
+
[computeRegistryTokenKey(registryUrl)]: token,
|
|
70
|
+
[computeRegistryKey(projectPackageObject.name)]: registryUrl,
|
|
71
|
+
}),
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
await Promise.all(promises)
|
|
75
|
+
try {
|
|
76
|
+
return await new Promise((resolve, reject) => {
|
|
77
|
+
const command = exec(
|
|
78
|
+
"npm publish",
|
|
79
|
+
{
|
|
80
|
+
cwd: urlToFileSystemPath(projectDirectoryUrl),
|
|
81
|
+
stdio: "silent",
|
|
82
|
+
},
|
|
83
|
+
(error) => {
|
|
84
|
+
if (error) {
|
|
85
|
+
// publish conflict generally occurs because servers
|
|
86
|
+
// returns 200 after npm publish
|
|
87
|
+
// but returns previous version if asked immediatly
|
|
88
|
+
// after for the last published version.
|
|
72
89
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
90
|
+
// TODO: ideally we should catch 404 error returned from npm
|
|
91
|
+
// it happens it the token is not allowed to publish
|
|
92
|
+
// a repository. And when we detect this we display a more useful message
|
|
93
|
+
// suggesting the token rights are insufficient to publish the package
|
|
77
94
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
// npm publish conclit
|
|
96
|
+
if (error.message.includes("EPUBLISHCONFLICT")) {
|
|
97
|
+
resolve({
|
|
98
|
+
success: true,
|
|
99
|
+
reason: "already-published",
|
|
100
|
+
})
|
|
101
|
+
} else if (
|
|
102
|
+
error.message.includes("Cannot publish over existing version")
|
|
103
|
+
) {
|
|
104
|
+
resolve({
|
|
105
|
+
success: true,
|
|
106
|
+
reason: "already-published",
|
|
107
|
+
})
|
|
108
|
+
} else if (
|
|
109
|
+
error.message.includes(
|
|
110
|
+
"You cannot publish over the previously published versions",
|
|
111
|
+
)
|
|
112
|
+
) {
|
|
113
|
+
resolve({
|
|
114
|
+
success: true,
|
|
115
|
+
reason: "already-published",
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
// github publish conflict
|
|
119
|
+
else if (
|
|
120
|
+
error.message.includes(
|
|
121
|
+
"ambiguous package version in package.json",
|
|
122
|
+
)
|
|
123
|
+
) {
|
|
124
|
+
resolve({
|
|
125
|
+
success: true,
|
|
126
|
+
reason: "already-published",
|
|
127
|
+
})
|
|
128
|
+
} else {
|
|
129
|
+
reject(error)
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
99
132
|
resolve({
|
|
100
133
|
success: true,
|
|
101
|
-
reason: "
|
|
134
|
+
reason: "published",
|
|
102
135
|
})
|
|
103
|
-
} else {
|
|
104
|
-
reject(error)
|
|
105
136
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
137
|
+
},
|
|
138
|
+
)
|
|
139
|
+
if (logNpmPublishOutput) {
|
|
140
|
+
command.stdout.on("data", (data) => {
|
|
141
|
+
logger.debug(data)
|
|
142
|
+
})
|
|
143
|
+
command.stderr.on("data", (data) => {
|
|
144
|
+
// debug because this output is part of
|
|
145
|
+
// the error message generated by a failing npm publish
|
|
146
|
+
logger.debug(data)
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
} finally {
|
|
151
|
+
await Promise.all([
|
|
152
|
+
restoreProcessEnv(),
|
|
153
|
+
restoreProjectPackageFile(),
|
|
154
|
+
restoreProjectNpmConfigFile(),
|
|
155
|
+
])
|
|
156
|
+
}
|
|
157
|
+
} catch (e) {
|
|
158
|
+
return {
|
|
159
|
+
success: false,
|
|
160
|
+
reason: e,
|
|
161
|
+
}
|
|
131
162
|
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
163
|
+
}
|
|
164
|
+
const { success, reason } = await getResult()
|
|
165
|
+
if (success) {
|
|
166
|
+
if (reason === "already-published") {
|
|
167
|
+
logger.info(
|
|
168
|
+
`${UNICODE.INFO} ${packageSlug} was already published on ${registryUrl}`,
|
|
169
|
+
)
|
|
170
|
+
} else {
|
|
171
|
+
logger.info(`${UNICODE.OK} ${packageSlug} published on ${registryUrl}`)
|
|
136
172
|
}
|
|
173
|
+
} else {
|
|
174
|
+
logger.error(`${UNICODE.FAILURE} error when publishing ${packageSlug} in ${registryUrl}
|
|
175
|
+
--- error stack ---
|
|
176
|
+
${reason.stack}`)
|
|
137
177
|
}
|
|
178
|
+
return { success, reason }
|
|
138
179
|
}
|
|
139
180
|
|
|
140
181
|
const computeRegistryTokenKey = (registryUrl) => {
|
|
@@ -147,7 +188,9 @@ const computeRegistryTokenKey = (registryUrl) => {
|
|
|
147
188
|
if (registryUrl.startsWith("//")) {
|
|
148
189
|
return `${registryUrl}/:_authToken`
|
|
149
190
|
}
|
|
150
|
-
throw new Error(
|
|
191
|
+
throw new Error(
|
|
192
|
+
`registryUrl must start with http or https, got ${registryUrl}`,
|
|
193
|
+
)
|
|
151
194
|
}
|
|
152
195
|
|
|
153
196
|
const computeRegistryKey = (packageName) => {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { resolveUrl, urlToFileSystemPath, readFile } from "@jsenv/
|
|
1
|
+
import { resolveUrl, urlToFileSystemPath, readFile } from "@jsenv/filesystem"
|
|
2
2
|
|
|
3
3
|
export const readProjectPackage = async ({ projectDirectoryUrl }) => {
|
|
4
4
|
const packageFileUrl = resolveUrl("./package.json", projectDirectoryUrl)
|
|
5
|
-
|
|
6
5
|
let packageObject
|
|
7
6
|
try {
|
|
8
7
|
const packageString = await readFile(packageFileUrl)
|
|
@@ -28,6 +27,5 @@ ${urlToFileSystemPath(packageFileUrl)}`,
|
|
|
28
27
|
}
|
|
29
28
|
throw e
|
|
30
29
|
}
|
|
31
|
-
|
|
32
30
|
return packageObject
|
|
33
31
|
}
|