fix(deploy): drop COPY data/ from Dockerfile so worktree-context staging build succeeds

The ORCH-058 staging rebuild (check_staging_image_fresh) builds the image with
the task git-worktree as the docker build context. A fresh worktree holds only
tracked files, but the Dockerfile did `COPY data/ ./data/` — and `data/` (the
SQLite dir) is gitignored, so it is absent from that context: `docker build`
failed with exit 1 ("BUILD-STAGING: docker build failed - aborting"), bouncing
the task off deploy-staging back to development in a loop.

The COPY was dead weight regardless: `data/` is always supplied at runtime as a
bind-mount volume (./data:/app/data, see docker-compose.yml) which shadows
anything baked into the image. Replace it with `RUN mkdir -p /app/data` so the
mountpoint exists without depending on the build context.

Regression guard: test_tc08b_dockerfile_does_not_copy_gitignored_data_dir
forbids COPY of any gitignored path (the worktree-context invariant).

Refs: ORCH-021

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 14:30:02 +00:00
committed by Dev Agent
parent b04fae748e
commit b9bcdc1545
3 changed files with 34 additions and 1 deletions

View File

@@ -102,6 +102,31 @@ def test_tc08_dockerfile_stamps_revision_label():
assert "LABEL org.opencontainers.image.revision=$GIT_SHA" in text
# ---------------------------------------------------------------------------
# TC-08b (ORCH-021 regression): the Dockerfile must not COPY a gitignored path.
# The ORCH-058 staging rebuild builds with the task *worktree* as the docker build
# context. A fresh worktree contains only tracked files, so any `COPY <gitignored>`
# (notably `data/`, the SQLite dir) makes `docker build` fail with exit 1 and bounces
# the task off `deploy-staging`. `data/` is a runtime bind-mount volume anyway, so it
# must never be a COPY source.
# ---------------------------------------------------------------------------
def test_tc08b_dockerfile_does_not_copy_gitignored_data_dir():
text = _DOCKERFILE.read_text(encoding="utf-8")
gitignore = (_ROOT / ".gitignore").read_text(encoding="utf-8").splitlines()
# Precondition: `data/` really is gitignored (the build context will not have it).
assert "data/" in [ln.strip() for ln in gitignore]
# The Dockerfile must not COPY it (would break the worktree-context staging build).
copy_sources = [
line.split()[1]
for line in text.splitlines()
if line.strip().upper().startswith("COPY") and len(line.split()) >= 3
]
assert "data/" not in copy_sources, (
"Dockerfile must not `COPY data/` — it's gitignored and absent from the "
"worktree build context used by the ORCH-058 staging rebuild (exit 1)."
)
# ---------------------------------------------------------------------------
# TC-09: caller↔hook contract — rebuild_staging_image builds the right command
# ---------------------------------------------------------------------------