bulletin-deploy 0.6.8 → 0.6.9-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 +12 -2
- package/bin/bulletin-deploy +4 -1
- package/dist/bug-report.d.ts +5 -1
- package/dist/bug-report.js +29 -16
- package/dist/{chunk-SLARK556.js → chunk-3W2COGJ6.js} +114 -19
- package/dist/{chunk-LGPTJYA3.js → chunk-CUFLI45S.js} +2 -2
- package/dist/{chunk-LVCOE5CC.js → chunk-IHFIWF2A.js} +22 -12
- package/dist/{chunk-KHLH5WQY.js → chunk-WOHUOD3E.js} +2 -2
- package/dist/{chunk-SYJ2L6RU.js → chunk-X7WJJEXW.js} +46 -5
- package/dist/deploy.d.ts +2 -1
- package/dist/deploy.js +6 -4
- package/dist/dotns.js +2 -2
- package/dist/index.js +4 -4
- package/dist/pool.d.ts +6 -2
- package/dist/pool.js +1 -1
- package/dist/telemetry.d.ts +13 -1
- package/dist/telemetry.js +15 -1
- package/dist/version-check.d.ts +6 -2
- package/dist/version-check.js +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ bulletin-deploy ./dist my-app00.dot
|
|
|
12
12
|
|
|
13
13
|
Your site is live at `https://my-app00.dot.li`
|
|
14
14
|
|
|
15
|
+
> **Stable vs release candidate.** `npm install -g bulletin-deploy` (and `@latest`) always resolves to the latest stable version — never an RC. Release candidates are published under the `rc` dist-tag and can be installed explicitly with `npm install -g bulletin-deploy@rc` (or a literal version pin like `@0.6.9-rc.0`). Only use RCs for testing.
|
|
16
|
+
|
|
15
17
|
## Prerequisites
|
|
16
18
|
|
|
17
19
|
- **Node.js 22+**
|
|
@@ -134,7 +136,7 @@ If you see **"Requires Full Personhood verification"**, the deploy will fail ear
|
|
|
134
136
|
| Variable | Default | Description |
|
|
135
137
|
|---|---|---|
|
|
136
138
|
| `BULLETIN_RPC` | `wss://paseo-bulletin-rpc.polkadot.io` | Bulletin chain WebSocket RPC |
|
|
137
|
-
| `BULLETIN_DEPLOY_TELEMETRY` |
|
|
139
|
+
| `BULLETIN_DEPLOY_TELEMETRY` | _(off for external users, on for internal)_ | `1` to opt in, `0` to force off — see **Telemetry** below |
|
|
138
140
|
| `BULLETIN_DEPLOY_UPDATE_CHECK` | `1` (enabled) | Set to `0` to disable version check on errors |
|
|
139
141
|
| `DOTNS_STATUS` | `full` (testnet) / `none` (mainnet) | PoP level to self-grant before registration: `none`, `lite`, or `full` |
|
|
140
142
|
| `IPFS_CID` | _(none)_ | Skip storage, use pre-existing CID |
|
|
@@ -221,7 +223,15 @@ Set `BULLETIN_DEPLOY_UPDATE_CHECK=0` to disable version checking.
|
|
|
221
223
|
|
|
222
224
|
## Telemetry
|
|
223
225
|
|
|
224
|
-
Sentry telemetry is
|
|
226
|
+
Sentry telemetry is **off by default for external users**. It's automatically on for deploys originating from inside Parity — either Parity CI, or local development trees whose git origin points at `paritytech/*`, `w3f/*`, or `polkadot-fellows/*`.
|
|
227
|
+
|
|
228
|
+
- `BULLETIN_DEPLOY_TELEMETRY=1` — explicit opt-in (useful if you want to help us debug an issue you're seeing).
|
|
229
|
+
- `BULLETIN_DEPLOY_TELEMETRY=0` — force off regardless of context.
|
|
230
|
+
|
|
231
|
+
Detection signals (OR'd together):
|
|
232
|
+
1. `GITHUB_REPOSITORY` matches a known-internal org — Parity-owned CI workflow.
|
|
233
|
+
2. `RUNNER_NAME` starts with `parity-` — Parity self-hosted runner.
|
|
234
|
+
3. `git remote get-url origin` points at a known-internal org — internal local dev.
|
|
225
235
|
|
|
226
236
|
What's tracked:
|
|
227
237
|
- Deploy duration and success/failure
|
package/bin/bulletin-deploy
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
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";
|
|
6
|
+
import { handleFailedDeploy, preReleaseWarning } from "../dist/version-check.js";
|
|
7
7
|
import { setDeployContext } from "../dist/bug-report.js";
|
|
8
8
|
import * as fs from "fs";
|
|
9
9
|
|
|
@@ -48,6 +48,9 @@ Options:
|
|
|
48
48
|
process.exit(0);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
const rcWarning = preReleaseWarning(VERSION);
|
|
52
|
+
if (rcWarning) console.error(rcWarning);
|
|
53
|
+
|
|
51
54
|
try {
|
|
52
55
|
if (flags.bootstrap) {
|
|
53
56
|
const rpc = flags.rpc ?? process.env.BULLETIN_RPC ?? DEFAULT_BULLETIN_RPC;
|
package/dist/bug-report.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ interface DeployContext {
|
|
|
9
9
|
sentryTraceId?: string;
|
|
10
10
|
}
|
|
11
11
|
declare function setDeployContext(ctx: Partial<DeployContext>): void;
|
|
12
|
+
declare function buildReportBody(error: Error): string;
|
|
13
|
+
declare function buildTitle(error: Error): string;
|
|
14
|
+
declare function buildLabels(error: Error): string[];
|
|
15
|
+
declare function createGhIssue(title: string, body: string, labels: string[]): void;
|
|
12
16
|
declare function offerBugReport(error: Error): Promise<void>;
|
|
13
17
|
|
|
14
|
-
export { offerBugReport, setDeployContext };
|
|
18
|
+
export { buildLabels, buildReportBody, buildTitle, createGhIssue, offerBugReport, setDeployContext };
|
package/dist/bug-report.js
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-X7WJJEXW.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3W2COGJ6.js";
|
|
9
9
|
import "./chunk-QGM4M3NI.js";
|
|
10
10
|
|
|
11
11
|
// src/bug-report.ts
|
|
@@ -63,6 +63,20 @@ function buildLabels(error) {
|
|
|
63
63
|
if (area) labels.push(area);
|
|
64
64
|
return labels;
|
|
65
65
|
}
|
|
66
|
+
function createGhIssue(title, body, labels) {
|
|
67
|
+
const args = [
|
|
68
|
+
"issue",
|
|
69
|
+
"create",
|
|
70
|
+
"--repo",
|
|
71
|
+
"paritytech/bulletin-deploy",
|
|
72
|
+
"--title",
|
|
73
|
+
title,
|
|
74
|
+
...labels.flatMap((l) => ["--label", l]),
|
|
75
|
+
"--body-file",
|
|
76
|
+
"-"
|
|
77
|
+
];
|
|
78
|
+
execFileSync("gh", args, { input: body, stdio: ["pipe", "inherit", "inherit"] });
|
|
79
|
+
}
|
|
66
80
|
async function offerBugReport(error) {
|
|
67
81
|
if (!isInteractive()) return;
|
|
68
82
|
const yes = await promptYesNo("\n This looks like a bug. Open an issue with debug info? [Y/n] ");
|
|
@@ -72,22 +86,17 @@ async function offerBugReport(error) {
|
|
|
72
86
|
const labels = buildLabels(error);
|
|
73
87
|
if (hasGhCli()) {
|
|
74
88
|
try {
|
|
75
|
-
|
|
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"] });
|
|
89
|
+
createGhIssue(title, body, labels);
|
|
87
90
|
console.error(" Issue created.");
|
|
88
91
|
} catch {
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
try {
|
|
93
|
+
console.error(" Retrying without labels...");
|
|
94
|
+
createGhIssue(title, body, []);
|
|
95
|
+
console.error(" Issue created (without labels).");
|
|
96
|
+
} catch {
|
|
97
|
+
console.error(" Failed to create issue. Debug info below:\n");
|
|
98
|
+
printFallback(title, body, labels);
|
|
99
|
+
}
|
|
91
100
|
}
|
|
92
101
|
} else {
|
|
93
102
|
console.error("\n gh CLI not found. Debug info below \u2014 paste into a new issue:\n");
|
|
@@ -103,6 +112,10 @@ function printFallback(title, body, labels) {
|
|
|
103
112
|
console.error(body);
|
|
104
113
|
}
|
|
105
114
|
export {
|
|
115
|
+
buildLabels,
|
|
116
|
+
buildReportBody,
|
|
117
|
+
buildTitle,
|
|
118
|
+
createGhIssue,
|
|
106
119
|
offerBugReport,
|
|
107
120
|
setDeployContext
|
|
108
121
|
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// src/telemetry.ts
|
|
2
2
|
import { execSync } from "child_process";
|
|
3
|
+
import { createHash } from "crypto";
|
|
3
4
|
import * as fs from "fs";
|
|
4
5
|
import * as path from "path";
|
|
5
6
|
|
|
6
7
|
// package.json
|
|
7
8
|
var package_default = {
|
|
8
9
|
name: "bulletin-deploy",
|
|
9
|
-
version: "0.6.
|
|
10
|
+
version: "0.6.9-rc.0",
|
|
10
11
|
private: false,
|
|
11
12
|
repository: {
|
|
12
13
|
type: "git",
|
|
@@ -70,7 +71,75 @@ var package_default = {
|
|
|
70
71
|
// src/telemetry.ts
|
|
71
72
|
var VERSION = package_default.version;
|
|
72
73
|
var DEFAULT_DSN = "https://e021c025d79c4c3ade2862a11f13c40b@o4511059872841728.ingest.de.sentry.io/4511093597405264";
|
|
73
|
-
var
|
|
74
|
+
var INTERNAL_ORG_RE = /^(paritytech|w3f|polkadot-fellows)\//i;
|
|
75
|
+
function extractRepoSlug(url) {
|
|
76
|
+
return url.replace(/.*github\.com[:/]/, "").replace(/\.git$/, "");
|
|
77
|
+
}
|
|
78
|
+
function tryGitRemote() {
|
|
79
|
+
try {
|
|
80
|
+
return extractRepoSlug(execSync("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim());
|
|
81
|
+
} catch {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function isInternalContextFromSignals(signals) {
|
|
86
|
+
if (INTERNAL_ORG_RE.test(signals.githubRepository ?? "")) return true;
|
|
87
|
+
if (signals.runnerName?.startsWith("parity-")) return true;
|
|
88
|
+
if (signals.gitRemote && INTERNAL_ORG_RE.test(signals.gitRemote)) return true;
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
function isInternalContext() {
|
|
92
|
+
return isInternalContextFromSignals({
|
|
93
|
+
githubRepository: process.env.GITHUB_REPOSITORY,
|
|
94
|
+
runnerName: process.env.RUNNER_NAME,
|
|
95
|
+
gitRemote: tryGitRemote()
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
var OPT_OUT = process.env.BULLETIN_DEPLOY_TELEMETRY === "0";
|
|
99
|
+
var OPT_IN = process.env.BULLETIN_DEPLOY_TELEMETRY === "1";
|
|
100
|
+
var DISABLED = OPT_OUT || !OPT_IN && !isInternalContext();
|
|
101
|
+
var CONVENTIONAL_BRANCH_PREFIXES = /* @__PURE__ */ new Set([
|
|
102
|
+
"fix",
|
|
103
|
+
"feat",
|
|
104
|
+
"chore",
|
|
105
|
+
"docs",
|
|
106
|
+
"test",
|
|
107
|
+
"refactor",
|
|
108
|
+
"release",
|
|
109
|
+
"bump",
|
|
110
|
+
"perf",
|
|
111
|
+
"style",
|
|
112
|
+
"ci",
|
|
113
|
+
"build",
|
|
114
|
+
"revert"
|
|
115
|
+
]);
|
|
116
|
+
function scrubPaths(msg) {
|
|
117
|
+
if (!msg) return msg;
|
|
118
|
+
return msg.replace(/\/Users\/[^\/\s"'`]+/g, "/Users/<redacted>").replace(/\/home\/[^\/\s"'`]+/g, "/home/<redacted>");
|
|
119
|
+
}
|
|
120
|
+
function truncateAddress(ss58) {
|
|
121
|
+
if (!ss58) return ss58;
|
|
122
|
+
return ss58.length > 8 ? `${ss58.slice(0, 8)}\u2026` : ss58;
|
|
123
|
+
}
|
|
124
|
+
function sanitizeBranch(name) {
|
|
125
|
+
if (!name) return name;
|
|
126
|
+
const slash = name.indexOf("/");
|
|
127
|
+
if (slash === -1) return name;
|
|
128
|
+
const prefix = name.slice(0, slash).toLowerCase();
|
|
129
|
+
if (CONVENTIONAL_BRANCH_PREFIXES.has(prefix)) return name;
|
|
130
|
+
return name.slice(slash + 1);
|
|
131
|
+
}
|
|
132
|
+
function sanitizeRepo(slug) {
|
|
133
|
+
if (!slug) return slug;
|
|
134
|
+
if (INTERNAL_ORG_RE.test(slug)) return slug;
|
|
135
|
+
const slash = slug.indexOf("/");
|
|
136
|
+
if (slash === -1) {
|
|
137
|
+
return `ext/${createHash("sha256").update(slug).digest("hex").slice(0, 12)}`;
|
|
138
|
+
}
|
|
139
|
+
const org = slug.slice(0, slash);
|
|
140
|
+
const repo = slug.slice(slash + 1);
|
|
141
|
+
return `${org}/${createHash("sha256").update(repo).digest("hex").slice(0, 12)}`;
|
|
142
|
+
}
|
|
74
143
|
var Sentry = null;
|
|
75
144
|
if (!DISABLED) {
|
|
76
145
|
try {
|
|
@@ -84,19 +153,35 @@ function initTelemetry() {
|
|
|
84
153
|
dsn: process.env.SENTRY_DSN || DEFAULT_DSN,
|
|
85
154
|
release: `${package_default.name}@${VERSION}`,
|
|
86
155
|
tracesSampleRate: 1,
|
|
87
|
-
environment: process.env.CI ? "ci" : "local"
|
|
156
|
+
environment: process.env.CI ? "ci" : "local",
|
|
157
|
+
// Sentry Node SDK captures os.hostname() by default, which leaks personal
|
|
158
|
+
// machine names (e.g. "Mac.fritz.box"). Override to something anonymous.
|
|
159
|
+
serverName: process.env.CI ? process.env.RUNNER_NAME ?? "ci" : "local",
|
|
160
|
+
beforeSend(event) {
|
|
161
|
+
if (event.server_name) event.server_name = process.env.CI ? process.env.RUNNER_NAME ?? "ci" : "local";
|
|
162
|
+
if (event.message) event.message = scrubPaths(event.message);
|
|
163
|
+
for (const ex of event.exception?.values ?? []) {
|
|
164
|
+
if (ex.value) ex.value = scrubPaths(ex.value);
|
|
165
|
+
}
|
|
166
|
+
for (const bc of event.breadcrumbs ?? []) {
|
|
167
|
+
if (bc.message) bc.message = scrubPaths(bc.message);
|
|
168
|
+
}
|
|
169
|
+
return event;
|
|
170
|
+
},
|
|
171
|
+
beforeSendTransaction(event) {
|
|
172
|
+
const spans = event.spans ?? [];
|
|
173
|
+
for (const span of spans) {
|
|
174
|
+
const attrs = span.data;
|
|
175
|
+
if (!attrs) continue;
|
|
176
|
+
for (const k of Object.keys(attrs)) {
|
|
177
|
+
const v = attrs[k];
|
|
178
|
+
if (typeof v === "string") attrs[k] = scrubPaths(v);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return event;
|
|
182
|
+
}
|
|
88
183
|
});
|
|
89
184
|
}
|
|
90
|
-
function extractRepoSlug(url) {
|
|
91
|
-
return url.replace(/.*github\.com[:/]/, "").replace(/\.git$/, "");
|
|
92
|
-
}
|
|
93
|
-
function tryGitRemote() {
|
|
94
|
-
try {
|
|
95
|
-
return extractRepoSlug(execSync("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim());
|
|
96
|
-
} catch {
|
|
97
|
-
return void 0;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
185
|
function tryPackageJsonRepo() {
|
|
101
186
|
try {
|
|
102
187
|
const pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), "package.json"), "utf-8"));
|
|
@@ -128,17 +213,20 @@ function resolveRunnerType() {
|
|
|
128
213
|
}
|
|
129
214
|
function getDeployAttributes(domain) {
|
|
130
215
|
return {
|
|
131
|
-
"deploy.repo": resolveRepo(domain),
|
|
132
|
-
"deploy.branch": process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || tryGitBranch(),
|
|
216
|
+
"deploy.repo": sanitizeRepo(resolveRepo(domain)),
|
|
217
|
+
"deploy.branch": sanitizeBranch(process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || tryGitBranch()),
|
|
133
218
|
"deploy.source": process.env.CI ? "ci" : "local",
|
|
134
219
|
"deploy.pr": process.env.GITHUB_PR_NUMBER || void 0,
|
|
135
220
|
"deploy.tool_version": VERSION,
|
|
136
221
|
"deploy.runner": resolveRunner(),
|
|
137
|
-
"deploy.runner_type": resolveRunnerType()
|
|
222
|
+
"deploy.runner_type": resolveRunnerType(),
|
|
223
|
+
// Seed "false" so successful spans form the %SAD denominator; the catch block and
|
|
224
|
+
// captureWarning flip it to "true" on friction.
|
|
225
|
+
"deploy.sad": "false"
|
|
138
226
|
};
|
|
139
227
|
}
|
|
140
228
|
function isExpectedError(msg) {
|
|
141
|
-
return /personhood|owned by|owner mismatch|reserved for original|invalid domain label|not authorized for bulletin|insufficient balance/i.test(msg);
|
|
229
|
+
return /personhood|owned by|owner mismatch|reserved for original|invalid domain label|not authorized for bulletin|insufficient balance|quota exhausted|insufficient .* authorization/i.test(msg);
|
|
142
230
|
}
|
|
143
231
|
async function withSpan(op, description, attributes, fn) {
|
|
144
232
|
if (!Sentry) return fn();
|
|
@@ -171,7 +259,7 @@ async function withDeploySpan(domain, fn) {
|
|
|
171
259
|
const msg = error.message;
|
|
172
260
|
span.setAttribute("deploy.status", "error");
|
|
173
261
|
span.setAttribute("deploy.error", msg.slice(0, 200));
|
|
174
|
-
span.setAttribute("deploy.sad", true);
|
|
262
|
+
span.setAttribute("deploy.sad", "true");
|
|
175
263
|
const isExpected = isExpectedError(msg);
|
|
176
264
|
if (!isExpected) {
|
|
177
265
|
span.setStatus({ code: 2, message: "internal_error" });
|
|
@@ -194,7 +282,7 @@ function captureWarning(message, context) {
|
|
|
194
282
|
Sentry.addBreadcrumb({ level: "warning", message, data: context });
|
|
195
283
|
Sentry.captureMessage(message, { level: "warning", extra: context });
|
|
196
284
|
const root = Sentry.getRootSpan(Sentry.getActiveSpan());
|
|
197
|
-
if (root) root.setAttribute("deploy.sad", true);
|
|
285
|
+
if (root) root.setAttribute("deploy.sad", "true");
|
|
198
286
|
} catch {
|
|
199
287
|
}
|
|
200
288
|
}
|
|
@@ -205,10 +293,17 @@ async function flush() {
|
|
|
205
293
|
|
|
206
294
|
export {
|
|
207
295
|
VERSION,
|
|
296
|
+
isInternalContextFromSignals,
|
|
297
|
+
isInternalContext,
|
|
298
|
+
scrubPaths,
|
|
299
|
+
truncateAddress,
|
|
300
|
+
sanitizeBranch,
|
|
301
|
+
sanitizeRepo,
|
|
208
302
|
initTelemetry,
|
|
209
303
|
resolveRepo,
|
|
210
304
|
resolveRunner,
|
|
211
305
|
resolveRunnerType,
|
|
306
|
+
getDeployAttributes,
|
|
212
307
|
isExpectedError,
|
|
213
308
|
withSpan,
|
|
214
309
|
withDeploySpan,
|
|
@@ -55,13 +55,13 @@ async function fetchPoolAuthorizations(api, accounts) {
|
|
|
55
55
|
);
|
|
56
56
|
return results;
|
|
57
57
|
}
|
|
58
|
-
async function ensureAuthorized(api, address, bulletinRpc, label) {
|
|
58
|
+
async function ensureAuthorized(api, address, bulletinRpc, label, minimum = { txs: TOPUP_THRESHOLD_TXS, bytes: TOPUP_THRESHOLD_BYTES }) {
|
|
59
59
|
const auth = await api.query.TransactionStorage.Authorizations.getValue(
|
|
60
60
|
Enum("Account", address)
|
|
61
61
|
);
|
|
62
62
|
const txsRemaining = auth ? BigInt(auth.extent.transactions) : 0n;
|
|
63
63
|
const bytesRemaining = auth ? auth.extent.bytes : 0n;
|
|
64
|
-
if (txsRemaining >=
|
|
64
|
+
if (txsRemaining >= minimum.txs && bytesRemaining >= minimum.bytes) {
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
console.log(` Auto-authorizing ${label ?? "account"} (${address.slice(0, 8)}...)...`);
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
TX_TIMEOUT_MS,
|
|
5
5
|
fetchNonce,
|
|
6
6
|
validateDomainLabel
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WOHUOD3E.js";
|
|
8
8
|
import {
|
|
9
9
|
merkleizeJS
|
|
10
10
|
} from "./chunk-GZ5UUECB.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
ensureAuthorized,
|
|
14
14
|
fetchPoolAuthorizations,
|
|
15
15
|
selectAccount
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CUFLI45S.js";
|
|
17
17
|
import {
|
|
18
18
|
VERSION,
|
|
19
19
|
captureWarning,
|
|
@@ -21,9 +21,10 @@ import {
|
|
|
21
21
|
resolveRunner,
|
|
22
22
|
resolveRunnerType,
|
|
23
23
|
setDeployAttribute,
|
|
24
|
+
truncateAddress,
|
|
24
25
|
withDeploySpan,
|
|
25
26
|
withSpan
|
|
26
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-3W2COGJ6.js";
|
|
27
28
|
|
|
28
29
|
// src/deploy.ts
|
|
29
30
|
import { Buffer } from "buffer";
|
|
@@ -306,6 +307,12 @@ var NonRetryableError = class extends Error {
|
|
|
306
307
|
}
|
|
307
308
|
};
|
|
308
309
|
var EXIT_CODE_NO_RETRY = 78;
|
|
310
|
+
function friendlyChainError(msg) {
|
|
311
|
+
if (/"type":\s*"Invalid"[\s\S]*?"type":\s*"Payment"/i.test(msg)) {
|
|
312
|
+
return "authorization quota exhausted (Bulletin signed extension rejected the tx \u2014 signer is out of authorized txs or bytes)";
|
|
313
|
+
}
|
|
314
|
+
return msg;
|
|
315
|
+
}
|
|
309
316
|
var DEFAULT_BULLETIN_RPC = "wss://paseo-bulletin-rpc.polkadot.io";
|
|
310
317
|
var DEFAULT_POOL_SIZE = 10;
|
|
311
318
|
var BULLETIN_RPC = DEFAULT_BULLETIN_RPC;
|
|
@@ -414,7 +421,7 @@ async function getProvider() {
|
|
|
414
421
|
}
|
|
415
422
|
console.log(` Using pool account ${selected.index}: ${selected.address}`);
|
|
416
423
|
setDeployAttribute("deploy.signer.mode", "pool");
|
|
417
|
-
setDeployAttribute("deploy.pool.account", selected.address);
|
|
424
|
+
setDeployAttribute("deploy.pool.account", truncateAddress(selected.address));
|
|
418
425
|
setDeployAttribute("deploy.pool.index", selected.index);
|
|
419
426
|
return { client, unsafeApi, signer: selected.signer, ss58: selected.address };
|
|
420
427
|
} catch (e) {
|
|
@@ -439,7 +446,7 @@ async function getDirectProvider(mnemonic) {
|
|
|
439
446
|
}
|
|
440
447
|
console.log(` Authorization: ${txsRemaining} txs, ${Number(bytesRemaining) / 1e6}MB remaining`);
|
|
441
448
|
setDeployAttribute("deploy.signer.mode", "direct");
|
|
442
|
-
setDeployAttribute("deploy.signer.address", ss58);
|
|
449
|
+
setDeployAttribute("deploy.signer.address", truncateAddress(ss58));
|
|
443
450
|
return { client, unsafeApi, signer, ss58 };
|
|
444
451
|
}
|
|
445
452
|
var MAX_BEST_CHAIN_DROPS = 5;
|
|
@@ -503,7 +510,7 @@ function watchTransaction(tx, signer, txOpts, onSuccess, { label = "transaction"
|
|
|
503
510
|
},
|
|
504
511
|
error: (e) => {
|
|
505
512
|
const msg = e?.message || String(e).slice(0, 500);
|
|
506
|
-
settle(reject)(new Error(`${label} subscription error: ${msg}`));
|
|
513
|
+
settle(reject)(new Error(`${label} subscription error: ${friendlyChainError(msg)}`));
|
|
507
514
|
}
|
|
508
515
|
});
|
|
509
516
|
});
|
|
@@ -574,20 +581,21 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
574
581
|
ownsClient = true;
|
|
575
582
|
}
|
|
576
583
|
const requiredTxs = BigInt(chunks.length + 1);
|
|
584
|
+
const requiredBytes = BigInt(totalBytes);
|
|
577
585
|
const auth = await unsafeApi.query.TransactionStorage.Authorizations.getValue(
|
|
578
586
|
Enum("Account", ss58)
|
|
579
587
|
);
|
|
580
588
|
const txsRemaining = auth ? BigInt(auth.extent.transactions) : 0n;
|
|
581
589
|
const bytesRemaining = auth ? auth.extent.bytes : 0n;
|
|
582
|
-
if (txsRemaining < requiredTxs || bytesRemaining <
|
|
590
|
+
if (txsRemaining < requiredTxs || bytesRemaining < requiredBytes) {
|
|
583
591
|
console.log(`
|
|
584
592
|
Account has insufficient authorization for this upload (need ${requiredTxs} txs / ${(totalBytes / 1e6).toFixed(1)}MB, have ${txsRemaining} txs / ${Number(bytesRemaining) / 1e6}MB)`);
|
|
585
593
|
console.log(` Attempting to re-authorize with Alice...`);
|
|
586
594
|
try {
|
|
587
|
-
await ensureAuthorized(unsafeApi, ss58, BULLETIN_RPC);
|
|
595
|
+
await ensureAuthorized(unsafeApi, ss58, BULLETIN_RPC, void 0, { txs: requiredTxs, bytes: requiredBytes });
|
|
588
596
|
console.log(` Re-authorization successful`);
|
|
589
597
|
} catch (e) {
|
|
590
|
-
throw new
|
|
598
|
+
throw new NonRetryableError(`Account ${ss58} has insufficient Bulletin authorization quota and auto-authorization via Alice failed (${e.message}). Authorize the account on-chain, or run 'bulletin-deploy --bootstrap --mnemonic "..."' in a dev network.`);
|
|
591
599
|
}
|
|
592
600
|
}
|
|
593
601
|
let reconnectionsUsed = 0;
|
|
@@ -689,7 +697,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
689
697
|
}
|
|
690
698
|
}
|
|
691
699
|
}
|
|
692
|
-
setDeployAttribute("deploy.pool.account", ss58);
|
|
700
|
+
setDeployAttribute("deploy.pool.account", truncateAddress(ss58));
|
|
693
701
|
console.log(`
|
|
694
702
|
All ${chunks.length} chunks included in block`);
|
|
695
703
|
console.log(` Verifying chunk integrity...`);
|
|
@@ -786,15 +794,16 @@ async function merkleize(directoryPath, outputCarPath) {
|
|
|
786
794
|
async function storeDirectory(directoryPath, provider = {}, password, jsMerkle) {
|
|
787
795
|
let carContent;
|
|
788
796
|
let ipfsCid;
|
|
797
|
+
const dirBasename = path.basename(directoryPath);
|
|
789
798
|
if (jsMerkle) {
|
|
790
|
-
const result = await withSpan("deploy.merkleize", "1a. merkleize (js)", { "deploy.directory":
|
|
799
|
+
const result = await withSpan("deploy.merkleize", "1a. merkleize (js)", { "deploy.directory": dirBasename }, async () => {
|
|
791
800
|
return merkleizeJS(directoryPath);
|
|
792
801
|
});
|
|
793
802
|
carContent = result.carBytes;
|
|
794
803
|
ipfsCid = result.cid;
|
|
795
804
|
} else {
|
|
796
805
|
const carPath = path.join(path.dirname(directoryPath), `${path.basename(directoryPath)}.car`);
|
|
797
|
-
const { cid } = await withSpan("deploy.merkleize", "1a. merkleize", { "deploy.directory":
|
|
806
|
+
const { cid } = await withSpan("deploy.merkleize", "1a. merkleize", { "deploy.directory": dirBasename }, async () => {
|
|
798
807
|
return merkleize(directoryPath, carPath);
|
|
799
808
|
});
|
|
800
809
|
ipfsCid = cid;
|
|
@@ -1006,6 +1015,7 @@ Or deploy with the original account, or use a different domain name.`);
|
|
|
1006
1015
|
export {
|
|
1007
1016
|
NonRetryableError,
|
|
1008
1017
|
EXIT_CODE_NO_RETRY,
|
|
1018
|
+
friendlyChainError,
|
|
1009
1019
|
DEFAULT_BULLETIN_RPC,
|
|
1010
1020
|
DEFAULT_POOL_SIZE,
|
|
1011
1021
|
isConnectionError,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
captureWarning,
|
|
3
3
|
withSpan
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3W2COGJ6.js";
|
|
5
5
|
|
|
6
6
|
// src/dotns.ts
|
|
7
7
|
import crypto from "crypto";
|
|
@@ -414,7 +414,7 @@ var DotNS = class {
|
|
|
414
414
|
return this;
|
|
415
415
|
} catch (e) {
|
|
416
416
|
lastError = e;
|
|
417
|
-
captureWarning("DotNS RPC endpoint failed, trying next", { endpoint: rpc, error: e.message, remainingEndpoints: endpoints.length - endpoints.indexOf(rpc) - 1 });
|
|
417
|
+
captureWarning("DotNS RPC endpoint failed, trying next", { endpoint: rpc, error: e.message?.slice(0, 200), remainingEndpoints: endpoints.length - endpoints.indexOf(rpc) - 1 });
|
|
418
418
|
console.log(` Failed to connect to ${rpc}: ${e.message}`);
|
|
419
419
|
if (this.client) {
|
|
420
420
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3W2COGJ6.js";
|
|
4
4
|
|
|
5
5
|
// src/version-check.ts
|
|
6
6
|
import { execSync, execFileSync } from "child_process";
|
|
@@ -17,6 +17,19 @@ function compareSemver(a, b) {
|
|
|
17
17
|
}
|
|
18
18
|
return 0;
|
|
19
19
|
}
|
|
20
|
+
function isPreReleaseVersion(version) {
|
|
21
|
+
return version.includes("-");
|
|
22
|
+
}
|
|
23
|
+
function preReleaseWarning(version) {
|
|
24
|
+
if (!isPreReleaseVersion(version)) return null;
|
|
25
|
+
return [
|
|
26
|
+
"",
|
|
27
|
+
`\u26A0\uFE0F Running bulletin-deploy ${version} (release candidate).`,
|
|
28
|
+
" This version is not recommended for production deploys.",
|
|
29
|
+
" For stable: npm install -g bulletin-deploy@latest",
|
|
30
|
+
""
|
|
31
|
+
].join("\n");
|
|
32
|
+
}
|
|
20
33
|
async function fetchJson(url) {
|
|
21
34
|
try {
|
|
22
35
|
const controller = new AbortController();
|
|
@@ -55,12 +68,38 @@ function isInternalUser() {
|
|
|
55
68
|
function isInteractive() {
|
|
56
69
|
return Boolean(process.stdin.isTTY && !process.env.CI);
|
|
57
70
|
}
|
|
58
|
-
async function promptYesNo(question) {
|
|
59
|
-
const
|
|
71
|
+
async function promptYesNo(question, input) {
|
|
72
|
+
const stdin = input ?? process.stdin;
|
|
73
|
+
if (!input && !process.stdin.isTTY) return false;
|
|
74
|
+
const rl = createInterface({ input: stdin, output: process.stderr });
|
|
75
|
+
let answered = false;
|
|
60
76
|
return new Promise((resolve) => {
|
|
77
|
+
rl.on("close", () => {
|
|
78
|
+
if (!answered) {
|
|
79
|
+
answered = true;
|
|
80
|
+
resolve(false);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
61
83
|
rl.question(question, (answer) => {
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
if (answered) return;
|
|
85
|
+
const a = answer.trim().toLowerCase();
|
|
86
|
+
if (a === "" || a === "y" || a === "yes") {
|
|
87
|
+
answered = true;
|
|
88
|
+
rl.close();
|
|
89
|
+
resolve(true);
|
|
90
|
+
} else if (a === "n" || a === "no") {
|
|
91
|
+
answered = true;
|
|
92
|
+
rl.close();
|
|
93
|
+
resolve(false);
|
|
94
|
+
} else {
|
|
95
|
+
rl.question(" Please answer Y or N: ", (retry) => {
|
|
96
|
+
if (answered) return;
|
|
97
|
+
const r = retry.trim().toLowerCase();
|
|
98
|
+
answered = true;
|
|
99
|
+
rl.close();
|
|
100
|
+
resolve(r === "" || r === "y" || r === "yes");
|
|
101
|
+
});
|
|
102
|
+
}
|
|
64
103
|
});
|
|
65
104
|
});
|
|
66
105
|
}
|
|
@@ -137,6 +176,8 @@ async function handleFailedDeploy(error) {
|
|
|
137
176
|
|
|
138
177
|
export {
|
|
139
178
|
compareSemver,
|
|
179
|
+
isPreReleaseVersion,
|
|
180
|
+
preReleaseWarning,
|
|
140
181
|
isInternalUser,
|
|
141
182
|
isInteractive,
|
|
142
183
|
promptYesNo,
|
package/dist/deploy.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ declare class NonRetryableError extends Error {
|
|
|
12
12
|
constructor(message: string);
|
|
13
13
|
}
|
|
14
14
|
declare const EXIT_CODE_NO_RETRY = 78;
|
|
15
|
+
declare function friendlyChainError(msg: string): string;
|
|
15
16
|
interface ProviderResult {
|
|
16
17
|
client: any;
|
|
17
18
|
unsafeApi: any;
|
|
@@ -70,4 +71,4 @@ interface DeployOptions {
|
|
|
70
71
|
}
|
|
71
72
|
declare function deploy(content: DeployContent, domainName?: string | null, options?: DeployOptions): Promise<DeployResult>;
|
|
72
73
|
|
|
73
|
-
export { DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, type DeployContent, type DeployOptions, type DeployResult, ENCRYPT_KEY_LEN, ENCRYPT_MAGIC, ENCRYPT_NONCE_LEN, ENCRYPT_PBKDF2_ITERATIONS, ENCRYPT_SALT_LEN, ENCRYPT_TAG_LEN, EXIT_CODE_NO_RETRY, NonRetryableError, chunk, createCID, deploy, deriveRootSigner, encodeContenthash, encryptContent, hasIPFS, isConnectionError, merkleize, storeChunkedContent, storeDirectory, storeFile };
|
|
74
|
+
export { DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, type DeployContent, type DeployOptions, type DeployResult, ENCRYPT_KEY_LEN, ENCRYPT_MAGIC, ENCRYPT_NONCE_LEN, ENCRYPT_PBKDF2_ITERATIONS, ENCRYPT_SALT_LEN, ENCRYPT_TAG_LEN, EXIT_CODE_NO_RETRY, NonRetryableError, chunk, createCID, deploy, deriveRootSigner, encodeContenthash, encryptContent, friendlyChainError, hasIPFS, isConnectionError, merkleize, storeChunkedContent, storeDirectory, storeFile };
|
package/dist/deploy.js
CHANGED
|
@@ -15,17 +15,18 @@ import {
|
|
|
15
15
|
deriveRootSigner,
|
|
16
16
|
encodeContenthash,
|
|
17
17
|
encryptContent,
|
|
18
|
+
friendlyChainError,
|
|
18
19
|
hasIPFS,
|
|
19
20
|
isConnectionError,
|
|
20
21
|
merkleize,
|
|
21
22
|
storeChunkedContent,
|
|
22
23
|
storeDirectory,
|
|
23
24
|
storeFile
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-IHFIWF2A.js";
|
|
26
|
+
import "./chunk-WOHUOD3E.js";
|
|
26
27
|
import "./chunk-GZ5UUECB.js";
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-CUFLI45S.js";
|
|
29
|
+
import "./chunk-3W2COGJ6.js";
|
|
29
30
|
import "./chunk-QGM4M3NI.js";
|
|
30
31
|
export {
|
|
31
32
|
DEFAULT_BULLETIN_RPC,
|
|
@@ -44,6 +45,7 @@ export {
|
|
|
44
45
|
deriveRootSigner,
|
|
45
46
|
encodeContenthash,
|
|
46
47
|
encryptContent,
|
|
48
|
+
friendlyChainError,
|
|
47
49
|
hasIPFS,
|
|
48
50
|
isConnectionError,
|
|
49
51
|
merkleize,
|
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-WOHUOD3E.js";
|
|
23
|
+
import "./chunk-3W2COGJ6.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-IHFIWF2A.js";
|
|
4
4
|
import {
|
|
5
5
|
DotNS
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WOHUOD3E.js";
|
|
7
7
|
import {
|
|
8
8
|
merkleizeJS
|
|
9
9
|
} from "./chunk-GZ5UUECB.js";
|
|
@@ -13,8 +13,8 @@ import {
|
|
|
13
13
|
ensureAuthorized,
|
|
14
14
|
fetchPoolAuthorizations,
|
|
15
15
|
selectAccount
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-CUFLI45S.js";
|
|
17
|
+
import "./chunk-3W2COGJ6.js";
|
|
18
18
|
import "./chunk-QGM4M3NI.js";
|
|
19
19
|
export {
|
|
20
20
|
DotNS,
|
package/dist/pool.d.ts
CHANGED
|
@@ -14,7 +14,11 @@ interface PoolAuthorization extends PoolAccount {
|
|
|
14
14
|
declare function derivePoolAccounts(poolSize?: number, mnemonic?: string): PoolAccount[];
|
|
15
15
|
declare function selectAccount(authorizations: PoolAuthorization[]): PoolAuthorization | null;
|
|
16
16
|
declare function fetchPoolAuthorizations(api: any, accounts: PoolAccount[]): Promise<PoolAuthorization[]>;
|
|
17
|
-
|
|
17
|
+
interface AuthorizationNeeds {
|
|
18
|
+
txs: bigint;
|
|
19
|
+
bytes: bigint;
|
|
20
|
+
}
|
|
21
|
+
declare function ensureAuthorized(api: any, address: string, bulletinRpc: string, label?: string, minimum?: AuthorizationNeeds): Promise<void>;
|
|
18
22
|
declare function bootstrapPool(bulletinRpc: string, poolSize?: number, mnemonic?: string): Promise<void>;
|
|
19
23
|
|
|
20
|
-
export { type PoolAccount, type PoolAuthorization, bootstrapPool, derivePoolAccounts, ensureAuthorized, fetchPoolAuthorizations, selectAccount };
|
|
24
|
+
export { type AuthorizationNeeds, type PoolAccount, type PoolAuthorization, bootstrapPool, derivePoolAccounts, ensureAuthorized, fetchPoolAuthorizations, selectAccount };
|
package/dist/pool.js
CHANGED
package/dist/telemetry.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
declare const VERSION: string;
|
|
2
|
+
interface InternalContextSignals {
|
|
3
|
+
githubRepository?: string;
|
|
4
|
+
runnerName?: string;
|
|
5
|
+
gitRemote?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function isInternalContextFromSignals(signals: InternalContextSignals): boolean;
|
|
8
|
+
declare function isInternalContext(): boolean;
|
|
9
|
+
declare function scrubPaths(msg: string): string;
|
|
10
|
+
declare function truncateAddress(ss58: string | undefined): string | undefined;
|
|
11
|
+
declare function sanitizeBranch(name: string | undefined): string | undefined;
|
|
12
|
+
declare function sanitizeRepo(slug: string | undefined): string | undefined;
|
|
2
13
|
declare function initTelemetry(): void;
|
|
3
14
|
declare function resolveRepo(domain: string): string;
|
|
4
15
|
declare function resolveRunner(): string;
|
|
5
16
|
declare function resolveRunnerType(): string;
|
|
17
|
+
declare function getDeployAttributes(domain: string): Record<string, string | number | boolean | undefined>;
|
|
6
18
|
declare function isExpectedError(msg: string): boolean;
|
|
7
19
|
declare function withSpan<T>(op: string, description: string, attributes: Record<string, string | number | boolean | undefined>, fn: () => T | Promise<T>): Promise<T>;
|
|
8
20
|
declare function withDeploySpan<T>(domain: string, fn: () => T | Promise<T>): Promise<T>;
|
|
@@ -10,4 +22,4 @@ declare function setDeployAttribute(key: string, value: string | number | boolea
|
|
|
10
22
|
declare function captureWarning(message: string, context?: Record<string, unknown>): void;
|
|
11
23
|
declare function flush(): Promise<void>;
|
|
12
24
|
|
|
13
|
-
export { VERSION, captureWarning, flush, initTelemetry, isExpectedError, resolveRepo, resolveRunner, resolveRunnerType, setDeployAttribute, withDeploySpan, withSpan };
|
|
25
|
+
export { type InternalContextSignals, VERSION, captureWarning, flush, getDeployAttributes, initTelemetry, isExpectedError, isInternalContext, isInternalContextFromSignals, resolveRepo, resolveRunner, resolveRunnerType, sanitizeBranch, sanitizeRepo, scrubPaths, setDeployAttribute, truncateAddress, withDeploySpan, withSpan };
|
package/dist/telemetry.js
CHANGED
|
@@ -2,26 +2,40 @@ import {
|
|
|
2
2
|
VERSION,
|
|
3
3
|
captureWarning,
|
|
4
4
|
flush,
|
|
5
|
+
getDeployAttributes,
|
|
5
6
|
initTelemetry,
|
|
6
7
|
isExpectedError,
|
|
8
|
+
isInternalContext,
|
|
9
|
+
isInternalContextFromSignals,
|
|
7
10
|
resolveRepo,
|
|
8
11
|
resolveRunner,
|
|
9
12
|
resolveRunnerType,
|
|
13
|
+
sanitizeBranch,
|
|
14
|
+
sanitizeRepo,
|
|
15
|
+
scrubPaths,
|
|
10
16
|
setDeployAttribute,
|
|
17
|
+
truncateAddress,
|
|
11
18
|
withDeploySpan,
|
|
12
19
|
withSpan
|
|
13
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-3W2COGJ6.js";
|
|
14
21
|
import "./chunk-QGM4M3NI.js";
|
|
15
22
|
export {
|
|
16
23
|
VERSION,
|
|
17
24
|
captureWarning,
|
|
18
25
|
flush,
|
|
26
|
+
getDeployAttributes,
|
|
19
27
|
initTelemetry,
|
|
20
28
|
isExpectedError,
|
|
29
|
+
isInternalContext,
|
|
30
|
+
isInternalContextFromSignals,
|
|
21
31
|
resolveRepo,
|
|
22
32
|
resolveRunner,
|
|
23
33
|
resolveRunnerType,
|
|
34
|
+
sanitizeBranch,
|
|
35
|
+
sanitizeRepo,
|
|
36
|
+
scrubPaths,
|
|
24
37
|
setDeployAttribute,
|
|
38
|
+
truncateAddress,
|
|
25
39
|
withDeploySpan,
|
|
26
40
|
withSpan
|
|
27
41
|
};
|
package/dist/version-check.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
|
|
1
3
|
interface VersionInfo {
|
|
2
4
|
latest: string;
|
|
3
5
|
minimumFromRegistry: string | null;
|
|
@@ -5,9 +7,11 @@ interface VersionInfo {
|
|
|
5
7
|
killSwitchMessage: string | null;
|
|
6
8
|
}
|
|
7
9
|
declare function compareSemver(a: string, b: string): number;
|
|
10
|
+
declare function isPreReleaseVersion(version: string): boolean;
|
|
11
|
+
declare function preReleaseWarning(version: string): string | null;
|
|
8
12
|
declare function isInternalUser(): boolean;
|
|
9
13
|
declare function isInteractive(): boolean;
|
|
10
|
-
declare function promptYesNo(question: string): Promise<boolean>;
|
|
14
|
+
declare function promptYesNo(question: string, input?: Readable): Promise<boolean>;
|
|
11
15
|
declare function classifyErrorArea(msg: string): string | null;
|
|
12
16
|
type VersionVerdict = {
|
|
13
17
|
action: "forced_update";
|
|
@@ -28,4 +32,4 @@ type VersionVerdict = {
|
|
|
28
32
|
declare function assessVersion(currentVersion: string, info: VersionInfo, internal: boolean): VersionVerdict;
|
|
29
33
|
declare function handleFailedDeploy(error: Error): Promise<void>;
|
|
30
34
|
|
|
31
|
-
export { type VersionVerdict, assessVersion, classifyErrorArea, compareSemver, handleFailedDeploy, isInteractive, isInternalUser, promptYesNo };
|
|
35
|
+
export { type VersionVerdict, assessVersion, classifyErrorArea, compareSemver, handleFailedDeploy, isInteractive, isInternalUser, isPreReleaseVersion, preReleaseWarning, promptYesNo };
|
package/dist/version-check.js
CHANGED
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
handleFailedDeploy,
|
|
6
6
|
isInteractive,
|
|
7
7
|
isInternalUser,
|
|
8
|
+
isPreReleaseVersion,
|
|
9
|
+
preReleaseWarning,
|
|
8
10
|
promptYesNo
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-X7WJJEXW.js";
|
|
12
|
+
import "./chunk-3W2COGJ6.js";
|
|
11
13
|
import "./chunk-QGM4M3NI.js";
|
|
12
14
|
export {
|
|
13
15
|
assessVersion,
|
|
@@ -16,5 +18,7 @@ export {
|
|
|
16
18
|
handleFailedDeploy,
|
|
17
19
|
isInteractive,
|
|
18
20
|
isInternalUser,
|
|
21
|
+
isPreReleaseVersion,
|
|
22
|
+
preReleaseWarning,
|
|
19
23
|
promptYesNo
|
|
20
24
|
};
|