diff --git a/.gitea/workflows/nightly.yml b/.gitea/workflows/nightly.yml index dcf349b2..da11ebf7 100644 --- a/.gitea/workflows/nightly.yml +++ b/.gitea/workflows/nightly.yml @@ -76,6 +76,28 @@ jobs: IMPORT_HOST_DIR=/srv/familienarchiv-staging/import EOF + - name: Verify backend /import:ro mount is wired + # Regression guard for #526: the /admin/system mass-import card + # only works when the backend service mounts the host import + # payload at /import (read-only). If a future "compose cleanup" + # PR drops the volumes block, mass import silently breaks again. + # `compose config` renders both shorthand and longform mounts as + # `target: /import` + `read_only: true`, so we assert against + # the rendered form rather than the raw source YAML. + run: | + set -e + docker compose \ + -f docker-compose.prod.yml \ + -p archiv-staging \ + --env-file .env.staging \ + --profile staging \ + config > /tmp/compose-rendered.yml + grep -q '^[[:space:]]*target: /import$' /tmp/compose-rendered.yml \ + || { echo "::error::backend is missing the /import bind mount (see #526)"; exit 1; } + grep -A2 '^[[:space:]]*target: /import$' /tmp/compose-rendered.yml \ + | grep -q 'read_only: true' \ + || { echo "::error::backend /import mount is not read-only (see #526)"; exit 1; } + - name: Build images # `--pull` forces re-fetching pinned base images so a CVE # re-publication of the same tag (e.g. node:20.19.0-alpine3.21,