// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // The image the three processes run from (spec §13). These are the properties a deployment // depends on, and each one has cost a deployment somewhere: a manifest the install stage does not // copy, a root process, a base image nobody pinned to the Node the app is written for. import { readdirSync, readFileSync } from "node:fs" import { describe, expect, it } from "vitest" import { parse } from "yaml" const dockerfile = readFileSync(new URL("../Dockerfile", import.meta.url), "utf8") const workspace = parse(readFileSync(new URL("../pnpm-workspace.yaml", import.meta.url), "utf8")) as { minimumReleaseAgeExclude: string[] } describe("the Dockerfile", () => { it("is multi-stage, with the runtime stage compose.yaml names", () => { expect(dockerfile).toMatch(/^FROM node:24-slim AS deps$/m) expect(dockerfile).toMatch(/^FROM deps AS build$/m) expect(dockerfile).toMatch(/^FROM node:24-slim AS runtime$/m) }) it("copies the manifest of every workspace package before installing", () => { // The install stage resolves the whole workspace, so a package whose manifest is missing // fails the install with "no package named @app/ is present in the workspace". const packages = readdirSync(new URL("..", import.meta.url), { withFileTypes: true }) expect(packages.some((entry) => entry.name === "pnpm-workspace.yaml")).toBe(true) for (const dir of ["config", "modules", "apps/web", "apps/worker"]) { expect(dockerfile, `${dir}/package.json is not copied`).toContain(`COPY ${dir}/package.json ./${dir}/`) } }) it("runs as a user that owns none of the files it runs", () => { expect(dockerfile).toMatch(/^USER node$/m) expect(dockerfile).toContain("--chown=root:root") }) it("takes the registry credential as a build secret, never as a layer or a build argument", () => { // Two build paths deliver the same credential under two ids: a preset single-image build // mounts it as `npmrc`, a compose build as `conusai_npmrc` (the platform prefixes its compose // secrets so a tenant's own can never collide). The install must accept either — a // deployment that built through the preset path got no credential at all and pnpm fell back // to the public registry, where the vendor scopes 404 (stage, deployment 4, 2026-10-20). expect(dockerfile).toContain("--mount=type=secret,id=conusai_npmrc,target=/run/secrets/conusai_npmrc") expect(dockerfile).toContain("--mount=type=secret,id=npmrc,target=/run/secrets/npmrc") expect(dockerfile).not.toMatch(/ARG .*(TOKEN|PASSWORD|SECRET)/) expect(dockerfile).not.toMatch(/_authToken/) }) it("excludes the vendor scopes from the release-age cooldown", () => { // minimumReleaseAge blocks versions published in the last seven days — but every dev // bundle publishes the vendor packages minutes before a deployment installs them, from // the ConusAI vendor registry, so the cooldown must never apply to either scope // (stage, deployment 5, 2026-10-20: ERR_PNPM_NO_MATURE_MATCHING_VERSION). expect(workspace.minimumReleaseAgeExclude).toContain("@conusai-sdk/*") expect(workspace.minimumReleaseAgeExclude).toContain("@conusai-kit/*") }) it("starts no process by default: compose.yaml names the one each service runs", () => { const cmd = dockerfile.match(/^CMD (.*)$/m)?.[1] ?? "" expect(cmd).toContain("compose.yaml") expect(cmd).not.toContain("next") }) })