From d7e4fd0938f65729e28fb7057a7ba60b0c7eb104 Mon Sep 17 00:00:00 2001 From: Don Garrett Date: Wed, 7 Oct 2026 23:09:08 +0000 Subject: [PATCH] M1.5 accepted: the tests run over a published image - The Dockerfile's test stage stacks on TEST_BASE: this build's agent by default, or a published image. It adds only the test tools (uv export of the dev group into the image's environment), never reinstalling the agent, so the suite tests the image as published. - scripts/e2e.sh --image passes NISSE_E2E_MODEL into the container. - The plan marks M1.5 done: v0.1.0's published image passed the whole e2e suite (9 of 9, 11m37s), with the release's own tests over it. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE --- Dockerfile | 21 +++++++++++++-------- docs/Development-Plan.md | 9 +++++++-- scripts/e2e.sh | 2 ++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 09df155..c0e1372 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,12 @@ # docker build -t nisse-dev . the agent # docker build --target test -t nisse-dev:test . plus the tests, for # scripts/e2e.sh --image +# docker build --target test --build-arg TEST_BASE= \ +# -t nisse-dev:test . the tests over a release as +# published (M1.5 acceptance) + +# What the test stage stacks on: this build's agent, or a published image. +ARG TEST_BASE=runtime FROM python:3.12-slim AS build COPY --from=ghcr.io/astral-sh/uv:0.12.10 /uv /usr/local/bin/uv @@ -40,9 +46,10 @@ VOLUME /var/lib/nisse-dev USER nisse ENTRYPOINT ["nisse-dev"] -# The image's own package plus the tests, so the end-to-end suite runs -# against what was built, not the source tree. -FROM runtime AS test +# The tests over an image's own package (this build's, or a published one, +# TEST_BASE): only the test tools are added, never the agent reinstalled, so +# the end-to-end suite runs against what was built, not the source beside it. +FROM ${TEST_BASE} AS test USER root RUN apt-get update \ && apt-get install -y --no-install-recommends git openssh-server \ @@ -57,11 +64,9 @@ COPY nisse-ops nisse-ops COPY tests tests COPY scripts scripts COPY conftest.py ./ -ENV UV_PROJECT_ENVIRONMENT=/opt/nisse -# Test tools too, all installed (not editable), and `uv run` never re-syncs: -# the tests import the package as built, not the source tree beside them. -RUN uv sync --frozen --all-packages --no-editable --inexact -ENV UV_NO_SYNC=1 +ENV UV_PROJECT_ENVIRONMENT=/opt/nisse UV_NO_SYNC=1 +RUN uv export --frozen --only-group dev --no-hashes --no-emit-project > /tmp/dev.txt \ + && uv pip install --quiet --python /opt/nisse/bin/python -r /tmp/dev.txt ENTRYPOINT [] # The default target: the agent itself. diff --git a/docs/Development-Plan.md b/docs/Development-Plan.md index 91b468a..456cdcd 100644 --- a/docs/Development-Plan.md +++ b/docs/Development-Plan.md @@ -275,8 +275,9 @@ in prose, asking mid-work (L5, #42, #77). - Deferred: config reload without a restart (with M2.5's entry step if wanted); the trust dial's configuration (M3.3). -**M1.5 The agent as a container image.** *Pre-approved.* **Built** (this PR); -accepted once a tag's image passes the e2e suite. +**M1.5 The agent as a container image.** *Pre-approved.* **Done** (#115; accepted +2026-10-07: `v0.1.0`'s published image passed the whole e2e suite, 9 of 9, run with +the release's own tests over it). - A Dockerfile for `nisse-dev`, stateless with a volume for state; a Gitea Actions workflow that builds it and pushes to Gitea's registry on each release tag (X4). - `bringup.sh` runs the image instead of a venv. @@ -287,6 +288,10 @@ accepted once a tag's image passes the e2e suite. package, for `scripts/e2e.sh --image REF`. Images are built only on release: `release.yml` pushes `gitea.dongar.net/dev/nisse-dev:` and `:latest` on a published release (`REGISTRY_TOKEN`, the `dev` organization's). +- Acceptance runs the tests over a published image: `docker build --target test + --build-arg TEST_BASE=gitea.dongar.net/dev/nisse-dev:` from the + release's checkout, then `scripts/e2e.sh --image`; the test stage adds only the + test tools, so the agent under test is the one published. - The live bring-up's switch to the image waits for the next live test (it needs its own test repository too); `bringup.sh plan` shows what it will run. diff --git a/scripts/e2e.sh b/scripts/e2e.sh index ddb9068..ced432b 100755 --- a/scripts/e2e.sh +++ b/scripts/e2e.sh @@ -23,6 +23,8 @@ if [ "${1:-}" = "--image" ]; then mkdir -p "$runs" secrets=() [ -f .env ] && secrets=(--env-file .env) + # The model, if overridden here, reaches the tests inside too. + [ -n "${NISSE_E2E_MODEL:-}" ] && secrets+=(-e "NISSE_E2E_MODEL=$NISSE_E2E_MODEL") # Host networking: the suite reaches Matrix, Gitea and LiteLLM as here. exec docker run --rm --network host "${secrets[@]}" \ -e NISSE_E2E_RUNS=/runs -v "$runs:/runs" \