test: align gitops render dependency contracts
This commit is contained in:
@@ -37,13 +37,28 @@ test("NC01 PaC artifact keeps the runtime GitOps file contract", async () => {
|
||||
|
||||
const promoteStep = gitopsPromote.taskSpec.steps.find((step) => step.name === "promote");
|
||||
assert.ok(promoteStep, "missing gitops-promote promote step");
|
||||
assert.equal(promoteStep.image, "127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1");
|
||||
assert.deepEqual(promoteStep.volumeMounts, [{
|
||||
name: "unidesk-runtime-gitops-scripts",
|
||||
mountPath: "/etc/unidesk-cicd-runtime-gitops",
|
||||
readOnly: true
|
||||
}]);
|
||||
assert.match(promoteStep.script, /UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=\/etc\/unidesk-cicd-runtime-gitops\/runtime-gitops-overlay\.json node \/etc\/unidesk-cicd-runtime-gitops\/runtime-gitops-postprocess\.mjs/u);
|
||||
assert.match(promoteStep.script, /UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=\/etc\/unidesk-cicd-runtime-gitops\/runtime-gitops-overlay\.json node \/etc\/unidesk-cicd-runtime-gitops\/runtime-gitops-verify\.mjs/u);
|
||||
const yamlDependencyBootstrap = [
|
||||
'ci_node_deps="${HWLAB_CI_NODE_DEPS:-/opt/hwlab-ci-node-deps/node_modules}"',
|
||||
'if [ -d "$ci_node_deps" ]; then',
|
||||
' if [ -d /workspace/source/repo ]; then ci_node_deps_target=/workspace/source/repo/node_modules; else ci_node_deps_target=./node_modules; fi',
|
||||
' mkdir -p "$ci_node_deps_target"',
|
||||
' for ci_node_dep in yaml; do if [ -d "$ci_node_deps/$ci_node_dep" ] && [ ! -e "$ci_node_deps_target/$ci_node_dep" ]; then ln -s "$ci_node_deps/$ci_node_dep" "$ci_node_deps_target/$ci_node_dep"; fi; done',
|
||||
"fi"
|
||||
].join("\n");
|
||||
const postprocessCommand = "UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json node /etc/unidesk-cicd-runtime-gitops/runtime-gitops-postprocess.mjs";
|
||||
const verifyCommand = "UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE=/etc/unidesk-cicd-runtime-gitops/runtime-gitops-overlay.json node /etc/unidesk-cicd-runtime-gitops/runtime-gitops-verify.mjs";
|
||||
const yamlDependencyBootstrapIndex = promoteStep.script.indexOf(yamlDependencyBootstrap);
|
||||
const postprocessIndex = promoteStep.script.indexOf(postprocessCommand);
|
||||
const verifyIndex = promoteStep.script.indexOf(verifyCommand);
|
||||
assert.notEqual(yamlDependencyBootstrapIndex, -1, "missing CI node yaml dependency bootstrap");
|
||||
assert.ok(postprocessIndex > yamlDependencyBootstrapIndex, "runtime GitOps postprocess must run after yaml is linked into the source workspace");
|
||||
assert.ok(verifyIndex > postprocessIndex, "runtime GitOps verify must run after postprocess with the same yaml dependency bootstrap");
|
||||
assert.doesNotMatch(promoteStep.script, /UNIDESK_RUNTIME_GITOPS_OVERLAY_B64/u);
|
||||
});
|
||||
|
||||
@@ -235,10 +250,10 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
||||
assert.match(prepareSourceScript, /git_timed source-clone 180 git clone --branch "\$\(params\.source-branch\)" "\$git_read_url"/u);
|
||||
assert.match(prepareSourceScript, /git_timed catalog-ls-remote 45 git ls-remote --exit-code --heads "\$git_read_url"/u);
|
||||
assert.match(prepareSourceScript, /git remote set-url gitops-catalog "\$git_read_url"/u);
|
||||
assert.match(prepareSourceScript, /prepare-source-dependencies/u);
|
||||
assert.match(prepareSourceScript, /require\.resolve\("yaml"\)/u);
|
||||
assert.match(prepareSourceScript, /npm ci --ignore-scripts --no-audit --prefer-offline/u);
|
||||
assert.match(prepareSourceScript, /bun install --frozen-lockfile --ignore-scripts/u);
|
||||
assert.match(prepareSourceScript, /"event":"prepare-source-dependencies","status":"skipped","reason":"renderer-dependency-install-disabled","dependency":"yaml"/u);
|
||||
assert.doesNotMatch(prepareSourceScript, /require\.resolve\("yaml"\)/u);
|
||||
assert.doesNotMatch(prepareSourceScript, /npm ci --ignore-scripts --no-audit --prefer-offline/u);
|
||||
assert.doesNotMatch(prepareSourceScript, /bun install --frozen-lockfile --ignore-scripts/u);
|
||||
assert.doesNotMatch(prepareSourceScript, /ci-tools-image-provides-required-node-runtime/u);
|
||||
assert.doesNotMatch(prepareSourceScript, /prepare-source-pre-npm/u);
|
||||
assert.doesNotMatch(prepareSourceScript, /prepare-source-proxy-preflight/u);
|
||||
@@ -249,12 +264,12 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
||||
assert.doesNotMatch(collectArtifacts.taskSpec.steps[0].script, /collect-artifacts-proxy-preflight/u);
|
||||
|
||||
const pipelineGitReadParam = pipelineJson.spec.params.find((param) => param.name === "git-read-url");
|
||||
assert.equal(pipelineGitReadParam?.default, "http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git");
|
||||
assert.equal(pipelineGitReadParam?.default, "http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git");
|
||||
const pipelineGitWriteParam = pipelineJson.spec.params.find((param) => param.name === "git-write-url");
|
||||
assert.equal(pipelineGitWriteParam?.default, "http://git-mirror-write.devops-infra.svc.cluster.local/pikasTech/HWLAB.git");
|
||||
|
||||
const sourceDescriptor = JSON.parse(await readFile(path.join(outDir, "source.json"), "utf8"));
|
||||
assert.equal(sourceDescriptor.gitReadUrl, "http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git");
|
||||
assert.equal(sourceDescriptor.gitReadUrl, "http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git");
|
||||
assert.equal(sourceDescriptor.gitWriteUrl, "http://git-mirror-write.devops-infra.svc.cluster.local/pikasTech/HWLAB.git");
|
||||
|
||||
const gitMirror = await readFile(path.join(outDir, "devops-infra", "git-mirror.yaml"), "utf8");
|
||||
@@ -341,7 +356,7 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
||||
const serviceId = retainedServiceIds[index];
|
||||
const task = taskByName(pipelineJson, `build-${serviceId}`);
|
||||
assert.deepEqual(task.runAfter, ["plan-artifacts"]);
|
||||
assert.deepEqual(task.when, [{ input: `$(tasks.plan-artifacts.results.affected-${serviceId})`, operator: "in", values: ["true"] }]);
|
||||
assert.deepEqual(task.when, [{ input: `$(tasks.plan-artifacts.results.build-${serviceId})`, operator: "in", values: ["true"] }]);
|
||||
}
|
||||
|
||||
const collectScript = collectArtifacts.taskSpec.steps[0].script;
|
||||
@@ -451,14 +466,14 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
||||
assert.equal(codexForwarderEnv.get("HWLAB_RUNTIME_MODE"), "env-reuse-git-mirror-checkout");
|
||||
assert.equal(codexForwarderEnv.get("HWLAB_BOOT_SH"), "deploy/runtime/boot/hwlab-codex-api-responses-forwarder.sh");
|
||||
assert.equal(codexForwarderEnv.get("HWLAB_BOOT_COMMIT"), cloudApiCommit);
|
||||
assert.equal(codexForwarderEnv.get("HWLAB_BOOT_READ_URL"), "http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git");
|
||||
assert.equal(codexForwarderEnv.get("HWLAB_BOOT_READ_URL"), "http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git");
|
||||
assert.ok(cloudApiEnv.some((entry) => entry.name === "HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT" && entry.value === cloudApiCommit));
|
||||
assert.ok(cloudApiEnv.some((entry) => entry.name === "HWLAB_CODE_AGENT_ADAPTER" && entry.value === "agentrun-v01"));
|
||||
assert.equal(cloudApi.spec.template.spec.initContainers?.some((entry) => entry.name === "hwlab-code-agent-workspace-init"), false);
|
||||
assert.equal(cloudApi.spec.template.spec.volumes?.some((entry) => /code-agent-codex|code-agent-workspace/u.test(entry.name)), false);
|
||||
assert.equal(cloudApiContainer.volumeMounts?.some((entry) => /code-agent-codex|code-agent-workspace/u.test(entry.name)), false);
|
||||
assert.equal(cloudApiEnv.some((entry) => entry.name === "HWLAB_CODE_AGENT_PROVIDER" && entry.value === "codex-stdio"), false);
|
||||
assert.equal(cloudApiEnv.some((entry) => entry.name === "HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR"), false);
|
||||
assert.ok(cloudApiEnv.some((entry) => entry.name === "HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR" && entry.value === "repo-owned"));
|
||||
assert.ok(cloudApiEnv.some((entry) => entry.name === "UNIDESK_MAIN_SERVER_IP" && entry.value === "http://74.48.78.17:18081"));
|
||||
assert.ok(cloudApiEnv.some((entry) => entry.name === "HWLAB_KEYCLOAK_ISSUER" && entry.value === "https://auth.74-48-78-17.nip.io/realms/hwlab"));
|
||||
assert.ok(cloudApiEnv.some((entry) => entry.name === "HWLAB_KEYCLOAK_CLIENT_ID" && entry.value === "hwlab-cloud-web"));
|
||||
@@ -473,7 +488,7 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
||||
assert.equal(deepseekBridgeEnv.get("HWLAB_RUNTIME_MODE"), "env-reuse-git-mirror-checkout");
|
||||
assert.equal(deepseekBridgeEnv.get("HWLAB_BOOT_SH"), "deploy/runtime/boot/hwlab-deepseek-responses-bridge.sh");
|
||||
assert.equal(deepseekBridgeEnv.get("HWLAB_BOOT_COMMIT"), cloudApiCommit);
|
||||
assert.equal(deepseekBridgeEnv.get("HWLAB_BOOT_READ_URL"), "http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git");
|
||||
assert.equal(deepseekBridgeEnv.get("HWLAB_BOOT_READ_URL"), "http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git");
|
||||
assert.equal(workloadsJson.items.some((item) => item.metadata?.labels?.["hwlab.pikastech.local/service-id"] === "hwlab-agent-worker"), false);
|
||||
const kustomization = await readFile(path.join(outDir, "runtime-v02", "kustomization.yaml"), "utf8");
|
||||
assert.doesNotMatch(kustomization, /code-agent-codex-config/u);
|
||||
@@ -493,7 +508,7 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
||||
|
||||
const application = await readFile(path.join(outDir, "argocd", "application-v02.yaml"), "utf8");
|
||||
assert.match(application, /"prune": true/u);
|
||||
assert.match(application, /git-mirror-http\.devops-infra\.svc\.cluster\.local/u);
|
||||
assert.match(application, /gitea-http\.devops-infra\.svc\.cluster\.local:3000\/mirrors\/pikasTech-HWLAB\.git/u);
|
||||
assert.doesNotMatch(application, /git@github\.com:pikasTech\/HWLAB\.git/u);
|
||||
|
||||
for (const generatedFile of ["deepseek-proxy.yaml", "postgres.yaml", "openfga.yaml", "node-frpc.yaml"]) {
|
||||
@@ -558,7 +573,7 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
|
||||
await assert.rejects(() => readFile(path.join(outDir, "tekton-v02", "poller.yaml"), "utf8"), { code: "ENOENT" });
|
||||
|
||||
const pipelineRunSample = await readFile(path.join(outDir, "tekton-v02", "pipelinerun.sample.yaml"), "utf8");
|
||||
assert.match(pipelineRunSample, /"name": "git-read-url"[\s\S]{0,140}git-mirror-http\.devops-infra\.svc\.cluster\.local/u);
|
||||
assert.match(pipelineRunSample, /"name": "git-read-url"[\s\S]{0,180}gitea-http\.devops-infra\.svc\.cluster\.local:3000\/mirrors\/pikasTech-HWLAB\.git/u);
|
||||
assert.match(pipelineRunSample, /"name": "git-write-url"[\s\S]{0,140}git-mirror-write\.devops-infra\.svc\.cluster\.local/u);
|
||||
assert.match(pipelineRunSample, /"name": "revision"[\s\S]{0,80}"value": "[0-9a-f]{40}"/u);
|
||||
assert.match(pipelineRunSample, /"name": "source-branch"[\s\S]{0,80}"value": "v0\.2"/u);
|
||||
@@ -820,10 +835,10 @@ test("v03 render includes JD01 secret-plane smoke on JD01 gitops root", { timeou
|
||||
const opencode = JSON.parse(await readFile(path.join(outDir, "runtime-v03", "opencode.yaml"), "utf8"));
|
||||
const opencodeDeployment = (opencode.items ?? []).find((item) => item.kind === "Deployment" && item.metadata?.name === "opencode-server");
|
||||
assert.ok(opencodeDeployment, "expected opencode-server deployment");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/opencode-provider-profile"], "dsflash-go");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/agentrun-provider-secret-ref"], "agentrun-v02/agentrun-v01-provider-dsflash-go");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/opencode-provider-profile"], "gpt.pika");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/agentrun-provider-secret-ref"], "agentrun-v02/agentrun-v01-provider-gpt-pika");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/opencode-provider-base-url"], "http://127.0.0.1:4097/v1");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/opencode-provider-upstream-base-url"], "https://opencode.ai/zen/go/v1");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/opencode-provider-upstream-base-url"], "https://api.pikapython.com/");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/opencode-image"], "127.0.0.1:5000/hwlab/opencode:1.17.7-git");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/opencode-provider-proxy-boot-sh"], "deploy/runtime/boot/opencode-provider-proxy.sh");
|
||||
assert.equal(opencodeDeployment.metadata?.annotations?.["hwlab.pikastech.local/values-printed"], "false");
|
||||
@@ -841,24 +856,24 @@ test("v03 render includes JD01 secret-plane smoke on JD01 gitops root", { timeou
|
||||
const opencodeEnvEntries = new Map((opencodeContainer?.env ?? []).map((entry) => [entry.name, entry]));
|
||||
assert.equal(opencodeEnvEntries.get("HTTPS_PROXY")?.value, "http://sub2api-egress-proxy.platform-infra.svc.cluster.local:10808");
|
||||
assert.match(opencodeEnvEntries.get("NO_PROXY")?.value ?? "", /\.svc\.cluster\.local/u);
|
||||
assert.deepEqual(opencodeEnvEntries.get("OPENCODE_DSFLASH_GO_API_KEY")?.valueFrom?.secretKeyRef, { name: "hwlab-v03-code-agent-provider", key: "opencode-api-key", optional: true });
|
||||
assert.deepEqual(opencodeEnvEntries.get("OPENCODE_GPT_PIKA_API_KEY")?.valueFrom?.secretKeyRef, { name: "hwlab-v03-code-agent-provider", key: "opencode-api-key", optional: true });
|
||||
const opencodeConfig = JSON.parse(opencodeEnvEntries.get("OPENCODE_CONFIG_CONTENT")?.value ?? "{}");
|
||||
assert.equal(opencodeConfig.model, "dsflash-go/deepseek-v4-flash");
|
||||
assert.equal(opencodeConfig.small_model, "dsflash-go/deepseek-v4-flash");
|
||||
assert.equal(opencodeConfig.provider["dsflash-go"].npm, "@ai-sdk/openai-compatible");
|
||||
assert.equal(opencodeConfig.provider["dsflash-go"].options.baseURL, "http://127.0.0.1:4097/v1");
|
||||
assert.equal(opencodeConfig.provider["dsflash-go"].options.apiKey, "{env:OPENCODE_DSFLASH_GO_API_KEY}");
|
||||
assert.equal(opencodeConfig.provider["dsflash-go"].models["deepseek-v4-flash"].reasoning, false);
|
||||
assert.equal(opencodeConfig.provider["dsflash-go"].models["deepseek-v4-flash"].tool_call, true);
|
||||
assert.deepEqual(opencodeConfig.provider["dsflash-go"].models["deepseek-v4-flash"].limit, { context: 1000000, output: 384000 });
|
||||
assert.equal(opencodeConfig.model, "gpt.pika/gpt-5.4-mini");
|
||||
assert.equal(opencodeConfig.small_model, "gpt.pika/gpt-5.4-mini");
|
||||
assert.equal(opencodeConfig.provider["gpt.pika"].npm, "@ai-sdk/openai-compatible");
|
||||
assert.equal(opencodeConfig.provider["gpt.pika"].options.baseURL, "http://127.0.0.1:4097/v1");
|
||||
assert.equal(opencodeConfig.provider["gpt.pika"].options.apiKey, "{env:OPENCODE_GPT_PIKA_API_KEY}");
|
||||
assert.equal(opencodeConfig.provider["gpt.pika"].models["gpt-5.4-mini"].reasoning, false);
|
||||
assert.equal(opencodeConfig.provider["gpt.pika"].models["gpt-5.4-mini"].tool_call, true);
|
||||
assert.deepEqual(opencodeConfig.provider["gpt.pika"].models["gpt-5.4-mini"].limit, { context: 1000000, output: 384000 });
|
||||
const providerProxy = collectContainersFromItem(opencodeDeployment).find((container) => container.name === "opencode-provider-proxy");
|
||||
assert.ok(providerProxy, "expected provider proxy sidecar");
|
||||
assert.equal(providerProxy.command, undefined);
|
||||
const providerProxyEnv = new Map((providerProxy.env ?? []).map((entry) => [entry.name, entry.value]));
|
||||
assert.equal(providerProxyEnv.get("HWLAB_BOOT_SH"), "deploy/runtime/boot/opencode-provider-proxy.sh");
|
||||
assert.equal(providerProxyEnv.get("HWLAB_BOOT_REF"), "v0.3");
|
||||
assert.match(providerProxyEnv.get("HWLAB_BOOT_READ_URL") ?? "", /pikasTech\/HWLAB/u);
|
||||
assert.equal(providerProxyEnv.get("HWLAB_OPENCODE_PROVIDER_PROXY_UPSTREAM_BASE_URL"), "https://opencode.ai/zen/go/v1");
|
||||
assert.match(providerProxyEnv.get("HWLAB_BOOT_READ_URL") ?? "", /pikasTech[-/]HWLAB/u);
|
||||
assert.equal(providerProxyEnv.get("HWLAB_OPENCODE_PROVIDER_PROXY_UPSTREAM_BASE_URL"), "https://api.pikapython.com/");
|
||||
assert.equal(providerProxyEnv.get("HWLAB_OPENCODE_PROVIDER_PROXY_PUBLIC_BASE_PATH"), "/v1");
|
||||
assert.equal(providerProxyEnv.get("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"), "http://otel-collector.platform-infra.svc.cluster.local:4318/v1/traces");
|
||||
assert.equal(providerProxyEnv.get("OTEL_SERVICE_NAME"), "opencode-provider-proxy");
|
||||
|
||||
Reference in New Issue
Block a user