feat: add v02 device-pod env reuse boot path
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
test("G14 CI planner maps bridge changes to cloud-api only", async () => {
|
||||
const repo = await createFixtureRepo();
|
||||
const repo = await createFixtureRepo({ includeDevicePod: true });
|
||||
await writeFile(path.join(repo, "cmd/hwlab-deepseek-responses-bridge/main.ts"), "console.log('bridge v2');\n");
|
||||
await git(repo, ["add", "."]);
|
||||
await git(repo, ["commit", "-m", "change bridge"]);
|
||||
@@ -88,18 +88,62 @@ test("global change classifier distinguishes gitops-only and test-only", () => {
|
||||
assert.equal(classifyGlobalChange(["cmd/hwlab-cloud-api/runtime-options.test.ts"]).testOnly, true);
|
||||
});
|
||||
|
||||
test("v02 planner marks device-pod code-only change as env reuse rollout", async () => {
|
||||
const repo = await createFixtureRepo({ includeDevicePod: true });
|
||||
const initialPlan = await createG14CiPlan({
|
||||
repoRoot: repo,
|
||||
lane: "v02",
|
||||
baseRef: "HEAD",
|
||||
targetRef: "HEAD",
|
||||
artifactCatalogPath: "deploy/artifact-catalog.v02.json",
|
||||
services: ["hwlab-device-pod"]
|
||||
});
|
||||
const initialDevicePod = initialPlan.services.find((service) => service.serviceId === "hwlab-device-pod");
|
||||
await writeFile(path.join(repo, "deploy/artifact-catalog.v02.json"), JSON.stringify(createCatalogFixture("ready", {
|
||||
devicePodEnvironmentInputHash: initialDevicePod.environmentInputHash,
|
||||
devicePodCodeInputHash: initialDevicePod.codeInputHash,
|
||||
devicePodBootCommit: initialPlan.sourceCommitId
|
||||
}), null, 2));
|
||||
await git(repo, ["add", "deploy/artifact-catalog.v02.json"]);
|
||||
await git(repo, ["commit", "-m", "seed v02 catalog"]);
|
||||
|
||||
await writeFile(path.join(repo, "internal/device-pod/executor.ts"), "export const version = 2;\n");
|
||||
await git(repo, ["add", "."]);
|
||||
await git(repo, ["commit", "-m", "change device pod code"]);
|
||||
|
||||
const plan = await createG14CiPlan({
|
||||
repoRoot: repo,
|
||||
lane: "v02",
|
||||
baseRef: "HEAD~1",
|
||||
targetRef: "HEAD",
|
||||
artifactCatalogPath: "deploy/artifact-catalog.v02.json",
|
||||
services: ["hwlab-device-pod"]
|
||||
});
|
||||
const devicePod = plan.services.find((service) => service.serviceId === "hwlab-device-pod");
|
||||
assert.equal(devicePod.runtimeMode, "env-reuse-git-mirror-checkout");
|
||||
assert.equal(devicePod.envChanged, false);
|
||||
assert.equal(devicePod.codeChanged, true);
|
||||
assert.equal(devicePod.bootSh, "deploy/runtime/boot/hwlab-device-pod.sh");
|
||||
assert.deepEqual(plan.affectedServices, ["hwlab-device-pod"]);
|
||||
});
|
||||
|
||||
async function createFixtureRepo(options = {}) {
|
||||
const deployServices = options.deployServices !== false;
|
||||
const k3sServiceMappings = options.k3sServiceMappings === true;
|
||||
const includeDevicePod = options.includeDevicePod === true;
|
||||
const repo = await mkdtemp(path.join(os.tmpdir(), "hwlab-g14-ci-plan-"));
|
||||
await mkdir(path.join(repo, "cmd/hwlab-cloud-api"), { recursive: true });
|
||||
await mkdir(path.join(repo, "cmd/hwlab-deepseek-responses-bridge"), { recursive: true });
|
||||
await mkdir(path.join(repo, "web/hwlab-cloud-web"), { recursive: true });
|
||||
await mkdir(path.join(repo, "internal/device-pod"), { recursive: true });
|
||||
await mkdir(path.join(repo, "deploy/runtime/boot"), { recursive: true });
|
||||
await mkdir(path.join(repo, "deploy/runtime/launcher"), { recursive: true });
|
||||
await mkdir(path.join(repo, "deploy"), { recursive: true });
|
||||
await writeFile(path.join(repo, "deploy/deploy.json"), JSON.stringify(createDeployFixture({ deployServices, k3sServiceMappings }), null, 2));
|
||||
await writeFile(path.join(repo, "deploy/deploy.json"), JSON.stringify(createDeployFixture({ deployServices, k3sServiceMappings, includeDevicePod }), null, 2));
|
||||
const catalogMode = options.catalog ?? "ready";
|
||||
if (catalogMode !== false) {
|
||||
await writeFile(path.join(repo, "deploy/artifact-catalog.dev.json"), JSON.stringify(createCatalogFixture(catalogMode), null, 2));
|
||||
await writeFile(path.join(repo, "deploy/artifact-catalog.v02.json"), JSON.stringify(createCatalogFixture(catalogMode), null, 2));
|
||||
}
|
||||
await writeFile(path.join(repo, "package.json"), JSON.stringify({ type: "module" }, null, 2));
|
||||
await writeFile(path.join(repo, "package-lock.json"), JSON.stringify({ lockfileVersion: 3 }, null, 2));
|
||||
@@ -107,40 +151,64 @@ async function createFixtureRepo(options = {}) {
|
||||
await writeFile(path.join(repo, "cmd/hwlab-deepseek-responses-bridge/main.ts"), "console.log('bridge');\n");
|
||||
await writeFile(path.join(repo, "cmd/hwlab-deepseek-responses-bridge/main.test.ts"), "console.log('test');\n");
|
||||
await writeFile(path.join(repo, "web/hwlab-cloud-web/index.html"), "<html></html>\n");
|
||||
await writeFile(path.join(repo, "internal/device-pod/executor.ts"), "export const version = 1;\n");
|
||||
await writeFile(path.join(repo, "deploy/runtime/boot/hwlab-device-pod.sh"), "#!/bin/sh\nexec bun cmd/hwlab-device-pod/main.ts\n");
|
||||
await writeFile(path.join(repo, "deploy/runtime/launcher/hwlab-env-reuse-launcher.ts"), "console.log('launcher');\n");
|
||||
await git(repo, ["init"]);
|
||||
await git(repo, ["add", "."]);
|
||||
await git(repo, ["commit", "-m", "initial"]);
|
||||
return repo;
|
||||
}
|
||||
|
||||
function createDeployFixture({ deployServices, k3sServiceMappings }) {
|
||||
const deploy = {};
|
||||
function createDeployFixture({ deployServices, k3sServiceMappings, includeDevicePod }) {
|
||||
const deploy = {
|
||||
lanes: {
|
||||
v02: {
|
||||
sourceRepo: "git@github.com:pikasTech/HWLAB.git",
|
||||
envReuseServices: ["hwlab-device-pod"],
|
||||
bootScripts: { "hwlab-device-pod": "deploy/runtime/boot/hwlab-device-pod.sh" }
|
||||
}
|
||||
}
|
||||
};
|
||||
if (deployServices) {
|
||||
deploy.services = [
|
||||
{ serviceId: "hwlab-cloud-api" },
|
||||
{ serviceId: "hwlab-cloud-web" }
|
||||
{ serviceId: "hwlab-cloud-web" },
|
||||
...(includeDevicePod ? [{ serviceId: "hwlab-device-pod" }] : [])
|
||||
];
|
||||
}
|
||||
if (k3sServiceMappings) {
|
||||
deploy.k3s = {
|
||||
serviceMappings: [
|
||||
{ serviceId: "hwlab-cloud-api", name: "hwlab-cloud-api" },
|
||||
{ serviceId: "hwlab-cloud-web", name: "hwlab-cloud-web" }
|
||||
{ serviceId: "hwlab-cloud-web", name: "hwlab-cloud-web" },
|
||||
...(includeDevicePod ? [{ serviceId: "hwlab-device-pod", name: "hwlab-device-pod" }] : [])
|
||||
]
|
||||
};
|
||||
}
|
||||
return deploy;
|
||||
}
|
||||
|
||||
function createCatalogFixture(mode) {
|
||||
function createCatalogFixture(mode, options = {}) {
|
||||
const digest = mode === "ready" ? `sha256:${"1".repeat(64)}` : "not_published";
|
||||
return {
|
||||
services: ["hwlab-cloud-api", "hwlab-cloud-web"].map((serviceId) => ({
|
||||
services: ["hwlab-cloud-api", "hwlab-cloud-web", "hwlab-device-pod"].map((serviceId) => ({
|
||||
serviceId,
|
||||
commitId: "abc1234",
|
||||
image: `127.0.0.1:5000/hwlab/${serviceId}:abc1234`,
|
||||
imageTag: "abc1234",
|
||||
digest
|
||||
digest,
|
||||
...(serviceId === "hwlab-device-pod" ? {
|
||||
runtimeMode: "env-reuse-git-mirror-checkout",
|
||||
envReuse: true,
|
||||
environmentImage: "127.0.0.1:5000/hwlab/hwlab-device-pod-env:env-abc1234",
|
||||
environmentDigest: digest,
|
||||
environmentInputHash: options.devicePodEnvironmentInputHash ?? "e".repeat(64),
|
||||
codeInputHash: options.devicePodCodeInputHash ?? "c".repeat(64),
|
||||
bootRepo: "git@github.com:pikasTech/HWLAB.git",
|
||||
bootCommit: options.devicePodBootCommit ?? "abc1234",
|
||||
bootSh: "deploy/runtime/boot/hwlab-device-pod.sh"
|
||||
} : {})
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user