@norskvideo/ctl-dev-kit 0.2.67 → 0.2.69
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/build/ctl-shell.nix +20 -2
- package/build/flake.nix +1 -1
- package/build/flake.sdk-app.nix +4 -4
- package/conventions/check-drift.ts +33 -0
- package/conventions/sync-drift.ts +25 -0
- package/create-product/turnkey.ts +4 -1
- package/package.json +2 -2
package/build/ctl-shell.nix
CHANGED
|
@@ -9,6 +9,24 @@
|
|
|
9
9
|
# need GitHub auth in every shell and CI runner.
|
|
10
10
|
{ pkgs, biome }:
|
|
11
11
|
let
|
|
12
|
+
# Bun from its own nixpkgs pin, so ctl and every product run one Bun, and
|
|
13
|
+
# bumping it is one edit here (the dev-kit sync carries it to the products)
|
|
14
|
+
# rather than moving the main nixpkgs pin, and with it Chromium and every
|
|
15
|
+
# other tool. Fetched by hash, so each repo shares one store path.
|
|
16
|
+
#
|
|
17
|
+
# 1.4.2: 1.3.13's node:http2 client segfaulted in its HPACK encoder
|
|
18
|
+
# (lshpack.HPACK.encode from H2FrameParser.request) — norsk-mgr's gRPC client
|
|
19
|
+
# to the Manager, killed mid-drain and mid-migration in the nightly e2e.
|
|
20
|
+
# Keep each repo's package.json "packageManager" (its image's Bun) on the
|
|
21
|
+
# same version. That nixpkgs no longer builds x86_64-darwin, which keeps the
|
|
22
|
+
# main pin's.
|
|
23
|
+
bun =
|
|
24
|
+
if pkgs.stdenv.hostPlatform.system == "x86_64-darwin" then pkgs.bun
|
|
25
|
+
else (import (builtins.fetchTarball {
|
|
26
|
+
url = "https://github.com/NixOS/nixpkgs/archive/e7439b6b14ad3cc35d05608ebca9bce01a25f5f8.tar.gz"; # bun 1.4.2
|
|
27
|
+
sha256 = "19y4py973w62z4qb7gzn0chjs67ihxy8rbjb7g71iyk8yz7z5k8z";
|
|
28
|
+
}) { inherit (pkgs.stdenv.hostPlatform) system; }).bun;
|
|
29
|
+
|
|
12
30
|
# Playwright doc-guide browser. nix-pinned headless Chromium needs a real X
|
|
13
31
|
# display on a truly headless box (page.fill silently no-ops on plain HTML
|
|
14
32
|
# inputs; some pages crash the renderer). Ubuntu's apt Xvfb is too old for
|
|
@@ -42,7 +60,7 @@ let
|
|
|
42
60
|
|
|
43
61
|
buildTools = [
|
|
44
62
|
biome
|
|
45
|
-
|
|
63
|
+
bun
|
|
46
64
|
pkgs.nodejs # @biomejs/biome's bin is a JS wrapper, not the binary — it is
|
|
47
65
|
# what reads BIOME_BINARY and execs the nix build. Something has
|
|
48
66
|
# to *parse* that wrapper first, so a modern node has to be on
|
|
@@ -91,7 +109,7 @@ let
|
|
|
91
109
|
};
|
|
92
110
|
in
|
|
93
111
|
{
|
|
94
|
-
inherit browserInputs browserHook buildTools mkCtl shell;
|
|
112
|
+
inherit browserInputs browserHook buildTools bun mkCtl shell;
|
|
95
113
|
|
|
96
114
|
# The Studio-product shells:
|
|
97
115
|
# default / dev -> build tools + the pinned norsk-ctl daemon on PATH
|
package/build/flake.nix
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
description = "norsk-ctl product build + dev shell";
|
|
20
20
|
|
|
21
21
|
inputs = {
|
|
22
|
-
nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15,
|
|
22
|
+
nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15, chromium 148.0.7778.167 (bun comes from its own pin in nix/ctl-shell.nix)
|
|
23
23
|
# Biome must match the version pinned in package.json (@biomejs/biome 2.5.5)
|
|
24
24
|
# exactly: 2.4.x can't parse this repo's biome.json (`rules.preset` is a
|
|
25
25
|
# 2.5 key) and any other 2.5.x emits a version-mismatch info that breaks the
|
package/build/flake.sdk-app.nix
CHANGED
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
# result belongs to a commit, and moved nightly by bump.yml. Decision: bun for tooling (install / build /
|
|
14
14
|
# test), Node for the shipped runtime (the SDK's blessed runtime).
|
|
15
15
|
#
|
|
16
|
-
# nixpkgs is pinned to the same rev the Studio flake uses, so
|
|
17
|
-
# fleet's
|
|
16
|
+
# nixpkgs is pinned to the same rev the Studio flake uses, so the store is
|
|
17
|
+
# shared; bun is the fleet's, from its own pin in nix/ctl-shell.nix.
|
|
18
18
|
description = "norsk-ctl sdk-app product dev shell (bun tooling + node runtime)";
|
|
19
19
|
|
|
20
20
|
inputs = {
|
|
21
|
-
nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15
|
|
21
|
+
nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15 (bun comes from its own pin in nix/ctl-shell.nix)
|
|
22
22
|
# Biome must match the version pinned in package.json (@biomejs/biome 2.5.5)
|
|
23
23
|
# exactly; the node_modules biome binary is glibc-linked and can't run on
|
|
24
24
|
# NixOS, so `bun run lint` execs this nix build via BIOME_BINARY. Keep this
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
ffmpegFull = pkgs.ffmpeg-full;
|
|
46
46
|
tools = [
|
|
47
47
|
biome # `bun run lint` execs this via BIOME_BINARY
|
|
48
|
-
|
|
48
|
+
ctlShell.bun # tooling: install / build / test; its own pin, shared with ctl and every product
|
|
49
49
|
pkgs.nodejs # the shipped runtime (bin/run -> node lib/index.js); also
|
|
50
50
|
# parses @biomejs/biome's JS wrapper that reads BIOME_BINARY
|
|
51
51
|
pkgs.git
|
|
@@ -412,6 +412,38 @@ export function productLogsProblems(repoRoot: string): string[] {
|
|
|
412
412
|
];
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
+
/** The Bun the dev-kit's build/ctl-shell.nix pins: the version its pin's URL
|
|
416
|
+
* line names (`… .tar.gz"; # bun 1.4.2`). The shell runs it; the product's
|
|
417
|
+
* image runs package.json's "packageManager", which must name the same. */
|
|
418
|
+
export function pinnedBunVersion(ctlShell: string): string | undefined {
|
|
419
|
+
return /archive\/[0-9a-f]{40}\.tar\.gz"; # bun (\d+\.\d+\.\d+)/.exec(ctlShell)?.[1];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/** package.json's "packageManager" against the shell's Bun. They drifted once
|
|
423
|
+
* already: the fleet's shells and images ran 1.3.13 by agreement alone, and a
|
|
424
|
+
* move to 1.4.2 (1.3.13's HTTP/2 client segfaulted) had to touch every repo. */
|
|
425
|
+
export function bunVersionProblems(repoRoot: string, ctlShellCanonical: string): string[] {
|
|
426
|
+
const want = pinnedBunVersion(ctlShellCanonical);
|
|
427
|
+
if (want === undefined) {
|
|
428
|
+
return ["@norskvideo/ctl-dev-kit build/ctl-shell.nix names no Bun version on its pin (`# bun X.Y.Z`)."];
|
|
429
|
+
}
|
|
430
|
+
const pkgPath = join(repoRoot, "package.json");
|
|
431
|
+
if (!existsSync(pkgPath)) return [];
|
|
432
|
+
let have: unknown;
|
|
433
|
+
try {
|
|
434
|
+
have = (JSON.parse(readFileSync(pkgPath, "utf8")) as { packageManager?: unknown }).packageManager;
|
|
435
|
+
} catch (e) {
|
|
436
|
+
return [`package.json is not parseable JSON (${e instanceof Error ? e.message : String(e)}).`];
|
|
437
|
+
}
|
|
438
|
+
return have === `bun@${want}`
|
|
439
|
+
? []
|
|
440
|
+
: [
|
|
441
|
+
`package.json "packageManager" is ${JSON.stringify(have ?? null)}, not "bun@${want}": it is the Bun the ` +
|
|
442
|
+
"product's image runs, and must be the one the shell runs (@norskvideo/ctl-dev-kit build/ctl-shell.nix). " +
|
|
443
|
+
"Re-sync to set it.",
|
|
444
|
+
];
|
|
445
|
+
}
|
|
446
|
+
|
|
415
447
|
// A file that must be a verbatim, byte-for-byte copy of its dev-kit canonical.
|
|
416
448
|
function verbatimProblem(
|
|
417
449
|
repoRoot: string,
|
|
@@ -862,6 +894,7 @@ export function checkDrift(repoRoot: string, canonical: CanonicalBytes, opts: Ch
|
|
|
862
894
|
|
|
863
895
|
for (const p of demoProblems(repoRoot, canonical.demoShim)) push(p);
|
|
864
896
|
for (const p of productLogsProblems(repoRoot)) push(p);
|
|
897
|
+
for (const p of bunVersionProblems(repoRoot, canonical.ctlShell)) push(p);
|
|
865
898
|
for (const p of ctlPinProblems(repoRoot)) push(p);
|
|
866
899
|
|
|
867
900
|
return { ok: problems.length === 0, problems };
|
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
PRODUCT_SENTINEL,
|
|
49
49
|
type ProductShape,
|
|
50
50
|
PUBLISH_IMAGE_LINE,
|
|
51
|
+
pinnedBunVersion,
|
|
51
52
|
RETIRED_BUMP_WORKFLOWS,
|
|
52
53
|
RUNNER_LINE,
|
|
53
54
|
resolveRepoName,
|
|
@@ -401,6 +402,29 @@ function syncDocsTheme(repoRoot: string, r: SyncReport): void {
|
|
|
401
402
|
for (const rel of adrift) r.written.push(`${DOCS_SITE_DIR}/${rel}`);
|
|
402
403
|
}
|
|
403
404
|
|
|
405
|
+
// package.json "packageManager": the Bun the product's image runs, set to the
|
|
406
|
+
// one the shell pins (build/ctl-shell.nix), so a Bun move reaches every
|
|
407
|
+
// product through its sync. Only that field's value is rewritten, so the
|
|
408
|
+
// file's own formatting stays. A package.json with no field is left for the
|
|
409
|
+
// gate to flag.
|
|
410
|
+
function syncPackageManager(repoRoot: string, ctlShell: string, r: SyncReport): void {
|
|
411
|
+
const want = pinnedBunVersion(ctlShell);
|
|
412
|
+
const path = join(repoRoot, "package.json");
|
|
413
|
+
if (want === undefined || !existsSync(path)) return;
|
|
414
|
+
const current = readFileSync(path, "utf8");
|
|
415
|
+
const field = /("packageManager"\s*:\s*")[^"]*(")/;
|
|
416
|
+
if (!field.test(current)) {
|
|
417
|
+
r.skipped.push("package.json (no packageManager to set)");
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
writeIfChanged(
|
|
421
|
+
path,
|
|
422
|
+
current.replace(field, (_m, a: string, b: string) => `${a}bun@${want}${b}`),
|
|
423
|
+
"package.json",
|
|
424
|
+
r.written,
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
404
428
|
export function syncDrift(
|
|
405
429
|
repoRoot: string,
|
|
406
430
|
canonical: CanonicalBytes,
|
|
@@ -448,6 +472,7 @@ export function syncDrift(
|
|
|
448
472
|
|
|
449
473
|
mkdirSync(dirname(join(repoRoot, CTL_SHELL_PATH)), { recursive: true });
|
|
450
474
|
writeIfChanged(join(repoRoot, CTL_SHELL_PATH), canonical.ctlShell, CTL_SHELL_PATH, r.written);
|
|
475
|
+
syncPackageManager(repoRoot, canonical.ctlShell, r);
|
|
451
476
|
syncFlake(repoRoot, flakeCanon, r);
|
|
452
477
|
syncClaude(repoRoot, canonical.core, r);
|
|
453
478
|
syncGitignore(repoRoot, canonical.gitignoreCore, r);
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
// from the schema package, addComponent/stubbedLibrary with a THROWING
|
|
14
14
|
// validate(), INVARIANTS + parity + byte-snapshot + studio-load wired into
|
|
15
15
|
// test:unit, and an image smoke tier.
|
|
16
|
+
|
|
17
|
+
import { pinnedBunVersion } from "../conventions/check-drift.ts";
|
|
16
18
|
import {
|
|
17
19
|
type GeneratedFile,
|
|
18
20
|
PRODUCT_ZOD,
|
|
@@ -362,7 +364,8 @@ function rootPackageJson(ctx: ShapeContext): string {
|
|
|
362
364
|
"@types/node": "^22.10.0",
|
|
363
365
|
typescript: "^5.7.2",
|
|
364
366
|
},
|
|
365
|
-
|
|
367
|
+
// The shell's Bun (build/ctl-shell.nix): the drift gate holds the two together.
|
|
368
|
+
packageManager: `bun@${pinnedBunVersion(ctx.canon.ctlShell)}`,
|
|
366
369
|
overrides: {
|
|
367
370
|
ws: "^8.20.1",
|
|
368
371
|
"shell-quote": "^1.9.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@norskvideo/ctl-dev-kit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.69",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./create-product": "./create-product/create-product.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@norskvideo/ctl-oas-to-ts": "^0.1.0",
|
|
41
|
-
"@norskvideo/norsk-sdk": "1.3.1-2026-10-
|
|
41
|
+
"@norskvideo/norsk-sdk": "1.3.1-2026-10-10-c587f1cc",
|
|
42
42
|
"@norskvideo/norsk-studio": "1.30.0-2026-10-10-c2e37ae9",
|
|
43
43
|
"@norskvideo/norsk-studio-builder": "1.30.0-2026-10-10-c2e37ae9",
|
|
44
44
|
"@norskvideo/norsk-studio-built-ins": "1.30.0-2026-10-10-c2e37ae9",
|