One-node bed: SDK-by-version, rename, and the store/broker upgrade proofs #27

Merged
jschoubben merged 26 commits from feat/a-bed-that-hands-over-nothing into main 2026-09-16 21:25:34 +00:00
Showing only changes of commit c3d5ec1d55 - Show all commits
+28 -7
View File
@@ -74,7 +74,7 @@ const BASE = { module: "mesh-tools", repo: "mesh-tools", path: "" };
* record of, so it provides nothing to anything. A module asking for `amqp` is asking for a
* provider in the graph, and this is it. No build: its image is upstream.
*/
const PROVIDER = { module: "lavinmq" };
const PROVIDER = { module: "lavinmq", repo: "mesh-catalog", path: "modules/lavinmq" };
/** Named once, because the step title is also how later steps say what they waited on. */
const NEEDS = "the mesh runs a broker for that module to talk to";
const MODULE = { module: "amqp-ping", repo: "mesh-catalog", path: "modules/amqp-ping" };
@@ -101,8 +101,21 @@ function forgeUrl(repo: string): string {
if (override) return override;
return source.replace(/[^/]+\.git$/, `${repo}.git`);
}
/** A branch is acceptable for an ordinary build; only genesis insists on a commit (ADR 0071). */
const buildRef = process.env["MESH_LAB_BUILD_REF"] ?? "main";
/**
* What to build, per repository.
*
* A branch is acceptable for an ordinary build; only genesis insists on a commit (ADR 0071). Per
* repository rather than one value for all of them, because a change under test usually lives in
* one repository and the rest should be built from what everyone else has — building them all from
* a feature branch would prove that branch against itself.
*
* MESH_LAB_BUILD_REF the default for every repository
* MESH_LAB_BUILD_REF_MESH_CATALOG ...overridden for one
*/
function refFor(repo: string): string {
const override = process.env[`MESH_LAB_BUILD_REF_${repo.toUpperCase().replaceAll("-", "_")}`];
return override ?? process.env["MESH_LAB_BUILD_REF"] ?? "main";
}
/**
* The shared base's manifest, on this workstation.
@@ -290,7 +303,7 @@ before(async () => {
// needs that record, is where it surfaced.
await registerModule(BASE.module, baseManifest);
const built = await mesh(
`build ${forgeUrl(BASE.repo)} --ref ${buildRef} --wait 1200s`, 1_500_000);
`build ${forgeUrl(BASE.repo)} --ref ${refFor(BASE.repo)} --wait 1200s`, 1_500_000);
assert.doesNotMatch(built, /failed/i, built);
return built;
});
@@ -300,7 +313,7 @@ before(async () => {
"the mesh builds the shared base from source", async () => {
await registerModule(MODULE.module, resolve(catalogDir, MODULE.module, "module.json"));
const built = await mesh(
`build ${forgeUrl(MODULE.repo)} --path ${MODULE.path} --ref ${buildRef} --wait 1200s`,
`build ${forgeUrl(MODULE.repo)} --path ${MODULE.path} --ref ${refFor(MODULE.repo)} --wait 1200s`,
1_500_000);
assert.doesNotMatch(built, /failed/i, built);
// The point of the whole step: what came out is named by a digest this mesh's registry
@@ -320,10 +333,18 @@ before(async () => {
// with something to offer — the mesh's own plumbing, not an entry in its graph. A module that
// wants a broker wants one the mesh knows about.
//
// `lavinmq` is that module, and it needs no building: its image is upstream, so this is a
// register and an assign, and it is a fair test of provisioning rather than of building.
// `lavinmq` is that module. It was first added here on the belief that it needed no building —
// its broker is an upstream image — and the mesh refused it: two of its three containers named a
// placeholder digest, "which is never a real image". That was right. The broker is upstream, but
// the module is not only the broker: it carries a run-once bootstrap that writes the broker's
// configuration, a provisioner that grants each consumer its own vhost and user, tools and an
// event consumer. All of that is its own code and has to be built like anything else.
await step(NEEDS, "the mesh builds a module standing on that base", async () => {
await registerModule(PROVIDER.module, resolve(catalogDir, PROVIDER.module, "module.json"));
const built = await mesh(
`build ${forgeUrl(PROVIDER.repo)} --path ${PROVIDER.path} --ref ${refFor(PROVIDER.repo)} --wait 1200s`,
1_500_000);
assert.doesNotMatch(built, /failed/i, built);
await mesh(`assign ${CONTROL} ${PROVIDER.module}`);
await mesh(`push ${CONTROL}`, 600_000);
for (let i = 0; i < 60; i++) {