Prereleases for testing on dev, and both hosts run the published images #1043

Closed
opened 2026-10-03 14:05:58 +00:00 by claude-bot · 3 comments
Collaborator

Owner's decision (2026-10-03, answering #1042 items 2 and 3): cut prereleases (vX.Y.Z-rcN) for testing on the dev server, and switch production to the published images instead of building from source.

What already exists

  • release.yml builds and pushes quest-board-{backend,frontend,bot}:<version> for every v*.*.* tag, adds :latest only for a final, and marks a tag containing - as a prerelease. Images exist for every release through 4.4.1.
  • Prod runs 4.4.1 built from source at a6abef1, the same commit the 4.4.1 images were built from.
  • Dev builds main from source (currently at 8192839d).
  • Both hosts have Docker Compose v5.5.0 and are logged in to the registry.

Gaps

  1. A prerelease's release notes come out as "No changelog entry found": release.yml looks for a ## [X.Y.Z-rcN] heading in CHANGELOG.md, and an rc should not gather the fragments that belong to the final.
  2. No compose overlay for the published images is committed. docs/OPERATIONS.md only shows an example pinned to 3.4.0.
  3. Nothing ties the image tag a host runs to the release it checked out.

Approach

  • docker-compose.images.yml, committed. It gives the six app services image: git.rhoving.com/rbrooks/quest-board-<c>:<version> and build: !reset null, so an image host cannot build from source. The release commit sets the version in this file alongside APP_VERSION, and check_version_sync.py enforces that they agree.
  • How a host runs it. The host's .env sets COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml. A deploy is git fetch --tags && git checkout v<version> && docker compose pull && docker compose up -d; rollback checks out the previous tag (only across releases without a migration).
  • Prerelease notes. A new changelog.py render prints the pending fragments without consuming them, and release.yml uses it for a tag containing -. An rc bumps the version in version.py, the bot's BOT_EXPECTED_APP_VERSION and the overlay; the fragments stay put until the final.
  • Docs and profile. docs/OPERATIONS.md gains "Cutting a prerelease" and rewrites "Running from Published Images" and "Updating Production". The project profile records Deploy.model: image and the prod image deploy, and the /qb-deploy-dev addendum is updated to match.

Host cutovers (separate, each confirmed by the owner)

  • Prod: switch to the 4.4.1 images, the same commit it runs now, so the cutover changes how prod runs and nothing it runs. The .env edit recreates every service, db and redis included, once.
  • Dev: dev's database is ahead of 4.4.1, so dev cuts over on the first prerelease (v4.5.0-rc1 or whatever the owner names it), not on 4.4.1.
  • From then on, dev receives changes only through prerelease tags, and no longer by deploying main.
**Owner's decision (2026-10-03, answering #1042 items 2 and 3):** cut prereleases (`vX.Y.Z-rcN`) for testing on the dev server, and switch production to the published images instead of building from source. ## What already exists - `release.yml` builds and pushes `quest-board-{backend,frontend,bot}:<version>` for every `v*.*.*` tag, adds `:latest` only for a final, and marks a tag containing `-` as a prerelease. Images exist for every release through 4.4.1. - **Prod** runs 4.4.1 built from source at `a6abef1`, the same commit the 4.4.1 images were built from. - **Dev** builds `main` from source (currently at `8192839d`). - Both hosts have Docker Compose v5.5.0 and are logged in to the registry. ## Gaps 1. A prerelease's release notes come out as "No changelog entry found": `release.yml` looks for a `## [X.Y.Z-rcN]` heading in `CHANGELOG.md`, and an rc should not gather the fragments that belong to the final. 2. No compose overlay for the published images is committed. `docs/OPERATIONS.md` only shows an example pinned to 3.4.0. 3. Nothing ties the image tag a host runs to the release it checked out. ## Approach - **`docker-compose.images.yml`, committed.** It gives the six app services `image: git.rhoving.com/rbrooks/quest-board-<c>:<version>` and `build: !reset null`, so an image host cannot build from source. The release commit sets the version in this file alongside `APP_VERSION`, and `check_version_sync.py` enforces that they agree. - **How a host runs it.** The host's `.env` sets `COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml`. A deploy is `git fetch --tags && git checkout v<version> && docker compose pull && docker compose up -d`; rollback checks out the previous tag (only across releases without a migration). - **Prerelease notes.** A new `changelog.py render` prints the pending fragments without consuming them, and `release.yml` uses it for a tag containing `-`. An rc bumps the version in `version.py`, the bot's `BOT_EXPECTED_APP_VERSION` and the overlay; the fragments stay put until the final. - **Docs and profile.** `docs/OPERATIONS.md` gains "Cutting a prerelease" and rewrites "Running from Published Images" and "Updating Production". The project profile records `Deploy.model: image` and the prod image deploy, and the `/qb-deploy-dev` addendum is updated to match. ## Host cutovers (separate, each confirmed by the owner) - **Prod:** switch to the 4.4.1 images, the same commit it runs now, so the cutover changes how prod runs and nothing it runs. The `.env` edit recreates every service, db and redis included, once. - **Dev:** dev's database is ahead of 4.4.1, so dev cuts over on the first prerelease (`v4.5.0-rc1` or whatever the owner names it), not on 4.4.1. - **From then on**, dev receives changes only through prerelease tags, and no longer by deploying `main`.
rbrooks referenced this issue from a commit 2026-10-03 15:03:15 +00:00
Author
Collaborator

Reopened. PR #1044 (the repo side) merged on 2026-10-03 and closed this automatically, but the host cutovers are part of this issue and are still to do.

The owner approved both on 2026-10-03:

  1. Dev → v4.5.0-rc1. The release PR is #1048. Once it merges: tag, wait for the images, then on docker-test back up .env, add COMPOSE_FILE, git checkout v4.5.0-rc1, pull and up, verify, and re-run the demo seed with --reset (lane 10's note: the next dev deploy needs it).
  2. Prod → the 4.4.1 images it already runs, after dev has proven the mechanics. The v4.4.1 tag predates the overlay, so the file goes in as an untracked copy, which must be deleted before the next git checkout vX. Then back up .env, make backup-now, add COMPOSE_FILE, pull and up.

Each step is reported here as it happens.

**Reopened.** PR #1044 (the repo side) merged on 2026-10-03 and closed this automatically, but the host cutovers are part of this issue and are still to do. The owner approved both on 2026-10-03: 1. **Dev → `v4.5.0-rc1`.** The release PR is #1048. Once it merges: tag, wait for the images, then on docker-test back up `.env`, add `COMPOSE_FILE`, `git checkout v4.5.0-rc1`, pull and up, verify, and re-run the demo seed with `--reset` (lane 10's note: the next dev deploy needs it). 2. **Prod → the 4.4.1 images** it already runs, after dev has proven the mechanics. The `v4.4.1` tag predates the overlay, so the file goes in as an untracked copy, which must be deleted before the next `git checkout vX`. Then back up `.env`, `make backup-now`, add `COMPOSE_FILE`, pull and up. Each step is reported here as it happens.
Author
Collaborator

Dev is on v4.5.0-rc1, from the published images (2026-10-03 ~15:35 UTC)

The release. PR #1048 merged, the tag was pushed, and the release workflow passed. The release is marked as a prerelease, and its notes are rendered from the fragments ("Prerelease of 4.5.0 for testing on the dev server; not for production.", then the sections). All three :4.5.0-rc1 images are published.

On docker-test, in ~/projects/Quest-Board:

  1. .env backed up to .env.bak-20261003T153040Z, and the database to questboard_manual_20261003T153042Z.dump, both before any change.
  2. git checkout v4.5.0-rc1, and COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml appended to .env. Then docker compose config --images resolves only the three :4.5.0-rc1 images, plus postgres and redis.
  3. docker compose pull && docker compose up -d. The migrate service applied the two new migrations (b680d1e2f3a4 #680, c1007a1b2c3d #1007).
  4. Verified:
    • all seven services healthy, each app service on its :4.5.0-rc1 image
    • curl http://localhost:18081/api/meta returns {"version":"4.5.0-rc1"}
    • /ready returns ok
    • no error or traceback in the backend, worker, beat or bot logs
  5. The new docs' preflight works: docker compose run --rm migrate python -m app.cli db_preflight from the new image printed revision c1007a1b2c3d, 26 users and 10 campaigns.
  6. Demo seed re-run with --reset, as lane 10 asked for the next dev deploy: 106 wiki articles, 21 session scripts, 152 media files, 14 tripwires armed with 0 attempts. A dry run first matched.

For the owner's review: lanes 5 to 11, the R4 fixes, the search results page (#1033) and the prototype drawings (#1047) are all live on dev now.

Next: prod onto the 4.4.1 images.

## Dev is on `v4.5.0-rc1`, from the published images (2026-10-03 ~15:35 UTC) **The release.** PR #1048 merged, the tag was pushed, and the release workflow passed. The release is marked as a prerelease, and its notes are rendered from the fragments ("Prerelease of 4.5.0 for testing on the dev server; not for production.", then the sections). All three `:4.5.0-rc1` images are published. **On docker-test**, in `~/projects/Quest-Board`: 1. `.env` backed up to `.env.bak-20261003T153040Z`, and the database to `questboard_manual_20261003T153042Z.dump`, both before any change. 2. `git checkout v4.5.0-rc1`, and `COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml` appended to `.env`. Then `docker compose config --images` resolves only the three `:4.5.0-rc1` images, plus postgres and redis. 3. `docker compose pull && docker compose up -d`. The `migrate` service applied the two new migrations (`b680d1e2f3a4` #680, `c1007a1b2c3d` #1007). 4. **Verified:** - all seven services healthy, each app service on its `:4.5.0-rc1` image - `curl http://localhost:18081/api/meta` returns `{"version":"4.5.0-rc1"}` - `/ready` returns ok - no error or traceback in the backend, worker, beat or bot logs 5. **The new docs' preflight works:** `docker compose run --rm migrate python -m app.cli db_preflight` from the new image printed revision `c1007a1b2c3d`, 26 users and 10 campaigns. 6. **Demo seed re-run** with `--reset`, as lane 10 asked for the next dev deploy: 106 wiki articles, 21 session scripts, 152 media files, 14 tripwires armed with 0 attempts. A dry run first matched. **For the owner's review:** lanes 5 to 11, the R4 fixes, the search results page (#1033) and the prototype drawings (#1047) are all live on dev now. **Next:** prod onto the 4.4.1 images.
Author
Collaborator

Prod is on the published 4.4.1 images (2026-10-03 ~15:38 UTC)

It runs what it ran before, the same release, from images. On docker-host, in /home/ryan/Quest-Board, at the v4.4.1 tag:

  1. Overlay in place. docker-compose.images.yml is written as an untracked copy of the 4.4.1 overlay (from 2064c2b2, the #1044 merge), because the v4.4.1 tag predates the file. config --images resolved only the three :4.4.1 images, and they were pulled ahead of the switch with the running services untouched.
  2. Backups. .env to .env.bak-20261003T153754Z, and the database to questboard_manual_20261003T153756Z.dump.
  3. Switch. COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml appended to .env, then docker compose up -d. Every service was recreated (db and redis included, as expected for a .env edit) and was down for about a minute.
  4. Verified:
    • all seven services healthy, each app service on git.rhoving.com/rbrooks/quest-board-*:4.4.1
    • APP_VERSION is 4.4.1 and /ready returns ok
    • migrate had nothing to apply
    • the bot logged "Version handshake OK: backend 4.4.1, bot API contract v1"
    • 0 tracebacks in the backend, worker, beat or frontend logs since
    • /api/meta returns 404 on prod: it was added after 4.4.1, so prod's version check is the exec form until the next release.

Notes for the next prod update:

  • Delete the untracked docker-compose.images.yml before git checkout vX.Y.Z. The tag carries its own copy, and git will refuse to check out over an untracked file. Then docker compose pull && docker compose up -d as docs/OPERATIONS.md says.
  • Rollback for this cutover: cp .env.bak-20261003T153754Z .env && docker compose up -d. The old source-built quest-board-*:latest images are still on the host, and compose uses them without building.
  • The pull also refreshed postgres:16-alpine and redis:7-alpine to their current digests, within the same major versions.

Both cutovers are done, so this is closed. #1045 (make migrate-safe) is the follow-up.

## Prod is on the published 4.4.1 images (2026-10-03 ~15:38 UTC) It runs what it ran before, the same release, from images. On `docker-host`, in `/home/ryan/Quest-Board`, at the `v4.4.1` tag: 1. **Overlay in place.** `docker-compose.images.yml` is written as an **untracked** copy of the 4.4.1 overlay (from `2064c2b2`, the #1044 merge), because the `v4.4.1` tag predates the file. `config --images` resolved only the three `:4.4.1` images, and they were pulled ahead of the switch with the running services untouched. 2. **Backups.** `.env` to `.env.bak-20261003T153754Z`, and the database to `questboard_manual_20261003T153756Z.dump`. 3. **Switch.** `COMPOSE_FILE=docker-compose.yml:docker-compose.images.yml` appended to `.env`, then `docker compose up -d`. Every service was recreated (db and redis included, as expected for a `.env` edit) and was down for about a minute. 4. **Verified:** - all seven services healthy, each app service on `git.rhoving.com/rbrooks/quest-board-*:4.4.1` - `APP_VERSION` is 4.4.1 and `/ready` returns ok - `migrate` had nothing to apply - the bot logged "Version handshake OK: backend 4.4.1, bot API contract v1" - 0 tracebacks in the backend, worker, beat or frontend logs since - `/api/meta` returns 404 on prod: it was added after 4.4.1, so prod's version check is the `exec` form until the next release. **Notes for the next prod update:** - **Delete the untracked `docker-compose.images.yml` before `git checkout vX.Y.Z`.** The tag carries its own copy, and git will refuse to check out over an untracked file. Then `docker compose pull && docker compose up -d` as `docs/OPERATIONS.md` says. - **Rollback for this cutover:** `cp .env.bak-20261003T153754Z .env && docker compose up -d`. The old source-built `quest-board-*:latest` images are still on the host, and compose uses them without building. - The pull also refreshed `postgres:16-alpine` and `redis:7-alpine` to their current digests, within the same major versions. Both cutovers are done, so this is closed. #1045 (`make migrate-safe`) is the follow-up.
rbrooks referenced this issue from a commit 2026-10-03 17:39:50 +00:00
rbrooks referenced this issue from a commit 2026-10-04 06:57:14 +00:00
rbrooks referenced this issue from a commit 2026-10-04 16:38:11 +00:00
rbrooks referenced this issue from a commit 2026-10-05 00:39:29 +00:00
rbrooks referenced this issue from a commit 2026-10-05 07:42:48 +00:00
rbrooks referenced this issue from a commit 2026-10-05 10:27:56 +00:00
rbrooks referenced this issue from a commit 2026-10-05 11:58:48 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#1043
No description provided.