ci: push v<semver> tag so deploy-prod can pull it; point .env.prod at real prod paths #129

Merged
fastie81 merged 5 commits from fix/deploy-prod-tag-match into main 2026-09-05 22:06:30 +12:00
Owner

Problem

deploy-prod sets APP_VERSION=${{ github.ref_name }} (e.g. v3.4.3) and pulls forgejo.scrat.co.nz/fastie81/honbu-manager:v3.4.3, but build-release only pushed bare semver (3.4.3) + latest via docker/metadata-action - so deploy-prod would always fail to find the v-prefixed tag. This CI path has never run end-to-end (verified: registry only contains test-* tags).

Fix

Add type=semver,pattern=v{{version}} to build-release metadata tags so the pushed image is also tagged v3.4.x, matching what deploy-prod pulls.

Also: point .env.prod BACKUP_PATH/CONTENT_PATH at the real prod host paths. deploy-prod scp-copies this .env.prod onto the prod node, so it must carry the absolute split-mount paths (else the backup-dir collision fix is silently reverted on the next prod deploy). Production has already been migrated to these paths (see #128 for the code/config split).

Note

Production is already running the fixed image (production-latest from #128, verified healthy, DB intact, backup now valid/non-recursive). This PR finishes making the automated v-tag -> build-release -> deploy-prod loop actually work.

## Problem deploy-prod sets APP_VERSION=${{ github.ref_name }} (e.g. v3.4.3) and pulls forgejo.scrat.co.nz/fastie81/honbu-manager:v3.4.3, but build-release only pushed bare semver (3.4.3) + latest via docker/metadata-action - so deploy-prod would always fail to find the v-prefixed tag. This CI path has never run end-to-end (verified: registry only contains test-* tags). ## Fix Add type=semver,pattern=v{{version}} to build-release metadata tags so the pushed image is also tagged v3.4.x, matching what deploy-prod pulls. Also: point .env.prod BACKUP_PATH/CONTENT_PATH at the real prod host paths. deploy-prod scp-copies this .env.prod onto the prod node, so it must carry the absolute split-mount paths (else the backup-dir collision fix is silently reverted on the next prod deploy). Production has already been migrated to these paths (see #128 for the code/config split). ## Note Production is already running the fixed image (production-latest from #128, verified healthy, DB intact, backup now valid/non-recursive). This PR finishes making the automated v-tag -> build-release -> deploy-prod loop actually work.
ci: push v<semver> tag so deploy-prod can pull it
Some checks failed
CI / lint-frontend (push) Successful in 2m22s
CI / deploy-test (push) Has been cancelled
CI / deploy-prod (push) Has been cancelled
CI / build-release (push) Has been cancelled
CI / test (push) Successful in 2m50s
CI / lint-frontend (pull_request) Successful in 1m12s
CI / build-test (push) Has been cancelled
CI / test (pull_request) Has been cancelled
CI / build-test (pull_request) Has been cancelled
CI / deploy-test (pull_request) Has been cancelled
CI / deploy-prod (pull_request) Has been cancelled
CI / build-release (pull_request) Has been cancelled
60740dfd11
deploy-prod uses APP_VERSION=${{ github.ref_name }} (e.g. v3.4.3) to pull
the image, but build-release only pushed bare semver (3.4.3) + latest, so the
deploy would always fail to find v<ver>. Add type=semver,pattern=v{{version}}
to build-release so the pushed tag matches what deploy-prod pulls.

Also point .env.prod BACKUP_PATH/CONTENT_PATH at the real prod host paths (the
CI deploy scp-copies this file to the prod node), so the split-mounts fix is
applied on deploy rather than defaulting to relative ./paths.
ci: single-image build promoted test -> prod
Some checks failed
CI / build (push) Has been cancelled
CI / deploy-test (push) Has been cancelled
CI / deploy-prod (push) Has been cancelled
CI / lint-frontend (push) Successful in 2m16s
CI / lint-frontend (pull_request) Successful in 1m8s
CI / test (pull_request) Has been cancelled
CI / test (push) Successful in 2m53s
CI / build (pull_request) Has been cancelled
CI / deploy-test (pull_request) Has been cancelled
CI / deploy-prod (pull_request) Has been cancelled
65a3a74488
Requirement: build ONE image, test it, then deploy the same artifact to Test
then Prod.

- Replace separate build-test + build-release jobs with a single build job
  that builds and pushes one immutable image ci-<sha> (and, on a v<semver>
  tag, aliases it to <ver>, v<ver>, <major>.<minor>, latest).
- deploy-test (needs build) and deploy-prod (needs build + deploy-test) both
  consume that same image via needs.build.outputs.image_tag - so the exact
  image tested is what reaches production.
- deploy-prod binds to the -p honbu-manager-production compose project so the
  real data volumes are reused (avoids creating a parallel empty stack).
- Trigger on tags v* for the release path; deploy-test also runs on v-tags so
  the promoted image is exercised on the test node before prod.
- .env.prod: absolute BACKUP_PATH/CONTENT_PATH (prod host paths) so the split
  mount fix survives a CI deploy (CI scp-copies this file to prod).
Author
Owner

Updated (commit 65a3a74): the pipeline now builds ONE image (ci-<sha>, aliased to v<ver>/<ver>/<major>.<minor>/latest on v-tags) and promotes that same artifact through deploy-test -> deploy-prod. deploy-test (needs: build) exercises it on the test node; deploy-prod (needs: build, deploy-test) pushes the identical image to prod on version tags. Also fixes the v-tag pull mismatch and binds -p honbu-manager-production so a prod deploy reuses the real data volumes. .env.prod carries absolute prod BACKUP_PATH/CONTENT_PATH so the #128 split-mount fix survives a CI deploy.

Updated (commit 65a3a74): the pipeline now builds ONE image (`ci-<sha>`, aliased to `v<ver>`/`<ver>`/`<major>.<minor>`/`latest` on v-tags) and promotes that same artifact through deploy-test -> deploy-prod. deploy-test (`needs: build`) exercises it on the test node; deploy-prod (`needs: build, deploy-test`) pushes the identical image to prod on version tags. Also fixes the v-tag pull mismatch and binds `-p honbu-manager-production` so a prod deploy reuses the real data volumes. `.env.prod` carries absolute prod BACKUP_PATH/CONTENT_PATH so the #128 split-mount fix survives a CI deploy.
ci: overlap image build with tests to cut wall-clock
Some checks failed
CI / deploy-test (push) Has been cancelled
CI / deploy-prod (push) Has been cancelled
CI / build (pull_request) Failing after 1m19s
CI / lint-frontend (push) Successful in 2m16s
CI / build (push) Failing after 1m18s
CI / test (push) Successful in 3m0s
CI / lint-frontend (pull_request) Successful in 2m5s
CI / test (pull_request) Successful in 2m53s
CI / deploy-test (pull_request) Has been skipped
CI / deploy-prod (pull_request) Has been skipped
926e618d35
Same tests, same deployment gates - the Docker image build now runs in
parallel with test/lint (build needs:[]), while deploy-test and deploy-prod
re-gate on test+lint+build (and deploy-prod also on deploy-test). This cuts
the critical path from test(after lint) then build (~3min + ~5min) to
max(test, build) (~5min) because the image build no longer waits for tests,
but tests still gate everything that is deployed. BuildKit inline layer cache
means pip/apt layers are also reused across runs.
ci: single push trigger plus expose podman socket to build job
All checks were successful
CI / test (push) Successful in 2m51s
CI / lint-frontend (push) Successful in 2m8s
CI / build (push) Successful in 2m30s
CI / deploy-test (push) Has been skipped
CI / deploy-prod (push) Has been skipped
43c5d54dfe
Drop the pull_request trigger - single-owner repo has no forks, so every PR
push fired both a push and a pull_request run, doubling each job.

Expose the runner's docker-compatible podman socket into the build job as
/var/run/docker.sock and set DOCKER_HOST so docker login and buildx can build.
This was a pre-existing gap on the Podman runner at 192.168.10.33 - build-test
had pushed 48 tags historically, but on the current podman label the job
container had no daemon socket, so buildx failed. Since deploy gates on build,
it had to reach a working daemon.

Same tests, same deployments - single trigger, no duplication, build reaches a daemon.
ci: prune old ci-* images (keep latest 5) via Forgejo packages API
All checks were successful
CI / test (push) Successful in 5m54s
CI / lint-frontend (push) Successful in 1m12s
CI / build (push) Successful in 2m24s
e1fcc240f2
Every build pushes an immutable ci-<sha> image; without retention the registry
accumulates one per push. After push, this step lists container versions via
the Forgejo packages API and deletes all but the 5 newest ci-* images (keeps
production-* and current). Uses REGISTRY_TOKEN (same token as docker login).
Sign in to join this conversation.
No reviewers
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
fastie81/honbu-manager!129
No description provided.