import { expect, test } from "bun:test"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { readGiteaWebhookGitOpsDelivery, renderGiteaWebhookSyncDesiredManifest } from "./platform-infra-gitea"; import { renderPlatformInfraGiteaApplication } from "../native/cicd/publish-platform-infra-gitea-gitops.mjs"; const root = resolve(import.meta.dir, "../.."); test("existing NC01 Repository can bootstrap the independent desired publisher without new RBAC", () => { const pipeline = Bun.YAML.parse(readFileSync(resolve(root, ".tekton/platform-infra-gitea-nc01-pac.yaml"), "utf8")) as any; expect(pipeline.metadata.annotations).toMatchObject({ "pipelinesascode.tekton.dev/on-event": "[push]", "pipelinesascode.tekton.dev/on-target-branch": "[master]", }); expect(pipeline.metadata.annotations["pipelinesascode.tekton.dev/on-cel-expression"]).toContain("node == 'NC01'"); expect(pipeline.spec.taskRunTemplate.serviceAccountName).toBe("default"); const script = pipeline.spec.pipelineSpec.tasks[0].taskSpec.steps[0].script as string; expect(script).toContain("$SOURCE_SNAPSHOT_PREFIX/$SOURCE_COMMIT"); expect(script).toContain("publish-platform-infra-gitea-gitops.mjs"); expect(script).not.toContain("build-unidesk-host-image"); expect(script).not.toContain("todo-note"); const pac = Bun.YAML.parse(readFileSync(resolve(root, "config/platform-infra/pipelines-as-code.yaml"), "utf8")) as any; const consumer = pac.consumers.find((item: any) => item.id === "platform-infra-gitea-nc01"); expect(consumer).toMatchObject({ repositoryRef: "sentinel-nc01-v03", node: "NC01", namespace: "devops-infra", pipeline: "platform-infra-gitea-nc01-pac", closeoutGitOpsMirrorFlush: false, }); expect(consumer.argoBootstrap).toBeUndefined(); }); test("owning YAML renders one child Application and the complete durable bridge desired state", () => { const delivery = readGiteaWebhookGitOpsDelivery(); expect(delivery.enabled).toBe(true); expect(delivery.bootstrapApplicationPath).toStartWith("deploy/gitops/unidesk-host/"); expect(delivery.desiredManifestPath).toStartWith("deploy/gitops/platform-infra/gitea-nc01/"); const application = renderPlatformInfraGiteaApplication(delivery); expect(application).toContain("kind: Application"); expect(application).toContain("name: platform-infra-gitea-nc01"); expect(application).toContain("path: deploy/gitops/platform-infra/gitea-nc01"); expect(application).toContain("prune: true"); expect(application).toContain("selfHeal: true"); const manifest = renderGiteaWebhookSyncDesiredManifest("NC01"); expect(manifest).toContain("kind: ServiceAccount"); expect(manifest).toContain("kind: PersistentVolumeClaim"); expect(manifest).toContain("strategy:\n type: Recreate"); expect(manifest).toContain("serviceAccountName: gitea-github-sync"); expect(manifest).toContain("name: UNIDESK_GITEA_WEBHOOK_RESPONSE_BUDGET_MS\n value: \"6500\""); expect(manifest).toContain("name: UNIDESK_GITEA_WEBHOOK_WORKER_ATTEMPT_TIMEOUT_MS\n value: \"120000\""); const candidateConfig = manifest.indexOf("name: gitea-github-sync-candidate\n namespace: devops-infra\n annotations:"); const candidateJob = manifest.indexOf("kind: Job\nmetadata:\n name: gitea-github-sync-candidate"); const deployment = manifest.indexOf("kind: Deployment\nmetadata:\n name: gitea-github-sync"); expect(candidateConfig).toBeGreaterThanOrEqual(0); expect(candidateJob).toBeGreaterThan(candidateConfig); expect(deployment).toBeGreaterThan(candidateJob); expect(manifest).toContain("argocd.argoproj.io/hook: PreSync"); expect(manifest).toContain('argocd.argoproj.io/sync-wave: "-2"'); expect(manifest).toContain('argocd.argoproj.io/sync-wave: "-1"'); expect(manifest).toContain("node /etc/gitea-github-sync-candidate/entrypoint.mjs &"); expect(manifest).toContain('import { startServer } from "./server.mjs";'); expect(manifest).toContain("- /etc/gitea-github-sync/entrypoint.mjs"); expect(manifest).toContain("mountPath: /etc/gitea-github-sync-candidate"); expect(manifest).toContain("name: candidate-inbox\n emptyDir: {}"); expect(manifest).toContain('gate: "gitea-github-sync-candidate-startup"'); const documents = manifest.split(/^---\s*$/mu).map((item) => item.trim()).filter(Boolean).map((item) => Bun.YAML.parse(item) as any); expect(documents.map((item) => item.kind)).toEqual(["ConfigMap", "Job", "ServiceAccount", "ConfigMap", "PersistentVolumeClaim", "Service", "Deployment"]); });