Files
pikasTech-unidesk/scripts/native/cicd/publish-unidesk-host-gitops.test.ts
T
2026-07-13 23:46:01 +02:00

116 lines
4.8 KiB
TypeScript

import { afterEach, describe, expect, test } from "bun:test";
import { spawnSync } from "node:child_process";
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { rootPath } from "../../src/config";
const temporaryRoots: string[] = [];
afterEach(() => {
for (const root of temporaryRoots.splice(0)) rmSync(root, { recursive: true, force: true });
});
describe("UniDesk Host GitOps publisher", () => {
test("skip preserves the GitOps branch and every managed resource", () => {
const root = mkdtempSync(join(tmpdir(), "unidesk-host-gitops-skip-"));
temporaryRoots.push(root);
const seed = join(root, "seed");
const bare = join(root, "gitops.git");
const releaseDir = join(root, "release");
const publisherWorktree = join(root, "publisher");
const configPath = join(root, "config.yaml");
const statePath = "deploy/gitops-state/unidesk-host/todo-note.json";
const resourcePath = "deploy/gitops/unidesk-host/hwlab-runtime-gitops-scripts.yaml";
const runtimeSourceCommit = "a".repeat(40);
const sourceCommit = "b".repeat(40);
const digest = `sha256:${"c".repeat(64)}`;
mkdirSync(seed);
git(["init", "-b", "unidesk-host-gitops"], seed);
identity(seed);
write(seed, "deploy/gitops/unidesk-host/todo-note.yaml", "existing service manifest\n");
write(seed, resourcePath, "stale configmap must remain unchanged\n");
write(seed, statePath, `${JSON.stringify({
version: 1,
kind: "UniDeskHostReleaseState",
serviceRef: "services.todoNote",
sourceCommit: runtimeSourceCommit,
digest,
digestRef: `registry.example/todo-note@${digest}`,
}, null, 2)}\n`);
git(["add", "."], seed);
git(["commit", "-m", "seed gitops"], seed);
const originalHead = git(["rev-parse", "HEAD"], seed).stdout.trim();
git(["init", "--bare", bare], root);
git(["remote", "add", "origin", `file://${bare}`], seed);
git(["push", "origin", "unidesk-host-gitops"], seed);
mkdirSync(releaseDir);
writeFileSync(join(releaseDir, "action"), "skip\n");
writeFileSync(join(releaseDir, "reason"), "runtime-inputs-unchanged\n");
writeFileSync(join(releaseDir, "baseline-source-commit"), `${runtimeSourceCommit}\n`);
writeFileSync(configPath, Bun.YAML.stringify({
delivery: {
enabled: true,
serviceRef: "services.todoNote",
image: { repository: "registry.example/todo-note" },
gitops: {
readUrl: `file://${bare}`,
writeUrl: `file://${bare}`,
branch: "unidesk-host-gitops",
manifestPath: "deploy/gitops/unidesk-host/todo-note.yaml",
releaseStatePath: statePath,
resources: [{
id: "hwlab-runtime-gitops-scripts",
renderer: "hwlab-runtime-gitops-scripts",
configRef: "config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01",
manifestPath: resourcePath,
namespace: "hwlab-ci",
}],
author: { name: "UniDesk Test", email: "unidesk-test@example.invalid" },
},
},
}));
const result = spawnSync("bun", [
"scripts/native/cicd/publish-unidesk-host-gitops.mjs",
"--config", configPath,
"--source-root", rootPath(),
"--metadata", join(root, "unused-metadata.json"),
"--release-dir", releaseDir,
"--source-commit", sourceCommit,
"--worktree", publisherWorktree,
], { cwd: rootPath(), encoding: "utf8", timeout: 30_000 });
expect(result.status, result.stderr).toBe(0);
const output = JSON.parse(result.stdout) as Record<string, any>;
expect(output).toMatchObject({ action: "skip", status: "skipped", changed: false, pushAttempts: 0, resources: [] });
expect(output.gitopsCommit).toBe(originalHead);
expect(git(["rev-parse", "refs/heads/unidesk-host-gitops"], bare).stdout.trim()).toBe(originalHead);
expect(show(bare, resourcePath)).toBe("stale configmap must remain unchanged\n");
expect(JSON.parse(show(bare, statePath)).sourceCommit).toBe(runtimeSourceCommit);
});
});
function write(root: string, relativePath: string, content: string) {
const path = join(root, relativePath);
mkdirSync(dirname(path), { recursive: true });
writeFileSync(path, content);
}
function identity(root: string) {
git(["config", "user.name", "UniDesk Test"], root);
git(["config", "user.email", "unidesk-test@example.invalid"], root);
}
function show(bare: string, relativePath: string): string {
return git(["show", `refs/heads/unidesk-host-gitops:${relativePath}`], bare).stdout;
}
function git(args: string[], cwd: string) {
const result = spawnSync("git", args, { cwd, encoding: "utf8" });
if (result.status !== 0) throw new Error(`git ${args.join(" ")} failed: ${result.stderr || result.stdout}`);
return result;
}