bulletin-deploy 0.6.9 → 0.6.10
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 +95 -3
- package/bin/bulletin-deploy +3 -0
- package/dist/bug-report.js +2 -2
- package/dist/{chunk-BUAELY3G.js → chunk-2FXONN6K.js} +7 -2
- package/dist/{chunk-INDAKTSG.js → chunk-6QG2QJV4.js} +5 -2
- package/dist/{chunk-CE67XAQY.js → chunk-H4HN4RRK.js} +1 -1
- package/dist/{chunk-TF4MTBZF.js → chunk-PRT3B52H.js} +1 -1
- package/dist/deploy.d.ts +6 -0
- 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.js +2 -2
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -66,6 +66,10 @@ Options:
|
|
|
66
66
|
--playground Publish to the Playground remix registry
|
|
67
67
|
--js-merkle Use pure-JS merkleization (no IPFS Kubo binary required)
|
|
68
68
|
--pool-size N Number of pool accounts (default: 10)
|
|
69
|
+
--tag "..." Free-form label attached to the deploy span as deploy.tag
|
|
70
|
+
(see Telemetry section). Use to isolate test/benchmark/canary
|
|
71
|
+
runs from real-user traffic in Sentry dashboards. Also readable
|
|
72
|
+
from DEPLOY_TAG env var.
|
|
69
73
|
--help Show help
|
|
70
74
|
```
|
|
71
75
|
|
|
@@ -247,9 +251,97 @@ What's tracked:
|
|
|
247
251
|
- Source metadata (repo, branch, PR number, CI vs local)
|
|
248
252
|
- Tool version (`deploy.tool_version`)
|
|
249
253
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
-
|
|
254
|
+
### Tagging test and benchmark runs
|
|
255
|
+
|
|
256
|
+
Real-user deploys and automated test/benchmark deploys share the same telemetry pipeline. Use `--tag` (or the `DEPLOY_TAG` env var) to label non-production runs so Sentry dashboards can filter them out:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
bulletin-deploy --tag e2e-ci-pr ./build my-app.dot
|
|
260
|
+
DEPLOY_TAG=load-test bulletin-deploy ./build my-app.dot
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The `tag` value is attached to the deploy span as `deploy.tag` (plus propagated through every child span).
|
|
264
|
+
|
|
265
|
+
Convention used in this repo:
|
|
266
|
+
- `e2e-ci-pr` / `e2e-ci-nightly` — CI-driven E2E runs (per-PR and nightly matrices).
|
|
267
|
+
- `e2e-local-smoke` / `e2e-local-pr` / `e2e-local-nightly` — maintainer-invoked E2E via `scripts/e2e-pass.sh`.
|
|
268
|
+
- Untagged — real-user deploys.
|
|
269
|
+
|
|
270
|
+
Sentry filter examples:
|
|
271
|
+
- Exclude all test traffic from a dashboard: `!has:deploy.tag`
|
|
272
|
+
- Only CI E2E: `deploy.tag:e2e-ci-*`
|
|
273
|
+
- Only nightly runs (local or CI): `deploy.tag:e2e-ci-nightly OR deploy.tag:e2e-local-nightly`
|
|
274
|
+
|
|
275
|
+
The shipped reusable workflow (`.github/workflows/deploy.yml`) exposes a `tag` input that feeds through to the CLI — pass it from caller workflows that do non-production deploys.
|
|
276
|
+
|
|
277
|
+
Dashboards:
|
|
278
|
+
- **Bulletin Deploy Health**: https://paritytech.sentry.io/dashboard/1669817/?project=4511093597405264 — overall deploy health across all consumer repos
|
|
279
|
+
- **Deploy Failures Detail**: https://paritytech.sentry.io/dashboard/1669818/?project=4511093597405264 — error drill-down
|
|
280
|
+
- **E2E Health (bulletin-deploy)**: https://paritytech.sentry.io/dashboard/1732713/?project=4511093597405264 — E2E suite pass rate, duration, and per-signer failure distribution (filtered by `deploy.tag:e2e-*`)
|
|
281
|
+
|
|
282
|
+
## Testing
|
|
283
|
+
|
|
284
|
+
Three layers of coverage: offline unit tests for pure helpers, live-testnet end-to-end tests that exercise the shipped reusable workflow, and CI matrices that run both per-PR and nightly.
|
|
285
|
+
|
|
286
|
+
### Offline unit tests
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
npm test
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Runs `test/test.js` + `test/pool.test.js` + `test/helpers/e2e-helpers.test.js` via `node --test`. No network. ~5 seconds. Always runs on every PR via GitHub Actions.
|
|
293
|
+
|
|
294
|
+
### Live-testnet E2E
|
|
295
|
+
|
|
296
|
+
Three scenarios land on Paseo Bulletin:
|
|
297
|
+
|
|
298
|
+
- **S1** — happy path on a stable label (`e2epool.dot` / `e2edirect.dot`)
|
|
299
|
+
- **S2** — fresh registration via commit-reveal (nightly only)
|
|
300
|
+
- **S3** — deploy to `e2eowned.dot` (owned by a different account), expects `EXIT_CODE_NO_RETRY` (78) and the "owned by a different account" error message
|
|
301
|
+
|
|
302
|
+
**Prerequisites** (one-time per testnet lifetime): see [`docs/e2e-bootstrap.md`](docs/e2e-bootstrap.md). Grants Alice PoP Full, funds+maps Bob, pre-registers `e2eowned.dot` to Bob via `dotns-cli`.
|
|
303
|
+
|
|
304
|
+
**Local launchers:**
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
npm run test:e2e:smoke # 1 scenario (S1 pool/js) ~5 min
|
|
308
|
+
npm run test:e2e:pr # 3 scenarios (matches per-PR CI) ~15 min
|
|
309
|
+
npm run test:e2e:nightly # 7 scenarios (matches nightly CI) ~30–45 min
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
All three run through to completion even if one fails; a colored summary prints at the end with per-scenario pass/fail, timing, JUnit report paths, and a pre-filtered Sentry trace link.
|
|
313
|
+
|
|
314
|
+
**Agent-friendly / quiet mode** — `E2E_QUIET=1` suppresses the live streaming output (`node:test` spec reporter + bulletin-deploy stdio + build logs) while still printing the summary and writing structured reports. Works with every mode:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
E2E_QUIET=1 npm run test:e2e:smoke
|
|
318
|
+
E2E_QUIET=1 npm run test:e2e:pr
|
|
319
|
+
E2E_QUIET=1 npm run test:e2e:nightly
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Equivalent flag form: `bash scripts/e2e-pass.sh --quiet <mode>`.
|
|
323
|
+
|
|
324
|
+
**JUnit reports** — every scenario writes one to `e2e-reports/<scenario>-<signer>-<merkle>.xml` regardless of quiet mode. Consume via any JUnit-compatible tool, or just `cat` the XML — `<failure>` blocks carry the assertion message and stack.
|
|
325
|
+
|
|
326
|
+
### CI matrices (`.github/workflows/e2e.yml`)
|
|
327
|
+
|
|
328
|
+
The CI workflow **calls the shipped reusable `.github/workflows/deploy.yml`** for every scenario — so each E2E job runs exactly the code path real consumers hit. Per-PR tests HEAD via `bulletin-deploy-version: "git+https://...#<sha>"` (the `prepare` npm script builds `dist/` during install). Nightly leaves the version empty so it tests the latest published release.
|
|
329
|
+
|
|
330
|
+
- **Per-PR** (3 jobs): on `pull_request` and `push` to `main`. S1 pool/js + S1 direct/kubo + S3 negative. Posts a sticky comment on the PR with results and updates in place on re-runs.
|
|
331
|
+
- **Nightly** (11 jobs): scheduled `0 3 * * *` UTC. Full S1 signer×merkle×runner cube + S2 pool/direct fresh-registration + S3. Failures auto-open a GitHub issue.
|
|
332
|
+
|
|
333
|
+
Every deploy job passes `tag: e2e-ci-pr` or `tag: e2e-ci-nightly` through to the CLI, so the E2E traffic is tagged in Sentry and can be filtered out of real-user dashboards (see Telemetry → Tagging test and benchmark runs above).
|
|
334
|
+
|
|
335
|
+
### Tag convention in this repo
|
|
336
|
+
|
|
337
|
+
| Trigger | `deploy.tag` |
|
|
338
|
+
|---|---|
|
|
339
|
+
| `npm run test:e2e:smoke` | `e2e-local-smoke` |
|
|
340
|
+
| `npm run test:e2e:pr` | `e2e-local-pr` |
|
|
341
|
+
| `npm run test:e2e:nightly` | `e2e-local-nightly` |
|
|
342
|
+
| E2E workflow per-PR | `e2e-ci-pr` |
|
|
343
|
+
| E2E workflow nightly | `e2e-ci-nightly` |
|
|
344
|
+
| Real-user deploys | _none_ (`!has:deploy.tag`) |
|
|
253
345
|
|
|
254
346
|
## Troubleshooting
|
|
255
347
|
|
package/bin/bulletin-deploy
CHANGED
|
@@ -20,6 +20,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
20
20
|
else if (args[i] === "--password") { flags.password = args[++i]; }
|
|
21
21
|
else if (args[i] === "--playground") { flags.playground = true; }
|
|
22
22
|
else if (args[i] === "--js-merkle") { flags.jsMerkle = true; }
|
|
23
|
+
else if (args[i] === "--tag") { flags.tag = args[++i]; }
|
|
23
24
|
else if (args[i] === "--version" || args[i] === "-V") { flags.version = true; }
|
|
24
25
|
else if (args[i] === "--help" || args[i] === "-h") { flags.help = true; }
|
|
25
26
|
else { positional.push(args[i]); }
|
|
@@ -45,6 +46,7 @@ Options:
|
|
|
45
46
|
--password "..." Encrypt SPA content (users will be prompted to decrypt)
|
|
46
47
|
--playground Publish to the playground remix registry
|
|
47
48
|
--js-merkle Use pure-JS merkleization (no IPFS Kubo binary required)
|
|
49
|
+
--tag "..." Label deploy in telemetry (or set DEPLOY_TAG env var); see Telemetry in README
|
|
48
50
|
--version Show version
|
|
49
51
|
--help Show this help`);
|
|
50
52
|
process.exit(0);
|
|
@@ -80,6 +82,7 @@ try {
|
|
|
80
82
|
poolSize: flags.poolSize,
|
|
81
83
|
password: flags.password,
|
|
82
84
|
jsMerkle: flags.jsMerkle,
|
|
85
|
+
tag: flags.tag,
|
|
83
86
|
});
|
|
84
87
|
|
|
85
88
|
const output = process.env.GITHUB_OUTPUT;
|
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-PRT3B52H.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2FXONN6K.js";
|
|
9
9
|
import "./chunk-QGM4M3NI.js";
|
|
10
10
|
|
|
11
11
|
// src/bug-report.ts
|
|
@@ -7,7 +7,7 @@ import * as path from "path";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "bulletin-deploy",
|
|
10
|
-
version: "0.6.
|
|
10
|
+
version: "0.6.10",
|
|
11
11
|
private: false,
|
|
12
12
|
repository: {
|
|
13
13
|
type: "git",
|
|
@@ -36,7 +36,12 @@ var package_default = {
|
|
|
36
36
|
],
|
|
37
37
|
scripts: {
|
|
38
38
|
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",
|
|
39
|
-
|
|
39
|
+
prepare: "npm run build",
|
|
40
|
+
test: "npm run build && node --test test/test.js test/pool.test.js test/helpers/e2e-helpers.test.js",
|
|
41
|
+
"test:e2e": "npm run build && node --test test/e2e.test.js",
|
|
42
|
+
"test:e2e:smoke": "bash scripts/e2e-pass.sh smoke",
|
|
43
|
+
"test:e2e:pr": "bash scripts/e2e-pass.sh pr",
|
|
44
|
+
"test:e2e:nightly": "bash scripts/e2e-pass.sh nightly",
|
|
40
45
|
benchmark: "npm run build && node benchmark.js"
|
|
41
46
|
},
|
|
42
47
|
dependencies: {
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
fetchNonce,
|
|
6
6
|
popStatusName,
|
|
7
7
|
validateDomainLabel
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-H4HN4RRK.js";
|
|
9
9
|
import {
|
|
10
10
|
merkleizeJS
|
|
11
11
|
} from "./chunk-GZ5UUECB.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
truncateAddress,
|
|
28
28
|
withDeploySpan,
|
|
29
29
|
withSpan
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-2FXONN6K.js";
|
|
31
31
|
|
|
32
32
|
// src/deploy.ts
|
|
33
33
|
import { Buffer } from "buffer";
|
|
@@ -884,12 +884,15 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
884
884
|
const rawName = domainName ? domainName.replace(".dot", "") : `test-domain-${Date.now().toString(36)}${randomSuffix}`;
|
|
885
885
|
const name = validateDomainLabel(rawName);
|
|
886
886
|
return withDeploySpan(name, async () => {
|
|
887
|
+
const deployTag = options.tag ?? process.env.DEPLOY_TAG;
|
|
888
|
+
if (deployTag) setDeployAttribute("deploy.tag", deployTag);
|
|
887
889
|
let cid;
|
|
888
890
|
let ipfsCid;
|
|
889
891
|
console.log("\n" + "=".repeat(60));
|
|
890
892
|
console.log(`DEPLOYING TO TESTNET v${VERSION}`);
|
|
891
893
|
console.log("=".repeat(60));
|
|
892
894
|
console.log(` Domain: ${name}.dot`);
|
|
895
|
+
if (deployTag) console.log(` Tag: ${deployTag}`);
|
|
893
896
|
if (typeof content === "string") console.log(` Build dir: ${path.resolve(content)}`);
|
|
894
897
|
if (process.env.CI) console.log(` Runner: ${resolveRunner()} (${resolveRunnerType()})`);
|
|
895
898
|
if (options.password) console.log(` Encrypted: yes`);
|
package/dist/deploy.d.ts
CHANGED
|
@@ -68,6 +68,12 @@ interface DeployOptions {
|
|
|
68
68
|
password?: string;
|
|
69
69
|
/** Use pure-JS merkleization instead of Kubo CLI. Required for WebContainer environments. */
|
|
70
70
|
jsMerkle?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Free-form label attached to the deploy span as `deploy.tag`. Used to separate
|
|
73
|
+
* test/benchmark/canary runs from real-user traffic in Sentry dashboards
|
|
74
|
+
* (e.g. "e2e-ci-pr", "load-test-a"). Falls back to DEPLOY_TAG env var.
|
|
75
|
+
*/
|
|
76
|
+
tag?: string;
|
|
71
77
|
/** Custom telemetry attributes, merged into the deploy span. Overrides auto-detected values. */
|
|
72
78
|
attributes?: Record<string, string>;
|
|
73
79
|
}
|
package/dist/deploy.js
CHANGED
|
@@ -23,11 +23,11 @@ import {
|
|
|
23
23
|
storeChunkedContent,
|
|
24
24
|
storeDirectory,
|
|
25
25
|
storeFile
|
|
26
|
-
} from "./chunk-
|
|
27
|
-
import "./chunk-
|
|
26
|
+
} from "./chunk-6QG2QJV4.js";
|
|
27
|
+
import "./chunk-H4HN4RRK.js";
|
|
28
28
|
import "./chunk-GZ5UUECB.js";
|
|
29
29
|
import "./chunk-JHNW2EKY.js";
|
|
30
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-2FXONN6K.js";
|
|
31
31
|
import "./chunk-QGM4M3NI.js";
|
|
32
32
|
export {
|
|
33
33
|
DEFAULT_BULLETIN_RPC,
|
package/dist/dotns.js
CHANGED
|
@@ -24,9 +24,9 @@ import {
|
|
|
24
24
|
simulateUserStatus,
|
|
25
25
|
stripTrailingDigits,
|
|
26
26
|
validateDomainLabel
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-H4HN4RRK.js";
|
|
28
28
|
import "./chunk-JHNW2EKY.js";
|
|
29
|
-
import "./chunk-
|
|
29
|
+
import "./chunk-2FXONN6K.js";
|
|
30
30
|
import "./chunk-QGM4M3NI.js";
|
|
31
31
|
export {
|
|
32
32
|
CONNECTION_TIMEOUT_MS,
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deploy
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6QG2QJV4.js";
|
|
4
4
|
import {
|
|
5
5
|
DotNS
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-H4HN4RRK.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-JHNW2EKY.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-2FXONN6K.js";
|
|
18
18
|
import "./chunk-QGM4M3NI.js";
|
|
19
19
|
export {
|
|
20
20
|
DotNS,
|
package/dist/telemetry.js
CHANGED
package/dist/version-check.js
CHANGED
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
isPreReleaseVersion,
|
|
9
9
|
preReleaseWarning,
|
|
10
10
|
promptYesNo
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-PRT3B52H.js";
|
|
12
|
+
import "./chunk-2FXONN6K.js";
|
|
13
13
|
import "./chunk-QGM4M3NI.js";
|
|
14
14
|
export {
|
|
15
15
|
assessVersion,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bulletin-deploy",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,7 +29,12 @@
|
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
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
|
+
"prepare": "npm run build",
|
|
33
|
+
"test": "npm run build && node --test test/test.js test/pool.test.js test/helpers/e2e-helpers.test.js",
|
|
34
|
+
"test:e2e": "npm run build && node --test test/e2e.test.js",
|
|
35
|
+
"test:e2e:smoke": "bash scripts/e2e-pass.sh smoke",
|
|
36
|
+
"test:e2e:pr": "bash scripts/e2e-pass.sh pr",
|
|
37
|
+
"test:e2e:nightly": "bash scripts/e2e-pass.sh nightly",
|
|
33
38
|
"benchmark": "npm run build && node benchmark.js"
|
|
34
39
|
},
|
|
35
40
|
"dependencies": {
|