bulletin-deploy 0.6.7 → 0.6.8-rc.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/README.md +20 -2
- package/bin/bulletin-deploy +11 -0
- package/dist/bug-report.d.ts +14 -0
- package/dist/bug-report.js +108 -0
- package/dist/{chunk-TD73EZ5I.js → chunk-AUTRMT26.js} +2 -2
- package/dist/{chunk-FBXG7YMT.js → chunk-FI2IKRB7.js} +1 -1
- package/dist/chunk-GCAPBR6G.js +146 -0
- package/dist/{chunk-ZGP4DMFK.js → chunk-GJVD4HRJ.js} +7 -3
- package/dist/deploy.js +3 -3
- package/dist/dotns.js +2 -2
- package/dist/index.js +3 -3
- package/dist/telemetry.js +1 -1
- package/dist/version-check.d.ts +31 -0
- package/dist/version-check.js +20 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -135,6 +135,7 @@ If you see **"Requires Full Personhood verification"**, the deploy will fail ear
|
|
|
135
135
|
|---|---|---|
|
|
136
136
|
| `BULLETIN_RPC` | `wss://paseo-bulletin-rpc.polkadot.io` | Bulletin chain WebSocket RPC |
|
|
137
137
|
| `BULLETIN_DEPLOY_TELEMETRY` | `1` (enabled) | Set to `0` to disable Sentry telemetry |
|
|
138
|
+
| `BULLETIN_DEPLOY_UPDATE_CHECK` | `1` (enabled) | Set to `0` to disable version check on errors |
|
|
138
139
|
| `DOTNS_STATUS` | `full` (testnet) / `none` (mainnet) | PoP level to self-grant before registration: `none`, `lite`, or `full` |
|
|
139
140
|
| `IPFS_CID` | _(none)_ | Skip storage, use pre-existing CID |
|
|
140
141
|
|
|
@@ -202,6 +203,22 @@ Instead of using a single account for all storage transactions, bulletin-deploy
|
|
|
202
203
|
|
|
203
204
|
When a pool account's authorization drops below thresholds (50 transactions or 50MB), bulletin-deploy automatically tops it up by submitting an `authorize_account` transaction from Alice.
|
|
204
205
|
|
|
206
|
+
## Version Checking
|
|
207
|
+
|
|
208
|
+
When a deploy fails, bulletin-deploy checks whether a newer version is available. This helps catch cases where the error was already fixed in a later release.
|
|
209
|
+
|
|
210
|
+
Two sources are checked in parallel:
|
|
211
|
+
- **npm registry** — reads the `minimumVersion` field from the latest published version
|
|
212
|
+
- **GitHub kill switch** (`min-version.json` in the repo) — allows emergency deprecation without a release
|
|
213
|
+
|
|
214
|
+
If either source indicates your version is below the minimum, the CLI tells you the version is unsupported and why. If you're simply outdated (but above the minimum), you get a suggestion to update.
|
|
215
|
+
|
|
216
|
+
For **paritytech** contributors in an interactive terminal, the CLI offers to update and retry automatically. For everyone else (external users, CI), it prints the update command and exits.
|
|
217
|
+
|
|
218
|
+
If you're already on the latest version and hit an error, the CLI offers to open a GitHub issue with collected debug info (paritytech contributors only).
|
|
219
|
+
|
|
220
|
+
Set `BULLETIN_DEPLOY_UPDATE_CHECK=0` to disable version checking.
|
|
221
|
+
|
|
205
222
|
## Telemetry
|
|
206
223
|
|
|
207
224
|
Sentry telemetry is enabled by default for deploy observability. Set `BULLETIN_DEPLOY_TELEMETRY=0` to disable.
|
|
@@ -212,10 +229,11 @@ What's tracked:
|
|
|
212
229
|
- DotNS phase timing (registration, contenthash update)
|
|
213
230
|
- Pool account selection
|
|
214
231
|
- Source metadata (repo, branch, PR number, CI vs local)
|
|
232
|
+
- Tool version (`deploy.tool_version`)
|
|
215
233
|
|
|
216
234
|
Dashboard:
|
|
217
|
-
- Bulletin Deploy Health: https://paritytech.sentry.io/dashboard/1669817
|
|
218
|
-
- Deploy Failures Detail: https://paritytech.sentry.io/dashboard/1669818
|
|
235
|
+
- Bulletin Deploy Health: https://paritytech.sentry.io/dashboard/1669817/?project=4511093597405264
|
|
236
|
+
- Deploy Failures Detail: https://paritytech.sentry.io/dashboard/1669818/?project=4511093597405264
|
|
219
237
|
|
|
220
238
|
## Troubleshooting
|
|
221
239
|
|
package/bin/bulletin-deploy
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import { deploy, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, NonRetryableError, EXIT_CODE_NO_RETRY } from "../dist/deploy.js";
|
|
4
4
|
import { bootstrapPool } from "../dist/pool.js";
|
|
5
5
|
import { VERSION } from "../dist/telemetry.js";
|
|
6
|
+
import { handleFailedDeploy } from "../dist/version-check.js";
|
|
7
|
+
import { setDeployContext } from "../dist/bug-report.js";
|
|
6
8
|
import * as fs from "fs";
|
|
7
9
|
|
|
8
10
|
const args = process.argv.slice(2);
|
|
@@ -57,6 +59,14 @@ try {
|
|
|
57
59
|
if (!domain) { console.error("Error: domain required (e.g. my-app.dot)"); process.exit(1); }
|
|
58
60
|
if (!fs.existsSync(buildDir)) { console.error(`Error: ${buildDir} does not exist`); process.exit(1); }
|
|
59
61
|
|
|
62
|
+
setDeployContext({
|
|
63
|
+
domain,
|
|
64
|
+
rpc: flags.rpc,
|
|
65
|
+
repo: process.env.GITHUB_REPOSITORY,
|
|
66
|
+
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME,
|
|
67
|
+
signerMode: flags.mnemonic ? "direct" : "pool",
|
|
68
|
+
});
|
|
69
|
+
|
|
60
70
|
const result = await deploy(buildDir, domain, {
|
|
61
71
|
playground: flags.playground,
|
|
62
72
|
mnemonic: flags.mnemonic,
|
|
@@ -79,5 +89,6 @@ try {
|
|
|
79
89
|
} catch (error) {
|
|
80
90
|
const noRetry = error instanceof NonRetryableError;
|
|
81
91
|
console.error(`Deployment failed${noRetry ? " (not retryable)" : ""}:`, error.message);
|
|
92
|
+
await handleFailedDeploy(error);
|
|
82
93
|
process.exit(noRetry ? EXIT_CODE_NO_RETRY : 1);
|
|
83
94
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface DeployContext {
|
|
2
|
+
domain?: string;
|
|
3
|
+
repo?: string;
|
|
4
|
+
branch?: string;
|
|
5
|
+
signerMode?: string;
|
|
6
|
+
chunkCount?: number;
|
|
7
|
+
totalSize?: string;
|
|
8
|
+
rpc?: string;
|
|
9
|
+
sentryTraceId?: string;
|
|
10
|
+
}
|
|
11
|
+
declare function setDeployContext(ctx: Partial<DeployContext>): void;
|
|
12
|
+
declare function offerBugReport(error: Error): Promise<void>;
|
|
13
|
+
|
|
14
|
+
export { offerBugReport, setDeployContext };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {
|
|
2
|
+
classifyErrorArea,
|
|
3
|
+
isInteractive,
|
|
4
|
+
promptYesNo
|
|
5
|
+
} from "./chunk-GCAPBR6G.js";
|
|
6
|
+
import {
|
|
7
|
+
VERSION
|
|
8
|
+
} from "./chunk-GJVD4HRJ.js";
|
|
9
|
+
import "./chunk-QGM4M3NI.js";
|
|
10
|
+
|
|
11
|
+
// src/bug-report.ts
|
|
12
|
+
import { execSync, execFileSync } from "child_process";
|
|
13
|
+
import * as os from "os";
|
|
14
|
+
var _deployContext = {};
|
|
15
|
+
function setDeployContext(ctx) {
|
|
16
|
+
_deployContext = { ..._deployContext, ...ctx };
|
|
17
|
+
}
|
|
18
|
+
function hasGhCli() {
|
|
19
|
+
try {
|
|
20
|
+
execSync("gh --version", { stdio: "pipe" });
|
|
21
|
+
return true;
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function buildReportBody(error) {
|
|
27
|
+
const lines = [
|
|
28
|
+
"## Environment",
|
|
29
|
+
"",
|
|
30
|
+
`- **bulletin-deploy**: ${VERSION}`,
|
|
31
|
+
`- **Node.js**: ${process.version}`,
|
|
32
|
+
`- **OS**: ${os.platform()} ${os.arch()} ${os.release()}`,
|
|
33
|
+
"",
|
|
34
|
+
"## Error",
|
|
35
|
+
"",
|
|
36
|
+
"```",
|
|
37
|
+
error.stack || error.message,
|
|
38
|
+
"```",
|
|
39
|
+
""
|
|
40
|
+
];
|
|
41
|
+
const ctx = _deployContext;
|
|
42
|
+
if (ctx.domain || ctx.repo || ctx.rpc) {
|
|
43
|
+
lines.push("## Deploy Context", "");
|
|
44
|
+
if (ctx.domain) lines.push(`- **Domain**: ${ctx.domain}`);
|
|
45
|
+
if (ctx.repo) lines.push(`- **Repo**: ${ctx.repo}`);
|
|
46
|
+
if (ctx.branch) lines.push(`- **Branch**: ${ctx.branch}`);
|
|
47
|
+
if (ctx.signerMode) lines.push(`- **Signer mode**: ${ctx.signerMode}`);
|
|
48
|
+
if (ctx.chunkCount != null) lines.push(`- **Chunks**: ${ctx.chunkCount}`);
|
|
49
|
+
if (ctx.totalSize) lines.push(`- **Total size**: ${ctx.totalSize}`);
|
|
50
|
+
if (ctx.rpc) lines.push(`- **RPC**: ${ctx.rpc}`);
|
|
51
|
+
if (ctx.sentryTraceId) lines.push(`- **Sentry trace**: ${ctx.sentryTraceId}`);
|
|
52
|
+
lines.push("");
|
|
53
|
+
}
|
|
54
|
+
return lines.join("\n");
|
|
55
|
+
}
|
|
56
|
+
function buildTitle(error) {
|
|
57
|
+
const msg = error.message.slice(0, 60);
|
|
58
|
+
return `[deploy-bug] ${msg}`;
|
|
59
|
+
}
|
|
60
|
+
function buildLabels(error) {
|
|
61
|
+
const labels = ["bug", "auto-report"];
|
|
62
|
+
const area = classifyErrorArea(error.message);
|
|
63
|
+
if (area) labels.push(area);
|
|
64
|
+
return labels;
|
|
65
|
+
}
|
|
66
|
+
async function offerBugReport(error) {
|
|
67
|
+
if (!isInteractive()) return;
|
|
68
|
+
const yes = await promptYesNo("\n This looks like a bug. Open an issue with debug info? [Y/n] ");
|
|
69
|
+
if (!yes) return;
|
|
70
|
+
const title = buildTitle(error);
|
|
71
|
+
const body = buildReportBody(error);
|
|
72
|
+
const labels = buildLabels(error);
|
|
73
|
+
if (hasGhCli()) {
|
|
74
|
+
try {
|
|
75
|
+
const args = [
|
|
76
|
+
"issue",
|
|
77
|
+
"create",
|
|
78
|
+
"--repo",
|
|
79
|
+
"paritytech/bulletin-deploy",
|
|
80
|
+
"--title",
|
|
81
|
+
title,
|
|
82
|
+
...labels.flatMap((l) => ["--label", l]),
|
|
83
|
+
"--body-file",
|
|
84
|
+
"-"
|
|
85
|
+
];
|
|
86
|
+
execFileSync("gh", args, { input: body, stdio: ["pipe", "inherit", "inherit"] });
|
|
87
|
+
console.error(" Issue created.");
|
|
88
|
+
} catch {
|
|
89
|
+
console.error(" Failed to create issue. Debug info below:\n");
|
|
90
|
+
printFallback(title, body, labels);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
console.error("\n gh CLI not found. Debug info below \u2014 paste into a new issue:\n");
|
|
94
|
+
console.error(` https://github.com/paritytech/bulletin-deploy/issues/new
|
|
95
|
+
`);
|
|
96
|
+
printFallback(title, body, labels);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function printFallback(title, body, labels) {
|
|
100
|
+
console.error(` Title: ${title}`);
|
|
101
|
+
console.error(` Labels: ${labels.join(", ")}
|
|
102
|
+
`);
|
|
103
|
+
console.error(body);
|
|
104
|
+
}
|
|
105
|
+
export {
|
|
106
|
+
offerBugReport,
|
|
107
|
+
setDeployContext
|
|
108
|
+
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
TX_TIMEOUT_MS,
|
|
5
5
|
fetchNonce,
|
|
6
6
|
validateDomainLabel
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FI2IKRB7.js";
|
|
8
8
|
import {
|
|
9
9
|
merkleizeJS
|
|
10
10
|
} from "./chunk-GZ5UUECB.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
setDeployAttribute,
|
|
22
22
|
withDeploySpan,
|
|
23
23
|
withSpan
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-GJVD4HRJ.js";
|
|
25
25
|
|
|
26
26
|
// src/deploy.ts
|
|
27
27
|
import { Buffer } from "buffer";
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import {
|
|
2
|
+
VERSION
|
|
3
|
+
} from "./chunk-GJVD4HRJ.js";
|
|
4
|
+
|
|
5
|
+
// src/version-check.ts
|
|
6
|
+
import { execSync, execFileSync } from "child_process";
|
|
7
|
+
import { createInterface } from "readline";
|
|
8
|
+
var REGISTRY_URL = "https://registry.npmjs.org/bulletin-deploy/latest";
|
|
9
|
+
var KILL_SWITCH_URL = "https://raw.githubusercontent.com/paritytech/bulletin-deploy/main/min-version.json";
|
|
10
|
+
var FETCH_TIMEOUT = 3e3;
|
|
11
|
+
function compareSemver(a, b) {
|
|
12
|
+
const pa = a.split(".").map(Number);
|
|
13
|
+
const pb = b.split(".").map(Number);
|
|
14
|
+
for (let i = 0; i < 3; i++) {
|
|
15
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return -1;
|
|
16
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return 1;
|
|
17
|
+
}
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
async function fetchJson(url) {
|
|
21
|
+
try {
|
|
22
|
+
const controller = new AbortController();
|
|
23
|
+
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT);
|
|
24
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
if (!res.ok) return null;
|
|
27
|
+
return await res.json();
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function fetchVersionInfo() {
|
|
33
|
+
const [registry, killSwitch] = await Promise.all([
|
|
34
|
+
fetchJson(REGISTRY_URL),
|
|
35
|
+
fetchJson(KILL_SWITCH_URL)
|
|
36
|
+
]);
|
|
37
|
+
if (!registry && !killSwitch) return null;
|
|
38
|
+
return {
|
|
39
|
+
latest: registry?.version ?? VERSION,
|
|
40
|
+
minimumFromRegistry: registry?.minimumVersion ?? null,
|
|
41
|
+
minimumFromKillSwitch: killSwitch?.minimumVersion ?? null,
|
|
42
|
+
killSwitchMessage: killSwitch?.message ?? null
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function isInternalUser() {
|
|
46
|
+
const repo = process.env.GITHUB_REPOSITORY;
|
|
47
|
+
if (repo?.startsWith("paritytech/")) return true;
|
|
48
|
+
try {
|
|
49
|
+
const remote = execSync("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
50
|
+
return remote.includes("paritytech/");
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function isInteractive() {
|
|
56
|
+
return Boolean(process.stdin.isTTY && !process.env.CI);
|
|
57
|
+
}
|
|
58
|
+
async function promptYesNo(question) {
|
|
59
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
rl.question(question, (answer) => {
|
|
62
|
+
rl.close();
|
|
63
|
+
resolve(!answer || answer.toLowerCase().startsWith("y"));
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function updateAndRetry() {
|
|
68
|
+
console.error("\n Updating bulletin-deploy...");
|
|
69
|
+
try {
|
|
70
|
+
execSync("npm install -g bulletin-deploy@latest", { stdio: "inherit" });
|
|
71
|
+
console.error(" Updated. Retrying deploy...\n");
|
|
72
|
+
execFileSync(process.argv[0], process.argv.slice(1), { stdio: "inherit" });
|
|
73
|
+
process.exit(0);
|
|
74
|
+
} catch {
|
|
75
|
+
console.error(" Update failed. Please run: npm install -g bulletin-deploy@latest");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function classifyErrorArea(msg) {
|
|
80
|
+
if (/personhood|owned by|owner mismatch|reserved for original|domain|dotns|commit-reveal/i.test(msg)) return "area:dotns";
|
|
81
|
+
if (/chunk|storage|authorized|authorization|pool|alice/i.test(msg)) return "area:storage";
|
|
82
|
+
if (/ipfs|cid|pin|dag/i.test(msg)) return "area:ipfs";
|
|
83
|
+
if (/connect|timeout|websocket|rpc|ECONNREFUSED|ENOTFOUND/i.test(msg)) return "area:network";
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function assessVersion(currentVersion, info, internal) {
|
|
87
|
+
const effectiveMinimum = [info.minimumFromRegistry, info.minimumFromKillSwitch].filter(Boolean).sort((a, b) => compareSemver(b, a))[0] ?? null;
|
|
88
|
+
if (effectiveMinimum && compareSemver(currentVersion, effectiveMinimum) < 0) {
|
|
89
|
+
return { action: "forced_update", currentVersion, minimumVersion: effectiveMinimum, message: info.killSwitchMessage };
|
|
90
|
+
}
|
|
91
|
+
if (compareSemver(currentVersion, info.latest) < 0) {
|
|
92
|
+
return { action: "suggest_update", currentVersion, latestVersion: info.latest, internal };
|
|
93
|
+
}
|
|
94
|
+
if (internal) {
|
|
95
|
+
return { action: "bug_report", internal: true };
|
|
96
|
+
}
|
|
97
|
+
return { action: "none" };
|
|
98
|
+
}
|
|
99
|
+
async function handleFailedDeploy(error) {
|
|
100
|
+
if (process.env.BULLETIN_DEPLOY_UPDATE_CHECK === "0") return;
|
|
101
|
+
const info = await fetchVersionInfo();
|
|
102
|
+
if (!info) return;
|
|
103
|
+
let verdict = assessVersion(VERSION, info, false);
|
|
104
|
+
if (verdict.action === "suggest_update" || verdict.action === "none") {
|
|
105
|
+
const internal = isInternalUser();
|
|
106
|
+
if (internal) verdict = assessVersion(VERSION, info, true);
|
|
107
|
+
}
|
|
108
|
+
switch (verdict.action) {
|
|
109
|
+
case "forced_update":
|
|
110
|
+
console.error(`
|
|
111
|
+
bulletin-deploy ${verdict.currentVersion} is no longer supported (minimum: ${verdict.minimumVersion}).`);
|
|
112
|
+
if (verdict.message) console.error(` Reason: ${verdict.message}`);
|
|
113
|
+
console.error(` Please update: npm install -g bulletin-deploy@latest
|
|
114
|
+
`);
|
|
115
|
+
break;
|
|
116
|
+
case "suggest_update":
|
|
117
|
+
if (verdict.internal && isInteractive()) {
|
|
118
|
+
const yes = await promptYesNo(`
|
|
119
|
+
bulletin-deploy ${verdict.currentVersion} \u2192 ${verdict.latestVersion} available. Update and retry? [Y/n] `);
|
|
120
|
+
if (yes) updateAndRetry();
|
|
121
|
+
else console.error(` Skipped. Run: npm install -g bulletin-deploy@latest
|
|
122
|
+
`);
|
|
123
|
+
} else {
|
|
124
|
+
console.error(`
|
|
125
|
+
A newer version of bulletin-deploy is available (${verdict.currentVersion} \u2192 ${verdict.latestVersion}).`);
|
|
126
|
+
console.error(` Run: npm install -g bulletin-deploy@latest
|
|
127
|
+
`);
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
case "bug_report": {
|
|
131
|
+
const { offerBugReport } = await import("./bug-report.js");
|
|
132
|
+
await offerBugReport(error);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export {
|
|
139
|
+
compareSemver,
|
|
140
|
+
isInternalUser,
|
|
141
|
+
isInteractive,
|
|
142
|
+
promptYesNo,
|
|
143
|
+
classifyErrorArea,
|
|
144
|
+
assessVersion,
|
|
145
|
+
handleFailedDeploy
|
|
146
|
+
};
|
|
@@ -6,7 +6,7 @@ import * as path from "path";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "bulletin-deploy",
|
|
9
|
-
version: "0.6.
|
|
9
|
+
version: "0.6.8-rc.0",
|
|
10
10
|
private: false,
|
|
11
11
|
repository: {
|
|
12
12
|
type: "git",
|
|
@@ -34,7 +34,7 @@ var package_default = {
|
|
|
34
34
|
"cdm.json"
|
|
35
35
|
],
|
|
36
36
|
scripts: {
|
|
37
|
-
build: "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/merkle.ts --format esm --dts --clean --target node22",
|
|
37
|
+
build: "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/merkle.ts src/version-check.ts src/bug-report.ts --format esm --dts --clean --target node22",
|
|
38
38
|
test: "npm run build && node --test test/test.js",
|
|
39
39
|
benchmark: "npm run build && node benchmark.js"
|
|
40
40
|
},
|
|
@@ -61,6 +61,7 @@ var package_default = {
|
|
|
61
61
|
tsup: "^8.5.0",
|
|
62
62
|
typescript: "^5.9.3"
|
|
63
63
|
},
|
|
64
|
+
minimumVersion: "0.5.6",
|
|
64
65
|
engines: {
|
|
65
66
|
node: ">=22"
|
|
66
67
|
}
|
|
@@ -81,6 +82,7 @@ function initTelemetry() {
|
|
|
81
82
|
if (!Sentry) return;
|
|
82
83
|
Sentry.init({
|
|
83
84
|
dsn: process.env.SENTRY_DSN || DEFAULT_DSN,
|
|
85
|
+
release: `${package_default.name}@${VERSION}`,
|
|
84
86
|
tracesSampleRate: 1,
|
|
85
87
|
environment: process.env.CI ? "ci" : "local"
|
|
86
88
|
});
|
|
@@ -119,7 +121,8 @@ function getDeployAttributes(domain) {
|
|
|
119
121
|
"deploy.repo": resolveRepo(domain),
|
|
120
122
|
"deploy.branch": process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || tryGitBranch(),
|
|
121
123
|
"deploy.source": process.env.CI ? "ci" : "local",
|
|
122
|
-
"deploy.pr": process.env.GITHUB_PR_NUMBER || void 0
|
|
124
|
+
"deploy.pr": process.env.GITHUB_PR_NUMBER || void 0,
|
|
125
|
+
"deploy.tool_version": VERSION
|
|
123
126
|
};
|
|
124
127
|
}
|
|
125
128
|
function isExpectedError(msg) {
|
|
@@ -154,6 +157,7 @@ async function withDeploySpan(domain, fn) {
|
|
|
154
157
|
const msg = error.message;
|
|
155
158
|
span.setAttribute("deploy.status", "error");
|
|
156
159
|
span.setAttribute("deploy.error", msg.slice(0, 200));
|
|
160
|
+
span.setAttribute("deploy.sad", true);
|
|
157
161
|
const isExpected = isExpectedError(msg);
|
|
158
162
|
if (!isExpected) {
|
|
159
163
|
span.setStatus({ code: 2, message: "internal_error" });
|
package/dist/deploy.js
CHANGED
|
@@ -21,11 +21,11 @@ import {
|
|
|
21
21
|
storeChunkedContent,
|
|
22
22
|
storeDirectory,
|
|
23
23
|
storeFile
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-AUTRMT26.js";
|
|
25
|
+
import "./chunk-FI2IKRB7.js";
|
|
26
26
|
import "./chunk-GZ5UUECB.js";
|
|
27
27
|
import "./chunk-LGPTJYA3.js";
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-GJVD4HRJ.js";
|
|
29
29
|
import "./chunk-QGM4M3NI.js";
|
|
30
30
|
export {
|
|
31
31
|
DEFAULT_BULLETIN_RPC,
|
package/dist/dotns.js
CHANGED
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
sanitizeDomainLabel,
|
|
20
20
|
stripTrailingDigits,
|
|
21
21
|
validateDomainLabel
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-FI2IKRB7.js";
|
|
23
|
+
import "./chunk-GJVD4HRJ.js";
|
|
24
24
|
import "./chunk-QGM4M3NI.js";
|
|
25
25
|
export {
|
|
26
26
|
CONNECTION_TIMEOUT_MS,
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deploy
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AUTRMT26.js";
|
|
4
4
|
import {
|
|
5
5
|
DotNS
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FI2IKRB7.js";
|
|
7
7
|
import {
|
|
8
8
|
merkleizeJS
|
|
9
9
|
} from "./chunk-GZ5UUECB.js";
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
fetchPoolAuthorizations,
|
|
15
15
|
selectAccount
|
|
16
16
|
} from "./chunk-LGPTJYA3.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-GJVD4HRJ.js";
|
|
18
18
|
import "./chunk-QGM4M3NI.js";
|
|
19
19
|
export {
|
|
20
20
|
DotNS,
|
package/dist/telemetry.js
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface VersionInfo {
|
|
2
|
+
latest: string;
|
|
3
|
+
minimumFromRegistry: string | null;
|
|
4
|
+
minimumFromKillSwitch: string | null;
|
|
5
|
+
killSwitchMessage: string | null;
|
|
6
|
+
}
|
|
7
|
+
declare function compareSemver(a: string, b: string): number;
|
|
8
|
+
declare function isInternalUser(): boolean;
|
|
9
|
+
declare function isInteractive(): boolean;
|
|
10
|
+
declare function promptYesNo(question: string): Promise<boolean>;
|
|
11
|
+
declare function classifyErrorArea(msg: string): string | null;
|
|
12
|
+
type VersionVerdict = {
|
|
13
|
+
action: "forced_update";
|
|
14
|
+
currentVersion: string;
|
|
15
|
+
minimumVersion: string;
|
|
16
|
+
message: string | null;
|
|
17
|
+
} | {
|
|
18
|
+
action: "suggest_update";
|
|
19
|
+
currentVersion: string;
|
|
20
|
+
latestVersion: string;
|
|
21
|
+
internal: boolean;
|
|
22
|
+
} | {
|
|
23
|
+
action: "bug_report";
|
|
24
|
+
internal: boolean;
|
|
25
|
+
} | {
|
|
26
|
+
action: "none";
|
|
27
|
+
};
|
|
28
|
+
declare function assessVersion(currentVersion: string, info: VersionInfo, internal: boolean): VersionVerdict;
|
|
29
|
+
declare function handleFailedDeploy(error: Error): Promise<void>;
|
|
30
|
+
|
|
31
|
+
export { type VersionVerdict, assessVersion, classifyErrorArea, compareSemver, handleFailedDeploy, isInteractive, isInternalUser, promptYesNo };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assessVersion,
|
|
3
|
+
classifyErrorArea,
|
|
4
|
+
compareSemver,
|
|
5
|
+
handleFailedDeploy,
|
|
6
|
+
isInteractive,
|
|
7
|
+
isInternalUser,
|
|
8
|
+
promptYesNo
|
|
9
|
+
} from "./chunk-GCAPBR6G.js";
|
|
10
|
+
import "./chunk-GJVD4HRJ.js";
|
|
11
|
+
import "./chunk-QGM4M3NI.js";
|
|
12
|
+
export {
|
|
13
|
+
assessVersion,
|
|
14
|
+
classifyErrorArea,
|
|
15
|
+
compareSemver,
|
|
16
|
+
handleFailedDeploy,
|
|
17
|
+
isInteractive,
|
|
18
|
+
isInternalUser,
|
|
19
|
+
promptYesNo
|
|
20
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bulletin-deploy",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.8-rc.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"cdm.json"
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
|
-
"build": "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/merkle.ts --format esm --dts --clean --target node22",
|
|
31
|
+
"build": "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/merkle.ts src/version-check.ts src/bug-report.ts --format esm --dts --clean --target node22",
|
|
32
32
|
"test": "npm run build && node --test test/test.js",
|
|
33
33
|
"benchmark": "npm run build && node benchmark.js"
|
|
34
34
|
},
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"tsup": "^8.5.0",
|
|
56
56
|
"typescript": "^5.9.3"
|
|
57
57
|
},
|
|
58
|
+
"minimumVersion": "0.5.6",
|
|
58
59
|
"engines": {
|
|
59
60
|
"node": ">=22"
|
|
60
61
|
}
|