@pnpm/releasing.commands 1100.2.10 → 1100.2.12

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.
@@ -22,6 +22,11 @@ export interface OtpParams {
22
22
  * - Web based authentication flow (authUrl/doneUrl in error body with doneUrl polling)
23
23
  * - Classic OTP prompt (manual code entry)
24
24
  *
25
+ * The caller is responsible for supplying a {@link OtpContext.fetch} that
26
+ * honors the desired network configuration (proxy, TLS, etc.); see
27
+ * https://github.com/pnpm/pnpm/issues/11561 for why this matters during the
28
+ * web-based authentication flow.
29
+ *
25
30
  * @see https://github.com/npm/cli/blob/7d900c46/lib/utils/otplease.js for npm's implementation.
26
31
  * @see https://github.com/npm/npm-profile/blob/main/lib/index.js for the webauth polling flow.
27
32
  */
@@ -5,6 +5,11 @@ import { SHARED_CONTEXT } from './utils/shared-context.js';
5
5
  * - Web based authentication flow (authUrl/doneUrl in error body with doneUrl polling)
6
6
  * - Classic OTP prompt (manual code entry)
7
7
  *
8
+ * The caller is responsible for supplying a {@link OtpContext.fetch} that
9
+ * honors the desired network configuration (proxy, TLS, etc.); see
10
+ * https://github.com/pnpm/pnpm/issues/11561 for why this matters during the
11
+ * web-based authentication flow.
12
+ *
8
13
  * @see https://github.com/npm/cli/blob/7d900c46/lib/utils/otplease.js for npm's implementation.
9
14
  * @see https://github.com/npm/npm-profile/blob/main/lib/index.js for the webauth polling flow.
10
15
  */
@@ -171,6 +171,21 @@ export async function api(opts) {
171
171
  if (!manifest.version) {
172
172
  throw new PnpmError('PACKAGE_VERSION_NOT_FOUND', `Package version is not defined in the ${manifestFileName}.`);
173
173
  }
174
+ const publishManifest = await createPublishManifest({
175
+ projectDir: dir,
176
+ modulesDir: path.join(opts.dir, 'node_modules'),
177
+ manifest,
178
+ embedReadme: opts.embedReadme,
179
+ catalogs: opts.catalogs ?? {},
180
+ hooks: opts.hooks,
181
+ });
182
+ // Strip semver build metadata (the `+<build>` segment) from the published version so that
183
+ // the tarball, the manifest packed inside it, and the metadata sent to the registry all agree.
184
+ // libnpmpublish runs `semver.clean()` on `manifest.version` before computing the provenance
185
+ // subject, which removes build metadata. Leaving it in here would mismatch the version embedded
186
+ // in the tarball's package.json and cause the registry to reject the publish with a 422 when
187
+ // verifying the sigstore provenance bundle. See https://github.com/pnpm/pnpm/issues/11518.
188
+ publishManifest.version = stripBuildMetadata(publishManifest.version);
174
189
  let tarballName;
175
190
  let packDestination;
176
191
  const normalizedName = manifest.name.replace('@', '').replace('/', '-');
@@ -178,23 +193,15 @@ export async function api(opts) {
178
193
  if (opts.packDestination) {
179
194
  throw new PnpmError('INVALID_OPTION', 'Cannot use --pack-destination and --out together');
180
195
  }
181
- const preparedOut = opts.out.replaceAll('%s', normalizedName).replaceAll('%v', manifest.version);
196
+ const preparedOut = opts.out.replaceAll('%s', normalizedName).replaceAll('%v', publishManifest.version);
182
197
  const parsedOut = path.parse(preparedOut);
183
198
  packDestination = parsedOut.dir ? parsedOut.dir : opts.packDestination;
184
199
  tarballName = parsedOut.base;
185
200
  }
186
201
  else {
187
- tarballName = `${normalizedName}-${manifest.version}.tgz`;
202
+ tarballName = `${normalizedName}-${publishManifest.version}.tgz`;
188
203
  packDestination = opts.packDestination;
189
204
  }
190
- const publishManifest = await createPublishManifest({
191
- projectDir: dir,
192
- modulesDir: path.join(opts.dir, 'node_modules'),
193
- manifest,
194
- embedReadme: opts.embedReadme,
195
- catalogs: opts.catalogs ?? {},
196
- hooks: opts.hooks,
197
- });
198
205
  const files = await packlist(dir, {
199
206
  manifest: publishManifest,
200
207
  });
@@ -257,6 +264,10 @@ export async function api(opts) {
257
264
  unpackedSize,
258
265
  };
259
266
  }
267
+ function stripBuildMetadata(version) {
268
+ const plusIndex = version.indexOf('+');
269
+ return plusIndex === -1 ? version : version.slice(0, plusIndex);
270
+ }
260
271
  function preventBundledDependenciesWithoutHoistedNodeLinker(nodeLinker, manifest) {
261
272
  if (nodeLinker === 'hoisted')
262
273
  return;
@@ -1,7 +1,8 @@
1
1
  import type { Config } from '@pnpm/config.reader';
2
2
  import { PnpmError } from '@pnpm/error';
3
+ import { type OtpContext } from './otp.js';
3
4
  import type { PackResult } from './pack.js';
4
- export type PublishPackedPkgOptions = Pick<Config, 'configByUri' | 'dryRun' | 'fetchRetries' | 'fetchRetryFactor' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'fetchTimeout' | 'registries' | 'tag' | 'userAgent'> & {
5
+ export type PublishPackedPkgOptions = Pick<Config, 'configByUri' | 'dryRun' | 'fetchRetries' | 'fetchRetryFactor' | 'fetchRetryMaxtimeout' | 'fetchRetryMintimeout' | 'fetchTimeout' | 'registries' | 'tag' | 'userAgent'> & Partial<Pick<Config, 'ca' | 'cert' | 'httpProxy' | 'httpsProxy' | 'key' | 'localAddress' | 'noProxy' | 'strictSsl'>> & {
5
6
  access?: 'public' | 'restricted';
6
7
  ci?: boolean;
7
8
  otp?: string;
@@ -37,6 +38,14 @@ export interface PublishSummary {
37
38
  bundled: string[];
38
39
  }
39
40
  export declare function publishPackedPkg(packResult: Pick<PackResult, 'publishedManifest' | 'tarballPath' | 'contents' | 'unpackedSize'>, opts: PublishPackedPkgOptions): Promise<PublishSummary>;
41
+ /**
42
+ * Builds the {@link OtpContext} used to drive the publish. The default fetch
43
+ * is replaced by one that respects proxy / TLS / local-address settings, so
44
+ * the `doneUrl` polling in the web-based authentication flow goes through
45
+ * the same network configuration as the initial publish request (see
46
+ * https://github.com/pnpm/pnpm/issues/11561).
47
+ */
48
+ export declare function createPublishContext(opts: PublishPackedPkgOptions): OtpContext;
40
49
  export declare class PublishUnsupportedRegistryProtocolError extends PnpmError {
41
50
  readonly registryUrl: string;
42
51
  constructor(registryUrl: string);
@@ -3,6 +3,7 @@ import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import { PnpmError } from '@pnpm/error';
5
5
  import { globalInfo, globalWarn } from '@pnpm/logger';
6
+ import { createDispatchedFetch } from '@pnpm/network.fetch';
6
7
  import { displayError } from './displayError.js';
7
8
  import { executeTokenHelper } from './executeTokenHelper.js';
8
9
  import { createFailedToPublishError } from './FailedToPublishError.js';
@@ -11,6 +12,7 @@ import { getIdToken, IdTokenError } from './oidc/idToken.js';
11
12
  import { determineProvenance, ProvenanceError } from './oidc/provenance.js';
12
13
  import { publishWithOtpHandling } from './otp.js';
13
14
  import { allRegistryConfigKeys, parseSupportedRegistryUrl } from './registryConfigKeys.js';
15
+ import { SHARED_CONTEXT } from './utils/shared-context.js';
14
16
  export async function publishPackedPkg(packResult, opts) {
15
17
  const { publishedManifest, tarballPath, contents, unpackedSize } = packResult;
16
18
  const tarballData = await fs.readFile(tarballPath);
@@ -37,13 +39,31 @@ export async function publishPackedPkg(packResult, opts) {
37
39
  globalWarn(`Skip publishing ${name}@${version} (dry run)`);
38
40
  return summary;
39
41
  }
40
- const response = await publishWithOtpHandling({ manifest: publishedManifest, tarballData, publishOptions });
42
+ const response = await publishWithOtpHandling({
43
+ context: createPublishContext(opts),
44
+ manifest: publishedManifest,
45
+ publishOptions,
46
+ tarballData,
47
+ });
41
48
  if (response.ok) {
42
49
  globalInfo(`✅ Published package ${name}@${version}`);
43
50
  return summary;
44
51
  }
45
52
  throw await createFailedToPublishError(packResult, response);
46
53
  }
54
+ /**
55
+ * Builds the {@link OtpContext} used to drive the publish. The default fetch
56
+ * is replaced by one that respects proxy / TLS / local-address settings, so
57
+ * the `doneUrl` polling in the web-based authentication flow goes through
58
+ * the same network configuration as the initial publish request (see
59
+ * https://github.com/pnpm/pnpm/issues/11561).
60
+ */
61
+ export function createPublishContext(opts) {
62
+ return {
63
+ ...SHARED_CONTEXT,
64
+ fetch: createDispatchedFetch({ ...opts, timeout: opts.fetchTimeout }),
65
+ };
66
+ }
47
67
  /**
48
68
  * npm accepts both `bundledDependencies` and `bundleDependencies` in package.json and normalizes
49
69
  * to a list of dependency names. We mirror that normalization so consumers see a consistent array.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/releasing.commands",
3
- "version": "1100.2.10",
3
+ "version": "1100.2.12",
4
4
  "description": "Commands for deploy, pack, and publish",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -27,58 +27,58 @@
27
27
  "@pnpm/npm-package-arg": "^2.0.0",
28
28
  "@types/normalize-path": "^3.0.2",
29
29
  "@zkochan/rimraf": "^4.0.0",
30
- "chalk": "^5.6.2",
31
- "ci-info": "^4.4.0",
32
- "detect-libc": "^2.1.2",
30
+ "chalk": "^5.6.0",
31
+ "ci-info": "^4.3.0",
32
+ "detect-libc": "^2.0.3",
33
33
  "enquirer": "^2.4.1",
34
34
  "execa": "npm:safe-execa@0.3.0",
35
35
  "libnpmpublish": "^11.1.3",
36
36
  "normalize-path": "^3.0.0",
37
37
  "normalize-registry-url": "2.0.1",
38
38
  "p-filter": "^4.1.0",
39
- "p-limit": "^7.3.0",
39
+ "p-limit": "^7.1.0",
40
40
  "ramda": "npm:@pnpm/ramda@0.28.1",
41
41
  "realpath-missing": "^2.0.0",
42
42
  "render-help": "^2.0.0",
43
- "semver": "^7.7.4",
44
- "tar-stream": "^3.2.0",
43
+ "semver": "^7.7.2",
44
+ "tar-stream": "^3.1.7",
45
45
  "tempy": "3.0.0",
46
- "tinyglobby": "^0.2.16",
46
+ "tinyglobby": "^0.2.14",
47
47
  "validate-npm-package-name": "7.0.2",
48
48
  "write-json-file": "^7.0.0",
49
49
  "write-yaml-file": "^6.0.0",
50
- "@pnpm/bins.resolver": "1100.0.2",
51
- "@pnpm/catalogs.types": "1100.0.0",
52
50
  "@pnpm/cli.common-cli-options-help": "1100.0.1",
53
- "@pnpm/cli.utils": "1101.0.2",
54
- "@pnpm/config.reader": "1101.2.1",
55
- "@pnpm/config.pick-registry-for-package": "1100.0.2",
51
+ "@pnpm/bins.resolver": "1100.0.3",
52
+ "@pnpm/catalogs.types": "1100.0.0",
53
+ "@pnpm/config.reader": "1101.3.0",
54
+ "@pnpm/cli.utils": "1101.0.3",
55
+ "@pnpm/config.pick-registry-for-package": "1100.0.3",
56
+ "@pnpm/deps.path": "1100.0.3",
57
+ "@pnpm/engine.runtime.node-resolver": "1101.0.7",
58
+ "@pnpm/engine.runtime.commands": "1100.0.13",
56
59
  "@pnpm/constants": "1100.0.0",
57
- "@pnpm/deps.path": "1100.0.2",
58
- "@pnpm/engine.runtime.commands": "1100.0.11",
59
- "@pnpm/engine.runtime.node-resolver": "1101.0.5",
60
60
  "@pnpm/error": "1100.0.0",
61
- "@pnpm/exec.lifecycle": "1100.0.6",
61
+ "@pnpm/exec.lifecycle": "1100.0.8",
62
62
  "@pnpm/exec.pnpm-cli-runner": "1100.0.0",
63
- "@pnpm/fetching.directory-fetcher": "1100.0.6",
64
- "@pnpm/fs.indexed-pkg-importer": "1100.0.5",
63
+ "@pnpm/fetching.directory-fetcher": "1100.0.8",
64
+ "@pnpm/fs.indexed-pkg-importer": "1100.0.6",
65
65
  "@pnpm/fs.is-empty-dir-or-nothing": "1100.0.0",
66
- "@pnpm/fs.packlist": "1100.0.0",
67
- "@pnpm/installing.client": "1100.0.11",
68
- "@pnpm/installing.commands": "1100.1.11",
69
- "@pnpm/lockfile.fs": "1100.0.6",
70
- "@pnpm/lockfile.types": "1100.0.4",
71
- "@pnpm/network.fetch": "1100.0.2",
66
+ "@pnpm/fs.packlist": "1100.0.1",
67
+ "@pnpm/installing.client": "1100.0.13",
68
+ "@pnpm/lockfile.fs": "1100.0.7",
69
+ "@pnpm/network.fetch": "1100.0.3",
72
70
  "@pnpm/network.git-utils": "1100.0.1",
73
71
  "@pnpm/network.web-auth": "1101.0.0",
74
- "@pnpm/releasing.exportable-manifest": "1100.0.3",
75
- "@pnpm/resolving.resolver-base": "1100.1.2",
76
- "@pnpm/types": "1101.0.0",
77
- "@pnpm/workspace.projects-filter": "1100.0.8",
78
- "@pnpm/workspace.projects-sorter": "1100.0.1"
72
+ "@pnpm/lockfile.types": "1100.0.5",
73
+ "@pnpm/installing.commands": "1100.2.0",
74
+ "@pnpm/releasing.exportable-manifest": "1100.0.4",
75
+ "@pnpm/types": "1101.1.0",
76
+ "@pnpm/workspace.projects-filter": "1100.0.10",
77
+ "@pnpm/resolving.resolver-base": "1100.1.3",
78
+ "@pnpm/workspace.projects-sorter": "1100.0.2"
79
79
  },
80
80
  "peerDependencies": {
81
- "@pnpm/logger": "^1001.0.1"
81
+ "@pnpm/logger": ">=1001.0.0 <1002.0.0"
82
82
  },
83
83
  "devDependencies": {
84
84
  "@jest/globals": "30.3.0",
@@ -92,20 +92,20 @@
92
92
  "@types/tar": "^7.0.87",
93
93
  "@types/tar-stream": "^3.1.4",
94
94
  "@types/validate-npm-package-name": "^4.0.2",
95
- "ci-info": "^4.4.0",
95
+ "ci-info": "^4.3.0",
96
96
  "cross-spawn": "^7.0.6",
97
97
  "is-windows": "^1.0.2",
98
98
  "load-json-file": "^7.0.1",
99
- "tar": "^7.5.13",
100
- "undici": "^7.25.0",
99
+ "tar": "^7.5.10",
100
+ "undici": "^7.2.0",
101
101
  "write-yaml-file": "^6.0.0",
102
- "@pnpm/assert-project": "1100.0.5",
102
+ "@pnpm/assert-project": "1100.0.7",
103
103
  "@pnpm/catalogs.config": "1100.0.0",
104
- "@pnpm/hooks.pnpmfile": "1100.0.6",
105
104
  "@pnpm/logger": "1100.0.0",
106
- "@pnpm/prepare": "1100.0.5",
107
- "@pnpm/releasing.commands": "1100.2.10",
105
+ "@pnpm/hooks.pnpmfile": "1100.0.7",
106
+ "@pnpm/releasing.commands": "1100.2.12",
108
107
  "@pnpm/test-fixtures": "1100.0.0",
108
+ "@pnpm/prepare": "1100.0.7",
109
109
  "@pnpm/test-ipc-server": "1100.0.0",
110
110
  "@pnpm/testing.command-defaults": "1100.0.1"
111
111
  },