feat: release 2.5.1

This commit is contained in:
2026-09-27 10:40:50 +00:00 Unverified
parent 46d97138dc
commit 5f7509a9c5
53 changed files with 2871 additions and 370 deletions
+86 -3
View File
@@ -45,9 +45,6 @@ describe("up API pipeline", () => {
join(root, ".kuberrc.ts"),
'export default { project: "shop" };\n',
);
const git = Bun.spawn(["git", "init", "-q", root]);
expect(await git.exited).toBe(0);
process.chdir(root);
process.env.XDG_CONFIG_HOME = configHome;
const identity = await resolveTrustIdentity("shop", root);
@@ -106,6 +103,92 @@ describe("up API pipeline", () => {
}
});
test("adopts before overlapping database and storage reconciliation, then renders merged env", async () => {
const root = await mkdtemp(join(tmpdir(), "kuber-up-api-"));
const previousCwd = process.cwd();
const order: string[] = [];
const started: string[] = [];
let bothReady!: () => void;
const bothStarted = new Promise<void>((resolve) => {
bothReady = resolve;
});
let releaseDatabase!: () => void;
let releaseStorage!: () => void;
const database = new Promise<void>((resolve) => {
releaseDatabase = resolve;
});
const storage = new Promise<void>((resolve) => {
releaseStorage = resolve;
});
try {
await writeFile(
join(root, "compose.yml"),
"services:\n app:\n image: nginx\n volumes:\n - postgresql:app\n - s3:assets\n",
);
await writeFile(
join(root, ".kuberrc.ts"),
'export default { project: "shop" };\n',
);
expect(await Bun.spawn(["git", "init", "-q", root]).exited).toBe(0);
process.chdir(root);
const trust = await resolveTrustIdentity("shop", root);
const request: ApiRequester = async <T>(path: string) => {
order.push(path);
if (path === "/workspaces/shop") throw new KuberApiError("missing", 404);
if (path === "/workspaces")
return {
metadata: { name: "shop", uid: "workspace", resourceVersion: "1" },
} as T;
if (path.endsWith("/adopt")) return { resourcesAdopted: 0 } as T;
if (path.endsWith("/databases")) {
started.push("database");
if (started.length === 2) bothReady();
await database;
return { app: { DATABASE_URL: "postgresql://app", SHARED: "database" } } as T;
}
if (path.endsWith("/storage")) {
started.push("storage");
if (started.length === 2) bothReady();
await storage;
return { app: { AWS_ACCESS_KEY_ID: "key", SHARED: "storage" } } as T;
}
if (path.endsWith("/plan")) return { desired: [], stale: [] } as T;
return {} as T;
};
const run = provideContext(() => runUp(false, request, { trust }));
try {
await bothStarted;
expect(started).toEqual(["database", "storage"]);
expect(order.indexOf("/workspaces/shop/adopt")).toBeLessThan(
order.indexOf("/workspaces/shop/databases"),
);
expect(order).not.toContain("/workspaces/shop/resources/plan");
releaseStorage();
await Promise.resolve();
expect(order).not.toContain("/workspaces/shop/resources/plan");
releaseDatabase();
const result = await run;
expect(result.serviceEnv).toEqual({
app: {
DATABASE_URL: "postgresql://app",
SHARED: "storage",
AWS_ACCESS_KEY_ID: "key",
},
});
expect(order.indexOf("/workspaces/shop/resources/plan")).toBeGreaterThan(
order.indexOf("/workspaces/shop/storage"),
);
} finally {
releaseStorage();
releaseDatabase();
await run.catch(() => {});
}
} finally {
process.chdir(previousCwd);
await rm(root, { recursive: true, force: true });
}
});
test("creates workspace metadata without embedding source blobs", async () => {
const calls: Array<{ path: string; init?: ApiRequestInit }> = [];
const request: ApiRequester = async <T>(