bulletin-deploy 0.7.15 → 0.7.16-rc.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/README.md +3 -0
- package/bin/bulletin-deploy +18 -4
- package/dist/bug-report.js +4 -4
- package/dist/{chunk-ZGU6FOLO.js → chunk-2IMBCUB2.js} +1 -1
- package/dist/{chunk-KMRYJR4E.js → chunk-5P7EZSOU.js} +20 -2
- package/dist/{chunk-Y2OSXJIZ.js → chunk-GHBHQP4S.js} +1 -1
- package/dist/{chunk-NE5MN2M2.js → chunk-MGTWZ6XS.js} +2 -2
- package/dist/{chunk-5TW653QP.js → chunk-OLU6VQG2.js} +12 -9
- package/dist/{chunk-AQUBKPSF.js → chunk-S2WGWNP5.js} +2 -2
- package/dist/{chunk-VQHM3R6N.js → chunk-WMSBC5B2.js} +70 -12
- package/dist/{chunk-2VYG7NXN.js → chunk-X3F7WHSF.js} +1 -1
- package/dist/chunk-probe.js +3 -3
- package/dist/deploy.d.ts +8 -0
- package/dist/deploy.js +8 -8
- package/dist/dotns.d.ts +3 -2
- package/dist/dotns.js +5 -3
- package/dist/environments.d.ts +1 -1
- package/dist/environments.js +1 -1
- package/dist/index.js +8 -8
- package/dist/memory-report.d.ts +1 -1
- package/dist/memory-report.js +2 -2
- package/dist/merkle.js +8 -8
- package/dist/run-state.js +1 -1
- package/dist/telemetry.js +2 -2
- package/dist/version-check.js +3 -3
- package/docs/telemetry.md +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -103,6 +103,7 @@ The runtime uses a 24-hour cache at `${XDG_CACHE_HOME:-~/.cache}/bulletin-deploy
|
|
|
103
103
|
| `--js-merkle` | Use pure-JS merkleization instead of the Kubo binary. |
|
|
104
104
|
| `--tag "..."` | Attach a free-form telemetry label. Also readable from `DEPLOY_TAG`. |
|
|
105
105
|
| `--gh-pages-mirror` | After a successful deploy, push the generated CAR to the current repo's `gh-pages` branch as an HTTP mirror. |
|
|
106
|
+
| `--input-car <path>` | Deploy from a pre-built CAR file instead of a build directory. Skips merkleization; reads the root CID from the CAR header. Usage: `bulletin-deploy --input-car site.car my-app.dot` |
|
|
106
107
|
| `--version` | Print the CLI version. |
|
|
107
108
|
| `--help` | Show help. |
|
|
108
109
|
|
|
@@ -201,6 +202,8 @@ await deploy("./dist", "my-app00.dot", { jsMerkle: true });
|
|
|
201
202
|
| `DOTNS_STATUS` | `full` on testnet, `none` on mainnet | PoP level to self-grant before registration: `none`, `lite`, or `full` |
|
|
202
203
|
| `IPFS_CID` | unset | Skip storage and reuse an existing CID |
|
|
203
204
|
| `DEPLOY_TAG` | unset | Telemetry label equivalent to `--tag` |
|
|
205
|
+
| `BULLETIN_DEPLOY_HOST_APP` | unset | Name of the host app embedding bulletin-deploy (e.g. `playground-cli`). Sets `deploy.host_app` on telemetry spans. |
|
|
206
|
+
| `BULLETIN_DEPLOY_HOST_APP_VERSION` | unset | Version of the host app. Sets `deploy.host_app_version` on telemetry spans when `BULLETIN_DEPLOY_HOST_APP` is also set. |
|
|
204
207
|
|
|
205
208
|
## Troubleshooting
|
|
206
209
|
|
package/bin/bulletin-deploy
CHANGED
|
@@ -27,6 +27,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
27
27
|
else if (args[i] === "--refresh-environments") { flags.refreshEnvironments = true; }
|
|
28
28
|
else if (args[i] === "--password") { flags.password = args[++i]; }
|
|
29
29
|
else if (args[i] === "--js-merkle") { flags.jsMerkle = true; }
|
|
30
|
+
else if (args[i] === "--input-car") { flags.inputCar = args[++i]; }
|
|
30
31
|
else if (args[i] === "--tag") { flags.tag = args[++i]; }
|
|
31
32
|
else if (args[i] === "--name") { flags.name = args[++i]; }
|
|
32
33
|
else if (args[i] === "--description") { flags.description = args[++i]; }
|
|
@@ -95,6 +96,8 @@ Options:
|
|
|
95
96
|
--pool-size N Number of pool accounts (default: 10)
|
|
96
97
|
--password "..." Encrypt SPA content (users will be prompted to decrypt)
|
|
97
98
|
--js-merkle Use pure-JS merkleization (no IPFS Kubo binary required)
|
|
99
|
+
--input-car <path> Deploy a pre-built CAR file; skips directory scan and merkleization.
|
|
100
|
+
Usage: bulletin-deploy --input-car <file.car> <domain.dot>
|
|
98
101
|
--tag "..." Label deploy in telemetry (or set DEPLOY_TAG env var); see Telemetry in README
|
|
99
102
|
--name "..." Optional. Sets the "name" text record on the domain.
|
|
100
103
|
--description "..." Optional. Sets the "description" text record (≤100 chars recommended).
|
|
@@ -210,10 +213,20 @@ if (!flags.help && !flags.version) {
|
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
try {
|
|
213
|
-
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
|
|
216
|
+
let buildDir, domain;
|
|
217
|
+
if (flags.inputCar) {
|
|
218
|
+
// --input-car mode: positional[0] is the domain; no build directory needed.
|
|
219
|
+
[domain] = positional;
|
|
220
|
+
if (!flags.inputCar) { console.error("Error: --input-car requires a path argument"); process.exit(1); }
|
|
221
|
+
if (!domain) { console.error("Error: domain required (e.g. my-app.dot)"); process.exit(1); }
|
|
222
|
+
if (!fs.existsSync(flags.inputCar)) { console.error(`Error: ${flags.inputCar} does not exist`); process.exit(1); }
|
|
223
|
+
buildDir = flags.inputCar; // passed as `content` to deploy(); inputCar branch handles it
|
|
224
|
+
} else {
|
|
225
|
+
[buildDir, domain] = positional;
|
|
226
|
+
if (!buildDir) { console.error("Error: build directory required"); process.exit(1); }
|
|
227
|
+
if (!domain) { console.error("Error: domain required (e.g. my-app.dot)"); process.exit(1); }
|
|
228
|
+
if (!fs.existsSync(buildDir)) { console.error(`Error: ${buildDir} does not exist`); process.exit(1); }
|
|
229
|
+
}
|
|
217
230
|
|
|
218
231
|
// --refresh-environments composed with a deploy: bust the cache before
|
|
219
232
|
// deploy() loads it, so deploy() picks up fresh data on the next loadEnvironments().
|
|
@@ -254,6 +267,7 @@ try {
|
|
|
254
267
|
poolSize: flags.poolSize,
|
|
255
268
|
password: flags.password,
|
|
256
269
|
jsMerkle: flags.jsMerkle,
|
|
270
|
+
inputCar: flags.inputCar,
|
|
257
271
|
tag: flags.tag,
|
|
258
272
|
ghPagesMirror: flags.ghPagesMirror,
|
|
259
273
|
name: flags.name,
|
package/dist/bug-report.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
offerBugReport,
|
|
10
10
|
scrubSecrets,
|
|
11
11
|
setDeployContext
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-S2WGWNP5.js";
|
|
13
|
+
import "./chunk-MGTWZ6XS.js";
|
|
14
|
+
import "./chunk-5P7EZSOU.js";
|
|
15
|
+
import "./chunk-2IMBCUB2.js";
|
|
16
16
|
import "./chunk-QGM4M3NI.js";
|
|
17
17
|
export {
|
|
18
18
|
buildCliFlagsSummary,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default,
|
|
3
3
|
writeRunState
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2IMBCUB2.js";
|
|
5
5
|
|
|
6
6
|
// src/memory-report.ts
|
|
7
7
|
import * as fs2 from "fs";
|
|
@@ -13,8 +13,23 @@ import * as v8 from "v8";
|
|
|
13
13
|
import { execSync } from "child_process";
|
|
14
14
|
import { createHash } from "crypto";
|
|
15
15
|
import * as fs from "fs";
|
|
16
|
+
import { createRequire } from "module";
|
|
16
17
|
import * as path from "path";
|
|
17
18
|
var VERSION = package_default.version;
|
|
19
|
+
function resolveDotnsCliVersion() {
|
|
20
|
+
try {
|
|
21
|
+
const require2 = createRequire(import.meta.url);
|
|
22
|
+
const mainPath = require2.resolve("@parity/dotns-cli");
|
|
23
|
+
const marker = `${path.sep}node_modules${path.sep}@parity${path.sep}dotns-cli${path.sep}`;
|
|
24
|
+
const idx = mainPath.lastIndexOf(marker);
|
|
25
|
+
if (idx === -1) return "unknown";
|
|
26
|
+
const pkgJson = path.join(mainPath.slice(0, idx + marker.length), "package.json");
|
|
27
|
+
return JSON.parse(fs.readFileSync(pkgJson, "utf-8")).version ?? "unknown";
|
|
28
|
+
} catch {
|
|
29
|
+
return "unknown";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
var DOTNS_CLI_VERSION = resolveDotnsCliVersion();
|
|
18
33
|
var DEFAULT_DSN = "https://e021c025d79c4c3ade2862a11f13c40b@o4511059872841728.ingest.de.sentry.io/4511093597405264";
|
|
19
34
|
var INTERNAL_ORG_RE = /^(paritytech|w3f|polkadot-fellows)\//i;
|
|
20
35
|
var PARITY_HOST_APPS = /* @__PURE__ */ new Set(["playground-cli"]);
|
|
@@ -211,6 +226,9 @@ function getDeployAttributes(domain) {
|
|
|
211
226
|
"deploy.dotns.toppedup": "false"
|
|
212
227
|
};
|
|
213
228
|
if (hostApp) attrs["deploy.host_app"] = hostApp;
|
|
229
|
+
const hostAppVersion = process.env.BULLETIN_DEPLOY_HOST_APP_VERSION;
|
|
230
|
+
if (hostAppVersion) attrs["deploy.host_app_version"] = hostAppVersion;
|
|
231
|
+
attrs["deploy.dotns_cli_version"] = DOTNS_CLI_VERSION;
|
|
214
232
|
return attrs;
|
|
215
233
|
}
|
|
216
234
|
function isExpectedError(msg) {
|
|
@@ -452,7 +470,7 @@ async function flush() {
|
|
|
452
470
|
function isBunRuntime() {
|
|
453
471
|
return typeof globalThis.Bun !== "undefined" || typeof process.versions.bun === "string";
|
|
454
472
|
}
|
|
455
|
-
var DEFAULT_THRESHOLD_MB =
|
|
473
|
+
var DEFAULT_THRESHOLD_MB = 800;
|
|
456
474
|
function toMb2(bytes) {
|
|
457
475
|
return Math.round(bytes / 1024 / 1024 * 100) / 100;
|
|
458
476
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5P7EZSOU.js";
|
|
4
4
|
|
|
5
5
|
// src/version-check.ts
|
|
6
6
|
import { execSync, execFileSync } from "child_process";
|
|
7
7
|
import { createInterface } from "readline";
|
|
8
8
|
var REGISTRY_URL = "https://registry.npmjs.org/bulletin-deploy/latest";
|
|
9
|
-
var KILL_SWITCH_URL = "https://raw.githubusercontent.com/paritytech/
|
|
9
|
+
var KILL_SWITCH_URL = "https://raw.githubusercontent.com/paritytech/triangle-deploy/main/min-version.json";
|
|
10
10
|
var FETCH_TIMEOUT = 3e3;
|
|
11
11
|
function compareSemver(a, b) {
|
|
12
12
|
const [coreA, preA] = a.split("-", 2);
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
captureWarning,
|
|
6
6
|
setDeployAttribute,
|
|
7
7
|
withSpan
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5P7EZSOU.js";
|
|
9
9
|
|
|
10
10
|
// src/dotns.ts
|
|
11
11
|
import { spawn } from "child_process";
|
|
@@ -362,6 +362,9 @@ function isExplicitCommitmentBuffer(envValue) {
|
|
|
362
362
|
const parsed = Number(envValue);
|
|
363
363
|
return Number.isFinite(parsed) && parsed > 0;
|
|
364
364
|
}
|
|
365
|
+
function isLikelyCommitmentRace(msg) {
|
|
366
|
+
return /CommitmentTooNew/i.test(msg) || /Revive\.ContractReverted/i.test(msg);
|
|
367
|
+
}
|
|
365
368
|
function classifyDotnsLabel(label) {
|
|
366
369
|
const totalLength = label.length;
|
|
367
370
|
const trailingDigits = countTrailingDigits(label);
|
|
@@ -1518,7 +1521,7 @@ var DotNS = class {
|
|
|
1518
1521
|
}
|
|
1519
1522
|
return { ...candidate, signerFreeBalance: effectiveBalance, feeFloor, toppedUp };
|
|
1520
1523
|
}
|
|
1521
|
-
async register(label, options = {}) {
|
|
1524
|
+
async register(label, options = {}, _cli = runDotnsCli) {
|
|
1522
1525
|
return withSpan("deploy.dotns.register", `2a. register ${label}.dot`, {}, async () => {
|
|
1523
1526
|
if (!this.connected) await this.connect(options);
|
|
1524
1527
|
label = validateDomainLabel(label);
|
|
@@ -1580,7 +1583,7 @@ var DotNS = class {
|
|
|
1580
1583
|
}
|
|
1581
1584
|
const runRegister = async (bufferSeconds) => {
|
|
1582
1585
|
const env = bufferSeconds ? { ...authEnv, DOTNS_COMMITMENT_BUFFER: bufferSeconds } : authEnv;
|
|
1583
|
-
return await
|
|
1586
|
+
return await _cli(
|
|
1584
1587
|
["register", "domain", "-n", label, "--json", ...statusArgs, ...reverseArgs, ...rpcFlag(this.rpc)],
|
|
1585
1588
|
env
|
|
1586
1589
|
);
|
|
@@ -1590,17 +1593,16 @@ var DotNS = class {
|
|
|
1590
1593
|
result = await runRegister();
|
|
1591
1594
|
} catch (err) {
|
|
1592
1595
|
const msg = err.message;
|
|
1593
|
-
if (
|
|
1596
|
+
if (!isLikelyCommitmentRace(msg)) throw err;
|
|
1594
1597
|
const retryBuffer = userSetBuffer ? void 0 : "60";
|
|
1595
|
-
console.log(`
|
|
1598
|
+
console.log(` register reverted on first attempt \u2014 retrying once${retryBuffer ? ` with DOTNS_COMMITMENT_BUFFER=${retryBuffer}s` : ""} (commit-reveal race; block-time lag typically resolves within a block or two).`);
|
|
1596
1599
|
try {
|
|
1597
1600
|
result = await runRegister(retryBuffer);
|
|
1598
1601
|
} catch (retryErr) {
|
|
1599
1602
|
const retryMsg = retryErr.message;
|
|
1600
|
-
if (
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
);
|
|
1603
|
+
if (!isLikelyCommitmentRace(retryMsg)) throw retryErr;
|
|
1604
|
+
const likelyCause = /CommitmentTooNew/i.test(retryMsg) ? `the chain's block timestamps are lagging wall-clock by more than 30s across two register attempts. This is usually a transient block-production slowdown. Retry in a minute, or set DOTNS_COMMITMENT_BUFFER=60 (or higher) to absorb longer drift. Upstream fix tracked at paritytech/dotns-sdk#105.` : `the register tx reverted twice in a row. This is typically a commit-reveal timing race (block-production slowdown), but could also be a contract rejection (label already taken, PoP status mismatch). Try again in a minute; if it persists, verify the label is available. Upstream: paritytech/dotns-sdk#105.`;
|
|
1605
|
+
throw new Error(`DotNS register failed after retry: ${likelyCause} Underlying: ${retryMsg}`);
|
|
1604
1606
|
}
|
|
1605
1607
|
}
|
|
1606
1608
|
console.log(`
|
|
@@ -1651,6 +1653,7 @@ export {
|
|
|
1651
1653
|
validateDomainLabel,
|
|
1652
1654
|
isCommitmentMature,
|
|
1653
1655
|
isExplicitCommitmentBuffer,
|
|
1656
|
+
isLikelyCommitmentRace,
|
|
1654
1657
|
classifyDotnsLabel,
|
|
1655
1658
|
canRegister,
|
|
1656
1659
|
simulateUserStatus,
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MGTWZ6XS.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
getCurrentSentryTraceId
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5P7EZSOU.js";
|
|
10
10
|
|
|
11
11
|
// src/bug-report.ts
|
|
12
12
|
import { execSync, execFileSync } from "child_process";
|
|
@@ -18,10 +18,10 @@ import {
|
|
|
18
18
|
} from "./chunk-S7EM5VMW.js";
|
|
19
19
|
import {
|
|
20
20
|
setDeployContext
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-S2WGWNP5.js";
|
|
22
22
|
import {
|
|
23
23
|
probeChunks
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-GHBHQP4S.js";
|
|
25
25
|
import {
|
|
26
26
|
packSection
|
|
27
27
|
} from "./chunk-C2TS5MER.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
parseDomainName,
|
|
33
33
|
popStatusName,
|
|
34
34
|
verifyNonceAdvanced
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-OLU6VQG2.js";
|
|
36
36
|
import {
|
|
37
37
|
derivePoolAccounts,
|
|
38
38
|
detectTestnet,
|
|
@@ -54,12 +54,12 @@ import {
|
|
|
54
54
|
truncateAddress,
|
|
55
55
|
withDeploySpan,
|
|
56
56
|
withSpan
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-5P7EZSOU.js";
|
|
58
58
|
import {
|
|
59
59
|
DEFAULT_ENV_ID,
|
|
60
60
|
loadEnvironments,
|
|
61
61
|
resolveEndpoints
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-X3F7WHSF.js";
|
|
63
63
|
import {
|
|
64
64
|
NonRetryableError
|
|
65
65
|
} from "./chunk-ZOC4GITL.js";
|
|
@@ -74,7 +74,7 @@ import * as fs2 from "fs";
|
|
|
74
74
|
import * as path2 from "path";
|
|
75
75
|
import { execSync as execSync2 } from "child_process";
|
|
76
76
|
import { importer } from "ipfs-unixfs-importer";
|
|
77
|
-
import { CarReader } from "@ipld/car/reader";
|
|
77
|
+
import { CarReader as CarReader2 } from "@ipld/car/reader";
|
|
78
78
|
import { CarWriter } from "@ipld/car/writer";
|
|
79
79
|
import { CID as CID2 } from "multiformats/cid";
|
|
80
80
|
import * as dagPB2 from "@ipld/dag-pb";
|
|
@@ -101,6 +101,7 @@ import { cryptoWaitReady } from "@polkadot/util-crypto";
|
|
|
101
101
|
import { getPolkadotSigner } from "polkadot-api/signer";
|
|
102
102
|
import { sr25519CreateDerive } from "@polkadot-labs/hdkd";
|
|
103
103
|
import { mnemonicToEntropy, entropyToMiniSecret, ss58Address } from "@polkadot-labs/hdkd-helpers";
|
|
104
|
+
import { CarReader } from "@ipld/car/reader";
|
|
104
105
|
function friendlyChainError(msg) {
|
|
105
106
|
if (/"type":\s*"Invalid"[\s\S]*?"type":\s*"Payment"/i.test(msg)) {
|
|
106
107
|
return "Bulletin quota exhausted (signed extension rejected the tx \u2014 signer is out of allowed txs or bytes; grant quota on-chain)";
|
|
@@ -406,6 +407,23 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
406
407
|
ss58 = provider.ss58;
|
|
407
408
|
ownsClient = true;
|
|
408
409
|
}
|
|
410
|
+
if (existingClient && reconnect) {
|
|
411
|
+
try {
|
|
412
|
+
await unsafeApi.query.System.Number.getValue();
|
|
413
|
+
} catch (e) {
|
|
414
|
+
if (isConnectionError(e)) {
|
|
415
|
+
console.log("\n Connection lost (stale client detected by pre-upload probe), reconnecting...");
|
|
416
|
+
const fresh = await reconnect();
|
|
417
|
+
client = fresh.client;
|
|
418
|
+
unsafeApi = fresh.unsafeApi;
|
|
419
|
+
signer = fresh.signer;
|
|
420
|
+
ss58 = fresh.ss58;
|
|
421
|
+
ownsClient = true;
|
|
422
|
+
} else {
|
|
423
|
+
throw e;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
409
427
|
const requiredTxs = BigInt(chunks.length + 1);
|
|
410
428
|
const requiredBytes = BigInt(totalBytes);
|
|
411
429
|
const [uploadAuth, currentBlockNum] = await Promise.all([
|
|
@@ -607,6 +625,9 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
607
625
|
}
|
|
608
626
|
}
|
|
609
627
|
if (!retried) {
|
|
628
|
+
if (isConnectionError(fail.error) && reconnectionsUsed >= MAX_RECONNECTIONS) {
|
|
629
|
+
throw new Error(`Connection lost and max reconnections (${MAX_RECONNECTIONS}) exhausted`);
|
|
630
|
+
}
|
|
610
631
|
throw new Error(`Chunk ${fail.index + 1} failed after ${MAX_CHUNK_RETRIES} retries: ${fail.error?.message?.slice(0, 100)}`);
|
|
611
632
|
}
|
|
612
633
|
}
|
|
@@ -699,7 +720,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
699
720
|
}
|
|
700
721
|
}
|
|
701
722
|
if (ownsClient) client.destroy();
|
|
702
|
-
return { storageCid: result, tier2Verified, tier2Inconclusive, tier2Fallback: fallbackStored.length };
|
|
723
|
+
return { storageCid: result, tier2Verified, tier2Inconclusive, tier2Fallback: fallbackStored.length, liveProvider: { client, unsafeApi, signer, ss58 } };
|
|
703
724
|
} catch (e) {
|
|
704
725
|
if (ownsClient) client.destroy();
|
|
705
726
|
throw e;
|
|
@@ -972,6 +993,7 @@ async function storeDirectoryV2(directoryPath, opts = {}) {
|
|
|
972
993
|
totalSize: `${(phaseA.carBytes.length / 1024 / 1024).toFixed(2)} MB`
|
|
973
994
|
});
|
|
974
995
|
const carMbA = String(Math.round(phaseA.carBytes.length / 1024 / 1024 * 100) / 100);
|
|
996
|
+
let phaseALiveProvider = provider;
|
|
975
997
|
await withSpan("deploy.chunk-upload", "1b. chunk-upload (phase A)", {
|
|
976
998
|
"deploy.chunks.total": carChunksA.length,
|
|
977
999
|
"deploy.chunks.skipped": skipCids.size,
|
|
@@ -979,7 +1001,8 @@ async function storeDirectoryV2(directoryPath, opts = {}) {
|
|
|
979
1001
|
"deploy.car.mb": carMbA
|
|
980
1002
|
}, async () => {
|
|
981
1003
|
sampleMemory("chunk_upload_start");
|
|
982
|
-
await storeChunkedContent(carChunksA, { ...provider, gateway, skipCids, probeFailedCids: probeFailedCidsA });
|
|
1004
|
+
const phaseAUpload = await storeChunkedContent(carChunksA, { ...provider, gateway, skipCids, probeFailedCids: probeFailedCidsA });
|
|
1005
|
+
phaseALiveProvider = { ...provider, ...phaseAUpload.liveProvider };
|
|
983
1006
|
sampleMemory("chunk_upload_end");
|
|
984
1007
|
});
|
|
985
1008
|
const phaseAKnownPresent = new Set(carChunkCidsA);
|
|
@@ -1013,6 +1036,9 @@ async function storeDirectoryV2(directoryPath, opts = {}) {
|
|
|
1013
1036
|
blocks: blocksList,
|
|
1014
1037
|
chunks: chunksMap
|
|
1015
1038
|
});
|
|
1039
|
+
phaseA.blocks.clear();
|
|
1040
|
+
carChunksA.length = 0;
|
|
1041
|
+
phaseA.carBytes = new Uint8Array(0);
|
|
1016
1042
|
const phaseB = await withSpan("deploy.merkleize", "1c. merkleize (js, finalise)", { "deploy.directory": dirBasename }, async () => {
|
|
1017
1043
|
const r = await merkleizeWithStableOrder(directoryPath, phaseA.stableOrder, { useKubo });
|
|
1018
1044
|
sampleMemory("merkleize_finalise_end");
|
|
@@ -1038,7 +1064,7 @@ async function storeDirectoryV2(directoryPath, opts = {}) {
|
|
|
1038
1064
|
"deploy.car.mb": carMbB
|
|
1039
1065
|
}, async () => {
|
|
1040
1066
|
sampleMemory("chunk_upload_b_start");
|
|
1041
|
-
const r = await storeChunkedContent(carChunksB, { ...
|
|
1067
|
+
const r = await storeChunkedContent(carChunksB, { ...phaseALiveProvider, gateway, skipCids: skipCidsB, probeFailedCids: probeFailedCidsA });
|
|
1042
1068
|
sampleMemory("chunk_upload_b_end");
|
|
1043
1069
|
return r;
|
|
1044
1070
|
});
|
|
@@ -1175,7 +1201,8 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
1175
1201
|
console.log("=".repeat(60));
|
|
1176
1202
|
console.log(` Domain: ${name}.dot`);
|
|
1177
1203
|
if (deployTag) console.log(` Tag: ${deployTag}`);
|
|
1178
|
-
if (
|
|
1204
|
+
if (options.inputCar) console.log(` Input CAR: ${path.resolve(options.inputCar)}`);
|
|
1205
|
+
else if (typeof content === "string") console.log(` Build dir: ${path.resolve(content)}`);
|
|
1179
1206
|
if (process.env.CI) console.log(` Runner: ${resolveRunner()} (${resolveRunnerType()})`);
|
|
1180
1207
|
if (options.password) console.log(` Encrypted: yes`);
|
|
1181
1208
|
let provider;
|
|
@@ -1243,7 +1270,38 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
1243
1270
|
console.log("Storage");
|
|
1244
1271
|
console.log("=".repeat(60));
|
|
1245
1272
|
await withSpan("deploy.storage", "1. storage", {}, async () => {
|
|
1246
|
-
if (
|
|
1273
|
+
if (options.inputCar) {
|
|
1274
|
+
const carPath = path.resolve(options.inputCar);
|
|
1275
|
+
if (!fs.existsSync(carPath)) throw new Error(`CAR file not found: ${carPath}`);
|
|
1276
|
+
console.log(`
|
|
1277
|
+
Mode: Pre-built CAR`);
|
|
1278
|
+
console.log(` Path: ${carPath}`);
|
|
1279
|
+
let carContent = fs.readFileSync(carPath);
|
|
1280
|
+
console.log(` Size: ${(carContent.length / 1024 / 1024).toFixed(2)} MB`);
|
|
1281
|
+
const reader = await CarReader.fromBytes(carContent);
|
|
1282
|
+
const roots = await reader.getRoots();
|
|
1283
|
+
if (roots.length === 0) throw new Error("CAR file has no roots");
|
|
1284
|
+
ipfsCid = roots[0].toString();
|
|
1285
|
+
console.log(` Root CID: ${ipfsCid}`);
|
|
1286
|
+
if (options.password) {
|
|
1287
|
+
console.log(` Encrypting CAR file...`);
|
|
1288
|
+
carContent = await encryptContent(carContent, options.password);
|
|
1289
|
+
console.log(` Encrypted: ${(carContent.length / 1024 / 1024).toFixed(2)} MB`);
|
|
1290
|
+
}
|
|
1291
|
+
const carChunks = chunk(carContent, CHUNK_SIZE);
|
|
1292
|
+
const predictedStorageCid = computeStorageCid(carChunks);
|
|
1293
|
+
if (options.ghPagesMirror) {
|
|
1294
|
+
mirrorPromise = mirrorToGitHubPages({
|
|
1295
|
+
domain: name,
|
|
1296
|
+
carBytes: carContent,
|
|
1297
|
+
cid: predictedStorageCid,
|
|
1298
|
+
toolVersion: VERSION,
|
|
1299
|
+
bulletinRpc: BULLETIN_ENDPOINTS[0],
|
|
1300
|
+
encrypted: Boolean(options.password)
|
|
1301
|
+
}).catch((err) => err instanceof Error ? err : new Error(String(err)));
|
|
1302
|
+
}
|
|
1303
|
+
cid = (await storeChunkedContent(carChunks, providerWithReconnect)).storageCid;
|
|
1304
|
+
} else if (process.env.IPFS_CID) {
|
|
1247
1305
|
if (options.password) {
|
|
1248
1306
|
throw new Error(
|
|
1249
1307
|
"IPFS_CID and --password are mutually exclusive: IPFS_CID skips the upload step, so there is nothing to encrypt. Either unset IPFS_CID to upload and encrypt fresh content, or remove --password to reuse the existing CID as-is."
|
|
@@ -1591,7 +1649,7 @@ async function merkleizeKuboBackend(directoryPath) {
|
|
|
1591
1649
|
).trim();
|
|
1592
1650
|
execSync2(`ipfs dag export ${cidStr} > "${carPath}"`);
|
|
1593
1651
|
const carBytes = fs2.readFileSync(carPath);
|
|
1594
|
-
const reader = await
|
|
1652
|
+
const reader = await CarReader2.fromBytes(carBytes);
|
|
1595
1653
|
const blocks = /* @__PURE__ */ new Map();
|
|
1596
1654
|
for await (const { cid, bytes } of reader.blocks()) {
|
|
1597
1655
|
blocks.set(cid.toString(), bytes);
|
|
@@ -7,7 +7,7 @@ import * as fs from "fs/promises";
|
|
|
7
7
|
import * as path from "path";
|
|
8
8
|
import * as os from "os";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
|
-
var DEFAULT_ENVIRONMENTS_URL = "https://raw.githubusercontent.com/paritytech/
|
|
10
|
+
var DEFAULT_ENVIRONMENTS_URL = "https://raw.githubusercontent.com/paritytech/triangle-deploy/main/assets/environments.json";
|
|
11
11
|
var DEFAULT_ENV_ID = "paseo-next";
|
|
12
12
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
13
13
|
var FETCH_TIMEOUT_MS = 5e3;
|
package/dist/chunk-probe.js
CHANGED
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
_decodeStorageValue,
|
|
6
6
|
_resetProbeSession,
|
|
7
7
|
probeChunks
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-GHBHQP4S.js";
|
|
9
|
+
import "./chunk-5P7EZSOU.js";
|
|
10
|
+
import "./chunk-2IMBCUB2.js";
|
|
11
11
|
import "./chunk-QGM4M3NI.js";
|
|
12
12
|
export {
|
|
13
13
|
ChainProbeCrossValidationError,
|
package/dist/deploy.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ declare function storeChunkedContent(chunks: Uint8Array[], { client: existingCli
|
|
|
68
68
|
tier2Verified: number;
|
|
69
69
|
tier2Inconclusive: number;
|
|
70
70
|
tier2Fallback: number;
|
|
71
|
+
liveProvider: ExistingProvider;
|
|
71
72
|
}>;
|
|
72
73
|
declare function chunk(data: Uint8Array, size?: number): Uint8Array[];
|
|
73
74
|
declare function hasIPFS(): boolean;
|
|
@@ -170,6 +171,13 @@ interface DeployOptions {
|
|
|
170
171
|
description?: string;
|
|
171
172
|
/** Skip the 500 MiB abort guard and allow oversized deploys. */
|
|
172
173
|
allowLargeDeploy?: boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Filesystem path to a pre-built `.car` file. When set, skips directory
|
|
176
|
+
* scanning and merkleization; the CAR bytes are read from disk, the root
|
|
177
|
+
* CID is parsed from the CAR header, and the file is uploaded directly.
|
|
178
|
+
* The positional `<build-dir>` argument is not required when this is set.
|
|
179
|
+
*/
|
|
180
|
+
inputCar?: string;
|
|
173
181
|
/**
|
|
174
182
|
* Pin the `deployedAt` timestamp for byte-identical rebuilds.
|
|
175
183
|
* Values: "commit" (git committer date), "epoch:<N>" (Unix epoch seconds),
|
package/dist/deploy.js
CHANGED
|
@@ -32,20 +32,20 @@ import {
|
|
|
32
32
|
storeDirectory,
|
|
33
33
|
storeDirectoryV2,
|
|
34
34
|
storeFile
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-WMSBC5B2.js";
|
|
36
36
|
import "./chunk-MJTQOXBC.js";
|
|
37
37
|
import "./chunk-KOSF5FDO.js";
|
|
38
38
|
import "./chunk-5MRZ3V4A.js";
|
|
39
39
|
import "./chunk-S7EM5VMW.js";
|
|
40
|
-
import "./chunk-
|
|
41
|
-
import "./chunk-
|
|
42
|
-
import "./chunk-
|
|
40
|
+
import "./chunk-S2WGWNP5.js";
|
|
41
|
+
import "./chunk-MGTWZ6XS.js";
|
|
42
|
+
import "./chunk-GHBHQP4S.js";
|
|
43
43
|
import "./chunk-C2TS5MER.js";
|
|
44
|
-
import "./chunk-
|
|
44
|
+
import "./chunk-OLU6VQG2.js";
|
|
45
45
|
import "./chunk-VOEFHED3.js";
|
|
46
|
-
import "./chunk-
|
|
47
|
-
import "./chunk-
|
|
48
|
-
import "./chunk-
|
|
46
|
+
import "./chunk-5P7EZSOU.js";
|
|
47
|
+
import "./chunk-2IMBCUB2.js";
|
|
48
|
+
import "./chunk-X3F7WHSF.js";
|
|
49
49
|
import {
|
|
50
50
|
EXIT_CODE_NO_RETRY,
|
|
51
51
|
NonRetryableError
|
package/dist/dotns.d.ts
CHANGED
|
@@ -122,6 +122,7 @@ declare function sanitizeDomainLabel(label: string): string;
|
|
|
122
122
|
declare function validateDomainLabel(label: string): string;
|
|
123
123
|
declare function isCommitmentMature(chainNowSeconds: number, commitTimestampSeconds: number, minimumAgeSeconds: number): boolean;
|
|
124
124
|
declare function isExplicitCommitmentBuffer(envValue: string | undefined): boolean;
|
|
125
|
+
declare function isLikelyCommitmentRace(msg: string): boolean;
|
|
125
126
|
declare function classifyDotnsLabel(label: string): {
|
|
126
127
|
status: number;
|
|
127
128
|
message: string;
|
|
@@ -233,7 +234,7 @@ declare class DotNS {
|
|
|
233
234
|
register(label: string, options?: DotNSConnectOptions & {
|
|
234
235
|
status?: string;
|
|
235
236
|
reverse?: boolean;
|
|
236
|
-
}): Promise<{
|
|
237
|
+
}, _cli?: (argv: string[], env?: Record<string, string>) => Promise<unknown>): Promise<{
|
|
237
238
|
label: string;
|
|
238
239
|
owner: string;
|
|
239
240
|
}>;
|
|
@@ -241,4 +242,4 @@ declare class DotNS {
|
|
|
241
242
|
}
|
|
242
243
|
declare const dotns: DotNS;
|
|
243
244
|
|
|
244
|
-
export { CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsCliInvocation, type DotnsCliInvocationSource, type DotnsPreflightResult, type DotnsSuccessAction, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, WS_HEARTBEAT_TIMEOUT_MS, canRegister, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertWeiToNative, countTrailingDigits, dotns, feeFloorFor, fetchNonce, fmtPas, isCommitmentMature, isExplicitCommitmentBuffer, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, resolveDotnsCliInvocation, runDotnsCli, sanitizeDomainLabel, simulateUserStatus, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced };
|
|
245
|
+
export { CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsCliInvocation, type DotnsCliInvocationSource, type DotnsPreflightResult, type DotnsSuccessAction, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, WS_HEARTBEAT_TIMEOUT_MS, canRegister, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertWeiToNative, countTrailingDigits, dotns, feeFloorFor, fetchNonce, fmtPas, isCommitmentMature, isExplicitCommitmentBuffer, isLikelyCommitmentRace, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, resolveDotnsCliInvocation, runDotnsCli, sanitizeDomainLabel, simulateUserStatus, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced };
|
package/dist/dotns.js
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
fmtPas,
|
|
27
27
|
isCommitmentMature,
|
|
28
28
|
isExplicitCommitmentBuffer,
|
|
29
|
+
isLikelyCommitmentRace,
|
|
29
30
|
parseDomainName,
|
|
30
31
|
parseProofOfPersonhoodStatus,
|
|
31
32
|
popStatusName,
|
|
@@ -36,10 +37,10 @@ import {
|
|
|
36
37
|
stripTrailingDigits,
|
|
37
38
|
validateDomainLabel,
|
|
38
39
|
verifyNonceAdvanced
|
|
39
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-OLU6VQG2.js";
|
|
40
41
|
import "./chunk-VOEFHED3.js";
|
|
41
|
-
import "./chunk-
|
|
42
|
-
import "./chunk-
|
|
42
|
+
import "./chunk-5P7EZSOU.js";
|
|
43
|
+
import "./chunk-2IMBCUB2.js";
|
|
43
44
|
import "./chunk-QGM4M3NI.js";
|
|
44
45
|
export {
|
|
45
46
|
CONNECTION_TIMEOUT_MS,
|
|
@@ -69,6 +70,7 @@ export {
|
|
|
69
70
|
fmtPas,
|
|
70
71
|
isCommitmentMature,
|
|
71
72
|
isExplicitCommitmentBuffer,
|
|
73
|
+
isLikelyCommitmentRace,
|
|
72
74
|
parseDomainName,
|
|
73
75
|
parseProofOfPersonhoodStatus,
|
|
74
76
|
popStatusName,
|
package/dist/environments.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const DEFAULT_ENVIRONMENTS_URL = "https://raw.githubusercontent.com/paritytech/
|
|
1
|
+
declare const DEFAULT_ENVIRONMENTS_URL = "https://raw.githubusercontent.com/paritytech/triangle-deploy/main/assets/environments.json";
|
|
2
2
|
declare const DEFAULT_ENV_ID = "paseo-next";
|
|
3
3
|
declare const CACHE_TTL_MS: number;
|
|
4
4
|
declare const FETCH_TIMEOUT_MS = 5000;
|
package/dist/environments.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
deploy,
|
|
3
3
|
merkleizeJS,
|
|
4
4
|
merkleizeWithStableOrder
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WMSBC5B2.js";
|
|
6
6
|
import {
|
|
7
7
|
computeStats,
|
|
8
8
|
renderSummary,
|
|
@@ -24,16 +24,16 @@ import {
|
|
|
24
24
|
isVolatilePath,
|
|
25
25
|
parseManifest
|
|
26
26
|
} from "./chunk-S7EM5VMW.js";
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-S2WGWNP5.js";
|
|
28
|
+
import "./chunk-MGTWZ6XS.js";
|
|
29
29
|
import {
|
|
30
30
|
probeChunks
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-GHBHQP4S.js";
|
|
32
32
|
import "./chunk-C2TS5MER.js";
|
|
33
33
|
import {
|
|
34
34
|
DotNS,
|
|
35
35
|
parseDomainName
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-OLU6VQG2.js";
|
|
37
37
|
import {
|
|
38
38
|
bootstrapPool,
|
|
39
39
|
derivePoolAccounts,
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
fetchPoolAuthorizations,
|
|
42
42
|
selectAccount
|
|
43
43
|
} from "./chunk-VOEFHED3.js";
|
|
44
|
-
import "./chunk-
|
|
44
|
+
import "./chunk-5P7EZSOU.js";
|
|
45
45
|
import {
|
|
46
46
|
VERSION,
|
|
47
47
|
loadRunState,
|
|
@@ -51,8 +51,8 @@ import {
|
|
|
51
51
|
shouldSkipStaleWarning,
|
|
52
52
|
stateFilePath,
|
|
53
53
|
writeRunState
|
|
54
|
-
} from "./chunk-
|
|
55
|
-
import "./chunk-
|
|
54
|
+
} from "./chunk-2IMBCUB2.js";
|
|
55
|
+
import "./chunk-X3F7WHSF.js";
|
|
56
56
|
import "./chunk-ZOC4GITL.js";
|
|
57
57
|
import "./chunk-HOTQDYHD.js";
|
|
58
58
|
import "./chunk-QGM4M3NI.js";
|
package/dist/memory-report.d.ts
CHANGED
package/dist/memory-report.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
maybeWriteMemoryReport,
|
|
6
6
|
safeHeap,
|
|
7
7
|
sampleFromBytes
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-5P7EZSOU.js";
|
|
9
|
+
import "./chunk-2IMBCUB2.js";
|
|
10
10
|
import "./chunk-QGM4M3NI.js";
|
|
11
11
|
export {
|
|
12
12
|
DEFAULT_THRESHOLD_MB,
|
package/dist/merkle.js
CHANGED
|
@@ -5,20 +5,20 @@ import {
|
|
|
5
5
|
merkleizeJSBackend,
|
|
6
6
|
merkleizeKuboBackend,
|
|
7
7
|
merkleizeWithStableOrder
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WMSBC5B2.js";
|
|
9
9
|
import "./chunk-MJTQOXBC.js";
|
|
10
10
|
import "./chunk-KOSF5FDO.js";
|
|
11
11
|
import "./chunk-5MRZ3V4A.js";
|
|
12
12
|
import "./chunk-S7EM5VMW.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-S2WGWNP5.js";
|
|
14
|
+
import "./chunk-MGTWZ6XS.js";
|
|
15
|
+
import "./chunk-GHBHQP4S.js";
|
|
16
16
|
import "./chunk-C2TS5MER.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-OLU6VQG2.js";
|
|
18
18
|
import "./chunk-VOEFHED3.js";
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-5P7EZSOU.js";
|
|
20
|
+
import "./chunk-2IMBCUB2.js";
|
|
21
|
+
import "./chunk-X3F7WHSF.js";
|
|
22
22
|
import "./chunk-ZOC4GITL.js";
|
|
23
23
|
import "./chunk-HOTQDYHD.js";
|
|
24
24
|
import "./chunk-QGM4M3NI.js";
|
package/dist/run-state.js
CHANGED
package/dist/telemetry.js
CHANGED
package/dist/version-check.js
CHANGED
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
isPreReleaseVersion,
|
|
9
9
|
preReleaseWarning,
|
|
10
10
|
promptYesNo
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-MGTWZ6XS.js";
|
|
12
|
+
import "./chunk-5P7EZSOU.js";
|
|
13
|
+
import "./chunk-2IMBCUB2.js";
|
|
14
14
|
import "./chunk-QGM4M3NI.js";
|
|
15
15
|
export {
|
|
16
16
|
assessVersion,
|
package/docs/telemetry.md
CHANGED
|
@@ -29,8 +29,11 @@ If another app embeds `bulletin-deploy` and already owns Sentry initialization,
|
|
|
29
29
|
```sh
|
|
30
30
|
BULLETIN_DEPLOY_USE_AMBIENT_SENTRY=1
|
|
31
31
|
BULLETIN_DEPLOY_HOST_APP=<your-app-name>
|
|
32
|
+
BULLETIN_DEPLOY_HOST_APP_VERSION=<your-app-version>
|
|
32
33
|
```
|
|
33
34
|
|
|
35
|
+
`BULLETIN_DEPLOY_HOST_APP_VERSION` is optional but recommended — it populates `deploy.host_app_version` on every span, enabling version-correlated triage in the dashboard.
|
|
36
|
+
|
|
34
37
|
That makes `bulletin-deploy` reuse the existing Sentry client instead of calling its own `Sentry.init()`.
|
|
35
38
|
|
|
36
39
|
Requirements:
|