diff --git a/README.md b/README.md index c7432705..544fa056 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,9 @@ it does not fetch changes to this Git-built CMS. Use the updater for releases. A clone does **not** install an automatic scheduler. If desired, explicitly add a cron entry with the absolute path of **your** checkout; keep logs in its `logs` directory. Do not configure both CI and Compose updates for the same instance. -The updater refuses an active `epicnext-cms-app` CI-managed container. +On a CI-managed host (either slot container running, or the nginx upstream +pointing at a blue/green slot) the updater skips with exit 0, so a cron run +that legitimately has nothing to do does not look like a failed deployment. Logs: `logs/docker-update.log`. After cutover, a startup, image or HTTP check failure automatically recreates the CMS with its previous image and verifies its @@ -898,7 +900,8 @@ that: - `scripts/docker-update.sh` refuses to run on a CI host. It used to test only `epicnext-cms-app`, but after a cutover to the green slot that container is stopped and deleted, so the guard stopped firing while the host stayed - CI-managed. It now checks both slot containers and the nginx upstream. + CI-managed. It now checks both slot containers and the nginx upstream, and + reports the skip with exit 0 instead of failing the cron. - `ci-deploy.sh` retires a compose replica of *this* checkout (`com.docker.compose.project.config_files`) from the candidate port before starting the candidate — but never a slot container, and never the port nginx diff --git a/src/lib/docker-update.test.ts b/src/lib/docker-update.test.ts index 9f3aa7c1..4db9590f 100644 --- a/src/lib/docker-update.test.ts +++ b/src/lib/docker-update.test.ts @@ -188,29 +188,27 @@ describe("Docker clone updates", () => { expect(r.calls).not.toContain("docker volume prune"); expect(r.calls).not.toContain("docker system prune"); }); - it.each([ - "dirty", - "ci-active", - "ci-green", - "ci-upstream", - "pull-failure", - "build-failure", - "migration-failure", - ])("does not replace the container after %s", (scenario) => { - const r = simulate(scenario); - expect(r.status, r.output).not.toBe(0); - expect(r.calls).not.toContain("compose up"); - }); + it.each(["dirty", "pull-failure", "build-failure", "migration-failure"])( + "does not replace the container after %s", + (scenario) => { + const r = simulate(scenario); + expect(r.status, r.output).not.toBe(0); + expect(r.calls).not.toContain("compose up"); + }, + ); // Regressie: na een cutover naar het groene slot bestaat epicnext-cms-app // niet meer en zag deze controle alleen een vrijgekomen blauwe container. De // dagelijkse `docker-update.sh` startte toen een compose-replica op poort // 3002 en blokkeerde elke volgende release. De blauwe container alleen // controleren is dus geen bewijs dat de host niet door CI beheerd wordt. - it.each(["ci-green", "ci-upstream"])( - "refuses a compose deployment while CI owns the host (%s)", + // + // A host owned by CI is a legitimate no-op, not an error: the cron run must + // exit 0 so it does not look like a failed deployment. + it.each(["ci-active", "ci-green", "ci-upstream"])( + "skips the compose deployment while CI owns the host (%s)", (scenario) => { const r = simulate(scenario); - expect(r.status, r.output).not.toBe(0); + expect(r.status, r.output).toBe(0); expect(r.output).toContain("This host is managed by CI"); expect(r.calls).not.toContain("compose up"); },