The release chain read the tag back from CloudronManifest.json BEFORE pinning
it, so t was always the previous tag: release built the new image, then
deployed the old one and printed success — the exact silent no-op this script
exists to prevent. Its usage text promises build -> pin -> deploy -> verify;
it did build -> deploy.
cmd_build now exports the tag it built and release pins THAT, then deploys and
verifies. Not exercised end-to-end yet (the theme deploy that found this bug
was run as separate build/pin/deploy steps and passed all checks); the edit is
syntax-checked only.
A fetch seconds after 'App is updated' can come back empty while the container
recreates, which false-negatived the x-coop-build check on the 1.4.5 deploy
(2026-10-26). http_body retries 3x before declaring failure.
REGISTRY_BUILD_TOKEN (+ optional REGISTRY_BUILD_USERNAME) lets a build run from
any host with the token in its environment, no ~/.cloudron.json builder config
required. The narrow credential (app password scoped to the registry app) is the
least-privileged way to hand a host build rights; with no token and no builder
config the script prints both bootstrap routes and exits instead of guessing.
I had it wrong: `cloudron builder build` uploads the build context and the
registry app's BuildKit builds it — the caller needs no docker, only a registry
login. The guard now checks for that login and prints both bootstrap routes
(narrow app password scoped to the registry app, or the CLI device flow) instead
of blaming a missing docker binary.
Three drifts between this repo and reality, found while moving the per-member key
seed into the app:
- The 'verify after every image deploy' block asserted the CREAM palette
(rgb(250,248,245)). The deployed palette has been the green wash
(rgb(234,243,234) with white text areas) for some time, so a correct deploy
would have read as a failure — and invited someone to 'fix' the CSS back.
- The block still verified against librechat-test.inference.coop; the swap to
chat.inference.coop happened 2026-10-21 and that alias is not provisioned.
- Nothing checked that the scheduler task's script exists in the running image,
which is exactly the failure mode a manifest repoint can introduce.
release.sh encodes the documented release flow (dirty-tree guard, always
--no-cache, pin-before-deploy) and its verify subcommand runs checks 1-5 plus the
seed task's log lines. sync-keys.js now prints its own md5 prefix on every run,
so a stale volume copy can never hide again — the repo copy's md5 is the
authority.
Verified: ./release.sh verify passes all six checks against the live app;
./release.sh volume sync-keys.js confirms md5 parity.