bulletin-deploy 0.19.4 → 0.20.0-rc.1

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.
Files changed (50) hide show
  1. package/bin/bulletin-deploy +61 -13
  2. package/dist/auth-config.js +3 -3
  3. package/dist/bug-report.js +4 -4
  4. package/dist/chain-health.js +3 -3
  5. package/dist/{chunk-6J4WRFRL.js → chunk-4GDRFJER.js} +1 -1
  6. package/dist/{chunk-R3BXRRKE.js → chunk-567ZRMI6.js} +1 -1
  7. package/dist/{chunk-BFK5UCUJ.js → chunk-A3VWIJKO.js} +29 -2
  8. package/dist/{chunk-D3YME2EG.js → chunk-CI4MX3LD.js} +8 -4
  9. package/dist/{chunk-D6BE3RAU.js → chunk-FR73P4GO.js} +158 -59
  10. package/dist/{chunk-FWJQAIVO.js → chunk-IJ3ONWE7.js} +57 -18
  11. package/dist/{chunk-F24S4EV5.js → chunk-IJIU2WZU.js} +3 -2
  12. package/dist/{chunk-CCIBF55X.js → chunk-IUPVNIVY.js} +1 -1
  13. package/dist/{chunk-JTH3ISLR.js → chunk-JBMBQFCO.js} +2 -2
  14. package/dist/{chunk-C437RTTU.js → chunk-JYJQNITR.js} +39 -23
  15. package/dist/{chunk-2P4EZOFF.js → chunk-JYVJRJ7H.js} +1 -1
  16. package/dist/{chunk-U2QO5G35.js → chunk-KACRAHSV.js} +1 -1
  17. package/dist/{chunk-UFP2XWZ4.js → chunk-NGVCDMLS.js} +3 -3
  18. package/dist/{chunk-OONQPYHM.js → chunk-QKEZK2M6.js} +110 -24
  19. package/dist/{chunk-ZZIOS4RG.js → chunk-SKL6ULZN.js} +344 -60
  20. package/dist/chunk-probe.js +3 -3
  21. package/dist/commands/login.js +14 -14
  22. package/dist/commands/logout.js +4 -4
  23. package/dist/commands/transfer.js +5 -5
  24. package/dist/commands/whoami.js +3 -3
  25. package/dist/deploy-actors.js +7 -7
  26. package/dist/deploy.d.ts +75 -3
  27. package/dist/deploy.js +32 -16
  28. package/dist/dotns.d.ts +71 -20
  29. package/dist/dotns.js +9 -5
  30. package/dist/incremental-stats.js +1 -1
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +27 -15
  33. package/dist/manifest/publish.d.ts +31 -1
  34. package/dist/manifest/publish.js +17 -15
  35. package/dist/manifest-fetch.d.ts +10 -0
  36. package/dist/manifest-fetch.js +1 -1
  37. package/dist/manifest-roundtrip.js +1 -1
  38. package/dist/memory-report.js +2 -2
  39. package/dist/merkle.js +14 -14
  40. package/dist/personhood/bootstrap.js +5 -5
  41. package/dist/personhood/people-client.js +5 -5
  42. package/dist/pool.d.ts +18 -2
  43. package/dist/pool.js +7 -1
  44. package/dist/run-state.d.ts +19 -1
  45. package/dist/run-state.js +11 -1
  46. package/dist/sss-allowance-cache.js +4 -4
  47. package/dist/storage-signer.js +14 -14
  48. package/dist/telemetry.js +2 -2
  49. package/dist/version-check.js +3 -3
  50. package/package.json +2 -2
@@ -6,12 +6,13 @@
6
6
  // SDK modules that trigger the "@parity/product-sdk-logger" localStorage warning.
7
7
  import "../dist/suppress-localstorage-warning.js";
8
8
 
9
- import { deploy, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, NonRetryableError, EXIT_CODE_NO_RETRY, isConnectionError, isBenignTeardownError, resolveEffectiveMnemonic, mnemonicConflictNotice, resolveEnvId, shouldPublishManifest, nonInteractivePhoneConfirmationError } from "../dist/deploy.js";
9
+ import { deploy, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, NonRetryableError, EXIT_CODE_NO_RETRY, isConnectionError, isBenignTeardownError, resolveEffectiveMnemonic, mnemonicConflictNotice, resolveEnvId, shouldPublishManifest, nonInteractivePhoneConfirmationError, printDeploymentCompleteBanner } from "../dist/deploy.js";
10
10
  import { VERSION, setDeployAttribute, captureWarning, closeTelemetry, setRunStateActive, markRelaunchOomHintShown, setVersionFreshness } from "../dist/telemetry.js";
11
11
  import { handleFailedDeploy, handlePreflightVersionCheck, fetchVersionInfo, preReleaseWarning, checkNodeVersion, classifyVersionFreshness, isInteractive } from "../dist/version-check.js";
12
12
  import { setDeployContext, installLogCapture, buildCliFlagsSummary } from "../dist/bug-report.js";
13
13
  import { loadRunState, writeRunState, shouldSkipStaleWarning, shouldShowOomHint, probablyOomRssMb } from "../dist/run-state.js";
14
- import { loadEnvironments, listEnvironments, formatEnvironmentTable, DEFAULT_ENV_ID } from "../dist/environments.js";
14
+ import { loadEnvironments, listEnvironments, formatEnvironmentTable, resolveEndpoints, DEFAULT_ENV_ID } from "../dist/environments.js";
15
+ import { DEFAULT_TLD } from "../dist/dotns.js";
15
16
  import * as fs from "fs";
16
17
  import * as readline from "readline";
17
18
 
@@ -454,25 +455,68 @@ try {
454
455
  // #1163: --no-manifest (--content-only) skips this entirely — the deploy is
455
456
  // content-only regardless of any discoverable config, so there's nothing to
456
457
  // preflight.
458
+ //
459
+ // #1164: hoisted so the SAME loaded config (one filesystem walk-up + parse)
460
+ // can drive both the manifestPending banner decision below and the actual
461
+ // publishManifest() call further down — previously each of those three call
462
+ // sites (this preflight, the banner decision, the publish block) reloaded
463
+ // the config independently. resolveConfigPath resolves `cwd` via
464
+ // `path.resolve(options.cwd ?? process.cwd())` (src/manifest/config-load.ts),
465
+ // which is idempotent, so reusing this result (loaded with the raw
466
+ // `buildDir`) is identical to the publish block's old `buildDirAbs`-based
467
+ // reload.
468
+ let preflightedConfig = null;
457
469
  if (!flags.noManifest) {
458
470
  try {
459
- const { preflightProductConfig } = await import("../dist/index.js");
471
+ const { preflightProductConfig, reconcileManifestDomain } = await import("../dist/index.js");
460
472
  // config-load resolves a relative cwd internally, so no node:path here
461
473
  // (it's only dynamically imported later, in the publish block).
462
- await preflightProductConfig(
463
- flags.config ? { path: flags.config } : { cwd: buildDir, walkUp: true },
464
- );
474
+ // #1156: preflightProductConfig (config discovery/parse + icon/executable
475
+ // file checks) and loadEnvironments (a local environments.json read)
476
+ // have no data dependency on each other — run them concurrently rather
477
+ // than paying their I/O sequentially.
478
+ const [loadedConfig, { doc }] = await Promise.all([
479
+ preflightProductConfig(
480
+ flags.config ? { path: flags.config } : { cwd: buildDir, walkUp: true },
481
+ ),
482
+ // No options: flags.environmentFile was already copied into
483
+ // process.env.BULLETIN_DEPLOY_ENV_FILE above, which loadEnvironments
484
+ // reads as its own default — passing it again here would just be
485
+ // recomputing that same fallback.
486
+ loadEnvironments(),
487
+ ]);
488
+ preflightedConfig = loadedConfig;
489
+ // Reconcile the config's domain against the ACTUAL deploy target
490
+ // BEFORE deploy() runs at all — this is the real "nothing uploaded
491
+ // yet" gate; src/manifest/publish.ts's own call to the same helper
492
+ // (inside publishManifest) is only a backstop for a library caller
493
+ // that skips this CLI entirely. Same env/TLD resolution publishManifest
494
+ // itself uses (loadEnvironments + resolveEndpoints), so this sees the
495
+ // identical environment the deploy will target — no RPC call, both are
496
+ // local config reads.
497
+ if (loadedConfig) {
498
+ const resolved = resolveEndpoints(doc, effectiveEnvId ?? DEFAULT_ENV_ID);
499
+ const envTld = resolved.tld ?? DEFAULT_TLD;
500
+ reconcileManifestDomain(loadedConfig.config.domain, domain, envTld, loadedConfig.sourcePath);
501
+ }
465
502
  } catch (err) {
466
503
  console.error(`Error: ${err?.message ?? err}`);
467
504
  process.exit(err instanceof NonRetryableError ? EXIT_CODE_NO_RETRY : 1);
468
505
  }
469
506
  }
470
507
 
508
+ // #1164: determine up front whether a manifest publish will follow, so
509
+ // deploy() can defer the "DEPLOYMENT COMPLETE" banner until publishManifest
510
+ // actually succeeds. Reuses the SAME preflightedConfig loaded just above —
511
+ // no second config load.
512
+ const manifestWillPublish = shouldPublishManifest({ configFound: !!preflightedConfig, noManifest: !!flags.noManifest });
513
+
471
514
  const result = await deploy(buildDir, domain, {
472
515
  mnemonic: effectiveMnemonic,
473
516
  derivationPath: flags.derivationPath,
474
517
  productName: flags.productName,
475
518
  suri: flags.suri,
519
+ manifestPending: manifestWillPublish,
476
520
  rpc: flags.rpc,
477
521
  env: effectiveEnvId,
478
522
  poolSize: flags.poolSize,
@@ -569,16 +613,15 @@ try {
569
613
  //
570
614
  // #1163: --no-manifest (--content-only) skips manifest publishing even when
571
615
  // a config is present. shouldPublishManifest() is the single source of
572
- // truth for that decision (config discovery still runs either way, so the
573
- // "config found but --no-manifest set" case is exercised for real, not just
574
- // in unit tests).
616
+ // truth for that decision.
617
+ //
618
+ // #1164: reuses `preflightedConfig` (loaded once, above) instead of a third
619
+ // independent tryLoadProductConfig call.
575
620
  {
576
- const { tryLoadProductConfig, publishManifest } = await import("../dist/index.js");
621
+ const { publishManifest } = await import("../dist/index.js");
577
622
  const path = await import("node:path");
578
623
  const buildDirAbs = path.resolve(buildDir);
579
- const loaded = await tryLoadProductConfig(
580
- flags.config ? { path: flags.config } : { cwd: buildDirAbs, walkUp: true },
581
- );
624
+ const loaded = preflightedConfig;
582
625
  if (shouldPublishManifest({ configFound: !!loaded, noManifest: !!flags.noManifest })) {
583
626
  try {
584
627
  await publishManifest({
@@ -596,6 +639,11 @@ try {
596
639
  storageSigner: result.storageSigner,
597
640
  storageSignerAddress: result.storageSignerAddress,
598
641
  });
642
+ // #1164: deploy() deferred the real completion banner (manifestPending
643
+ // was set above) — print it now that the manifest phase actually
644
+ // succeeded, so a manifest publish failure never leaves a false
645
+ // "DEPLOYMENT COMPLETE!" on screen.
646
+ printDeploymentCompleteBanner(result.fullDomain, result.browserUrl);
599
647
  } catch (err) {
600
648
  console.error(`Manifest publish failed: ${err?.message ?? err}`);
601
649
  process.exit(err instanceof NonRetryableError ? EXIT_CODE_NO_RETRY : 1);
@@ -9,11 +9,11 @@ import {
9
9
  getPeopleChainEndpoints,
10
10
  hasPersistedSession,
11
11
  resolveBulletinEndpoints
12
- } from "./chunk-U2QO5G35.js";
12
+ } from "./chunk-KACRAHSV.js";
13
13
  import "./chunk-TSPERKUS.js";
14
14
  import "./chunk-3NR3T7US.js";
15
- import "./chunk-BFK5UCUJ.js";
16
- import "./chunk-OONQPYHM.js";
15
+ import "./chunk-A3VWIJKO.js";
16
+ import "./chunk-QKEZK2M6.js";
17
17
  import "./chunk-SH2LG52Z.js";
18
18
  export {
19
19
  DOT_DAPP_ID,
@@ -10,10 +10,10 @@ import {
10
10
  offerBugReport,
11
11
  scrubSecrets,
12
12
  setDeployContext
13
- } from "./chunk-UFP2XWZ4.js";
14
- import "./chunk-R3BXRRKE.js";
15
- import "./chunk-BFK5UCUJ.js";
16
- import "./chunk-OONQPYHM.js";
13
+ } from "./chunk-NGVCDMLS.js";
14
+ import "./chunk-567ZRMI6.js";
15
+ import "./chunk-A3VWIJKO.js";
16
+ import "./chunk-QKEZK2M6.js";
17
17
  import "./chunk-SH2LG52Z.js";
18
18
  export {
19
19
  buildCliFlagsSummary,
@@ -3,9 +3,9 @@ import {
3
3
  DEFAULT_WINDOW_BLOCKS,
4
4
  MAX_SPANS_PER_SAMPLER,
5
5
  endpointHost
6
- } from "./chunk-CCIBF55X.js";
7
- import "./chunk-BFK5UCUJ.js";
8
- import "./chunk-OONQPYHM.js";
6
+ } from "./chunk-IUPVNIVY.js";
7
+ import "./chunk-A3VWIJKO.js";
8
+ import "./chunk-QKEZK2M6.js";
9
9
  import "./chunk-SH2LG52Z.js";
10
10
  export {
11
11
  ChainHealthSampler,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-GRPLHUYC.js";
4
4
  import {
5
5
  DOT_DAPP_ID
6
- } from "./chunk-U2QO5G35.js";
6
+ } from "./chunk-KACRAHSV.js";
7
7
 
8
8
  // src/sss-allowance-cache.ts
9
9
  import { mkdir, readFile, writeFile, unlink } from "fs/promises";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-BFK5UCUJ.js";
3
+ } from "./chunk-A3VWIJKO.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  package_default,
3
3
  writeRunState
4
- } from "./chunk-OONQPYHM.js";
4
+ } from "./chunk-QKEZK2M6.js";
5
5
  import {
6
6
  FALLBACK_CONFIG_ORIGIN,
7
7
  SHIPPED_CONFIG_ORIGIN
@@ -245,7 +245,29 @@ var DEPLOY_SEED_STORAGE = {
245
245
  "deploy.storage.phase_b.probe_hit_count": 0,
246
246
  "deploy.phase_a.chunks_uploaded": 0,
247
247
  // Manifest-aware Phase A trust: count of section-1 CIDs trusted from prev manifest.
248
- "deploy.phase_a.chunks_trusted": 0
248
+ "deploy.phase_a.chunks_trusted": 0,
249
+ // Seeded "false" like the other content-type booleans above, so every span
250
+ // carries it for ratio queries — including file-mode/bytes-mode deploys and
251
+ // any deploy that errors before reaching the directory-mode storage phase,
252
+ // neither of which ever runs the code that flips this. Set to "true" by
253
+ // deploy.ts's directory-mode storage phase when it takes the incremental
254
+ // path; stays "false" for the legacy full-upload path (encrypted or
255
+ // network==="mainnet", #1550). Deliberately a different attribute from the
256
+ // top-level "deploy.incremental" in DEPLOY_SEED_CONTENT above, which only
257
+ // records whether a previous contenthash was found (i.e. whether this
258
+ // deploy COULD be incremental) — this one records whether the storage
259
+ // phase actually took that path.
260
+ "deploy.storage.incremental": "false",
261
+ // #1382: deploy.cache.manifest_source (set by the telemetryAttributes(...)
262
+ // loop in storeDirectoryV2, near the very end of the storage phase) was
263
+ // previously entirely unset on any deploy that never reached that point —
264
+ // a subdomain deploy, an early error, or the encrypted legacy path
265
+ // (storeDirectory never calls computeStats at all). That "(unset)" bucket
266
+ // was 23.1% of real-user spans, larger than every failure bucket combined,
267
+ // and indistinguishable from a genuine outcome. "not_reached" names it.
268
+ // Overwritten unconditionally by the telemetryAttributes loop once
269
+ // storeDirectoryV2's stats step runs — see the regression test in test.js.
270
+ "deploy.cache.manifest_source": "not_reached"
249
271
  };
250
272
  var DEPLOY_SEED_PROBE = {
251
273
  "deploy.probe.finality_miss_count": 0,
@@ -272,6 +294,10 @@ var DEPLOY_SEED_BULLETIN_UPLOAD = {
272
294
  "bulletin.upload.block_hash": "",
273
295
  "bulletin.upload.block_number": ""
274
296
  };
297
+ var DEPLOY_SEED_BULLETIN_AUTH = {
298
+ "deploy.bulletin.quota_exhausted": "false",
299
+ "deploy.bulletin.quota_exhausted_dimension": "none"
300
+ };
275
301
  var DEPLOY_SEED_RECEIPTS = {
276
302
  "deploy.contenthash.tx": "",
277
303
  "deploy.contenthash.block": "",
@@ -303,6 +329,7 @@ function getDeployAttributes(domain) {
303
329
  ...DEPLOY_SEED_POOL,
304
330
  ...DEPLOY_SEED_MANIFEST,
305
331
  ...DEPLOY_SEED_BULLETIN_UPLOAD,
332
+ ...DEPLOY_SEED_BULLETIN_AUTH,
306
333
  ...DEPLOY_SEED_RECEIPTS,
307
334
  ...DEPLOY_SEED_P2P,
308
335
  // Computed at call time (depend on domain arg, env vars, or external process calls):
@@ -126,7 +126,11 @@ function renderSummary(s) {
126
126
  }
127
127
  lines.push(`Cache:`);
128
128
  if (s.manifestSource === "none") {
129
- lines.push(` Manifest: first deploy (no previous manifest)`);
129
+ if (!s.manifestFetchReason || s.manifestFetchReason === "first_deploy") {
130
+ lines.push(` Manifest: first deploy (no previous manifest)`);
131
+ } else {
132
+ lines.push(` Manifest: none (${s.manifestFetchReason})`);
133
+ }
130
134
  } else if (s.manifestSource === "embedded") {
131
135
  const sizeStr = s.manifestBytes > 0 ? `, ${fmtKb(s.manifestBytes)} KB Range hit` : "";
132
136
  lines.push(` Manifest: embedded (${s.manifestFetchAttempts} ${attemptsWord}${sizeStr})`);
@@ -147,7 +151,7 @@ function renderSummary(s) {
147
151
  if (s.probeFailedMetadata > 0) reasons.push("metadata_error");
148
152
  probeFailedStr = `, ${s.probeFailed} probe-failed (${reasons.join(", ")})`;
149
153
  }
150
- lines.push(` Probed: ${s.probedTotal} chunks \u2192 ${s.probePresent} on chain, ${s.probeAbsent} absent${probeFailedStr}`);
154
+ lines.push(` Probed: ${s.probedTotal} chunks \u2192 ${s.probePresent} on chain, ${s.probeAbsent} absent${probeFailedStr} (Phase A only)`);
151
155
  }
152
156
  if (s.recycledCids > 0 && s.manifestSource === "embedded") {
153
157
  lines.push(` Recycled: ${s.recycledCids} CIDs found on-chain that weren't in the previous manifest`);
@@ -159,9 +163,9 @@ function renderSummary(s) {
159
163
  lines.push(` CAR sections: manifest ${fmtKb(s.section0Bytes)} KB \xB7 stable ${fmtMb(s.section1Bytes)} MB \xB7 volatile ${fmtMb(s.section2Bytes)} MB`);
160
164
  if (s.chunksUploaded > 0) {
161
165
  if (s.bytesSkipped > 0) {
162
- lines.push(` Upload: ${fmtMb(s.bytesUploaded)} MB across ${s.chunksUploaded} chunks (vs ${fmtMb(s.carBytes)} MB if full deploy)`);
166
+ lines.push(` Upload: ${fmtMb(s.bytesUploaded)} MB across ${s.chunksUploaded} chunks (A+B combined) (vs ${fmtMb(s.carBytes)} MB if full deploy)`);
163
167
  } else {
164
- lines.push(` Upload: ${fmtMb(s.bytesUploaded)} MB across ${s.chunksUploaded} chunks`);
168
+ lines.push(` Upload: ${fmtMb(s.bytesUploaded)} MB across ${s.chunksUploaded} chunks (A+B combined)`);
165
169
  }
166
170
  }
167
171
  if (s.estimatedSecondsSaved > 0 || s.bytesSkipped > 0) {