diff --git a/Dockerfile b/Dockerfile index 64be4d4f..92b061a5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,7 @@ ARG NEXT_PUBLIC_WS_URL=__DEFT_WS_URL__ ARG NEXT_PUBLIC_FEATURE_HUDDLES=false ARG NEXT_PUBLIC_FEATURE_APPS=false ARG NEXT_PUBLIC_DEFT_SELF_HOSTED=false -ARG DEFT_RELEASE_VERSION=0.3.0-preview.14 +ARG DEFT_RELEASE_VERSION= ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL ENV NEXT_PUBLIC_WS_URL=$NEXT_PUBLIC_WS_URL @@ -52,7 +52,7 @@ RUN pnpm --filter @deft/app-kit build && pnpm --filter @deft/web build # Stage 3: Production FROM node:22-alpine AS runner -ARG DEFT_RELEASE_VERSION=0.3.0-preview.14 +ARG DEFT_RELEASE_VERSION= ARG VCS_REF=unknown ARG SOURCE_URL=https://github.com/Maneek21/Deft LABEL org.opencontainers.image.licenses="AGPL-3.0-only" \ diff --git a/scripts/release-workflow.test.mjs b/scripts/release-workflow.test.mjs index d688a30f..5bf95319 100644 --- a/scripts/release-workflow.test.mjs +++ b/scripts/release-workflow.test.mjs @@ -10,6 +10,7 @@ import { fileURLToPath } from 'node:url'; const workflow = readFileSync(new URL('../.github/workflows/release.yml', import.meta.url), 'utf8'); const ciWorkflow = readFileSync(new URL('../.github/workflows/ci.yml', import.meta.url), 'utf8'); const compose = readFileSync(new URL('../docker-compose.yml', import.meta.url), 'utf8'); +const dockerfile = readFileSync(new URL('../Dockerfile', import.meta.url), 'utf8'); const generatorUrl = new URL('./generate-release-manifest.mjs', import.meta.url); const generator = readFileSync(generatorUrl, 'utf8'); const scopeResolverUrl = new URL('./resolve-release-scope.mjs', import.meta.url); @@ -58,6 +59,16 @@ function createPinnedHermesFixture(root) { writeFileSync(join(root, 'package.json'), `${JSON.stringify({ version: manifest.deft_release }, null, 2)}\n`); } +test('source builds report the checked-out release, not a stale Dockerfile default', () => { + // The release workflow passes DEFT_RELEASE_VERSION explicitly. Any default here + // would override the in-code fallback in apps/api/src/lib/agent-channel.ts, which + // release prep keeps in step with package.json. + const defaults = [...dockerfile.matchAll(/^ARG DEFT_RELEASE_VERSION=(.*)$/gm)].map((match) => match[1]); + assert.ok(defaults.length > 0, 'Dockerfile must declare DEFT_RELEASE_VERSION'); + assert.deepEqual(defaults.filter(Boolean), [], 'Dockerfile must not pin a DEFT_RELEASE_VERSION default'); + assert.match(workflow, /DEFT_RELEASE_VERSION=\$\{\{ steps\.release\.outputs\.version \}\}/); +}); + test('release publication signs and verifies the exact image digest before creating a release', () => { assert.match(workflow, /id-token:\s*write/); assert.match(workflow, /attestations:\s*write/);