deploy: rebuild build: images when their inputs change #290

Merged
mysticalsoap merged 1 commit from deploy-rebuild into trunk 2026-09-19 23:17:10 -04:00
Owner

Problem

just deploy keyed on */compose.yml only. A Renovate bump of a Dockerfile FROM digest, or an edit to anything a Dockerfile copies, changed nothing live until a manual build. Four images are built locally (config-renderer behind five init containers, dagu-tools, metadata, knock). Closes #288.

Fix

  • changed_stacks now also matches a stack when a changed path is one of its build inputs: each build: service's Dockerfile plus the sources of its COPY/ADD lines (globs cut at the first wildcard, --from= stages skipped). Contexts and dockerfile overrides are read from docker compose config --format json, so they resolve exactly as compose does. The whole build context is deliberately not watched: config-renderer and knock build from _helper itself, and that would recreate infra on every docs edit.
  • Any build: stack is brought up with --build. Cache hit when nothing changed, real build otherwise.
  • --dry-run prints what would be recreated. Maintenance.md updated in both places that describe just deploy.

Verification

  • Resolved inputs per stack, on the live tree: infra/monitoring/invidious → _helper/config-renderer/Dockerfile; dagu → dagu/tools/Dockerfile; media → media/metadata/Dockerfile; web → _helper/knock/Dockerfile plus _helper/common, _helper/knock/requirements.txt, jellyfin-defaults.json, static, templates.
  • Synthetic change set {_helper/knock/requirements.txt, _helper/common/notify.py, _helper/docs/Maintenance.md, dagu/tools/Dockerfile} selects exactly dagu and web; the docs path triggers nothing.
  • python3 _helper/deploy.py --dry-run on a clean tree: "No changed stacks to deploy." With dagu --dry-run: "would recreate dagu/compose.yml (with --build)".
  • just deploy dagu for real: dagu-dagu-tools built (cache), container recreated, stack healthy.
## Problem `just deploy` keyed on `*/compose.yml` only. A Renovate bump of a Dockerfile `FROM` digest, or an edit to anything a Dockerfile copies, changed nothing live until a manual build. Four images are built locally (config-renderer behind five init containers, dagu-tools, metadata, knock). Closes #288. ## Fix - `changed_stacks` now also matches a stack when a changed path is one of its build inputs: each `build:` service's Dockerfile plus the sources of its `COPY`/`ADD` lines (globs cut at the first wildcard, `--from=` stages skipped). Contexts and dockerfile overrides are read from `docker compose config --format json`, so they resolve exactly as compose does. The whole build context is deliberately not watched: config-renderer and knock build from `_helper` itself, and that would recreate infra on every docs edit. - Any `build:` stack is brought up with `--build`. Cache hit when nothing changed, real build otherwise. - `--dry-run` prints what would be recreated. Maintenance.md updated in both places that describe `just deploy`. ## Verification - Resolved inputs per stack, on the live tree: infra/monitoring/invidious → `_helper/config-renderer/Dockerfile`; dagu → `dagu/tools/Dockerfile`; media → `media/metadata/Dockerfile`; web → `_helper/knock/Dockerfile` plus `_helper/common`, `_helper/knock/requirements.txt`, `jellyfin-defaults.json`, `static`, `templates`. - Synthetic change set `{_helper/knock/requirements.txt, _helper/common/notify.py, _helper/docs/Maintenance.md, dagu/tools/Dockerfile}` selects exactly dagu and web; the docs path triggers nothing. - `python3 _helper/deploy.py --dry-run` on a clean tree: "No changed stacks to deploy." With `dagu --dry-run`: "would recreate dagu/compose.yml (with --build)". - `just deploy dagu` for real: dagu-dagu-tools built (cache), container recreated, stack healthy.
deploy: rebuild build: images when their inputs change
All checks were successful
validate / validate (pull_request) Successful in 23s
eedd2fc6a6
deploy.py only watched */compose.yml, so a Renovate bump of a Dockerfile's
FROM digest, or any edit to what a Dockerfile copies, changed nothing live
until someone built by hand. The image scan showed the cost on dagu-tools
and metadata.

Build inputs come from `docker compose config` (contexts resolved the way
compose resolves them) plus a parse of each Dockerfile's COPY/ADD sources,
globs cut at their first wildcard. Watching the whole build context instead
would make every docs edit under _helper recreate infra, since
config-renderer and knock build from _helper itself.

A build: stack always comes up with --build: a cache hit when nothing
changed, so the flag costs nothing in the common case and the detection
only decides whether the stack is touched at all.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mysticalsoap deleted branch deploy-rebuild 2026-09-19 23:17:10 -04:00
Sign in to join this conversation.
No description provided.