ci: switch to tag-based Docker builds #129

Merged
cal merged 1 commits from ci/tag-based-docker-builds into main 2026-03-23 17:22:08 +00:00
Owner

Summary

Adopts the Major Domo "build on tag" CI pattern. Docker images are now built only when a CalVer tag is pushed — no more builds on PRs or branch pushes.

Changes

  • Workflow trigger: push.tags: ['20*'] only (removes branch push + PR triggers)
  • Version extraction: inline from tag ref (removes calver, docker-tags, gitea-tag reusable actions)
  • Docker tags: <version> + production (removes dev/rc/stable channel logic)
  • Build cache: added (was missing)
  • CLAUDE.md: removed stale next-release release workflow, updated CI/CD description

How to release

git tag 2026.3.42
git push origin 2026.3.42

What's removed

  • Auto-CalVer generation on merge
  • Multi-channel tag resolution
  • next-release branch triggers
  • PR Docker builds (throwaway images)
## Summary Adopts the Major Domo "build on tag" CI pattern. Docker images are now built only when a CalVer tag is pushed — no more builds on PRs or branch pushes. ### Changes - **Workflow trigger**: `push.tags: ['20*']` only (removes branch push + PR triggers) - **Version extraction**: inline from tag ref (removes `calver`, `docker-tags`, `gitea-tag` reusable actions) - **Docker tags**: `<version>` + `production` (removes dev/rc/stable channel logic) - **Build cache**: added (was missing) - **CLAUDE.md**: removed stale `next-release` release workflow, updated CI/CD description ### How to release ```bash git tag 2026.3.42 git push origin 2026.3.42 ``` ### What's removed - Auto-CalVer generation on merge - Multi-channel tag resolution - `next-release` branch triggers - PR Docker builds (throwaway images)
cal added 1 commit 2026-03-23 15:49:41 +00:00
Replace branch/PR-triggered Docker builds with tag-only triggers.
Images are now built only when a CalVer tag is pushed
(git tag YYYY.M.BUILD && git push origin YYYY.M.BUILD).

- Remove calver, docker-tags, and gitea-tag reusable actions
- Add inline version extraction from tag ref
- Add build cache (was missing)
- Update CLAUDE.md: remove stale next-release release workflow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude added the
ai-reviewing
label 2026-03-23 16:15:47 +00:00
Claude approved these changes 2026-03-23 16:16:46 +00:00
Dismissed
Claude left a comment
Collaborator

AI Code Review

Files Reviewed

  • .gitea/workflows/build.yml (modified)
  • CLAUDE.md (modified)

Findings

Correctness

  • Trigger: push.tags: ['20*'] correctly matches CalVer tags like 2026.3.11. The 20* glob will not false-positive on branch names since branch triggers have been fully removed.
  • Version extraction: VERSION=${GITHUB_REF#refs/tags/} is correct bash parameter expansion. For GITHUB_REF=refs/tags/2026.3.11, this yields 2026.3.11 exactly. No off-by-one or edge case.
  • fetch-depth: 0: Retained and still necessary for git rev-parse --short HEAD in the version step.
  • production tag: Always overwritten on each release — correct behavior for a "latest stable" pointer.
  • Discord notifications: if: success() and if: failure() now fire unconditionally on tag-triggered runs (previously gated on branch name). This is the correct behavior — tag pushes are always release events.
  • Removed gitea-tag step: The auto-tagging-on-merge step is correctly dropped since tags are now created manually before the workflow fires.
  • sha_short and timestamp outputs: Computed in the version step and used in Build Summary and Discord notifications. Not used in Docker tags (appropriate — version tag is the canonical identifier).
  • CLAUDE.md update: Removes the 5-line next-release release workflow and replaces it with a single accurate line. Matches the parent CLAUDE.md which already states the next-release staging pattern is retired.

Security

  • No secrets introduced or exposed. DOCKERHUB_USERNAME, DOCKERHUB_TOKEN, and DISCORD_WEBHOOK continue to be sourced from repository secrets.
  • No shell injection risk — GITHUB_REF is a trusted context variable provided by the runner, not user input.

Style & Conventions

  • Workflow structure follows the existing step-by-step pattern in the file.
  • Inline version extraction replaces three reusable actions with a single 4-line shell block — reduces external dependencies and makes the workflow fully self-contained. Matches the "Major Domo build on tag" pattern referenced in the PR body.
  • Build cache added via type=registry — standard BuildKit pattern, was previously absent.

Suggestions

  • The top comment block (lines 1-8 in the file) will be updated by this PR to reflect the new trigger behavior. This is complete and accurate as written.
  • No suggestions — the change is clean and minimal.

Verdict: APPROVED

Clean, focused CI refactor. Trigger, version extraction, Docker tagging, and Discord notifications are all correct. CLAUDE.md update accurately reflects the new workflow and removes the stale next-release documentation that the parent CLAUDE.md already marked as retired. No correctness issues, no security concerns, no convention violations.


Automated review by Claude PR Reviewer

## AI Code Review ### Files Reviewed - `.gitea/workflows/build.yml` (modified) - `CLAUDE.md` (modified) ### Findings #### Correctness - **Trigger**: `push.tags: ['20*']` correctly matches CalVer tags like `2026.3.11`. The `20*` glob will not false-positive on branch names since branch triggers have been fully removed. - **Version extraction**: `VERSION=${GITHUB_REF#refs/tags/}` is correct bash parameter expansion. For `GITHUB_REF=refs/tags/2026.3.11`, this yields `2026.3.11` exactly. No off-by-one or edge case. - **`fetch-depth: 0`**: Retained and still necessary for `git rev-parse --short HEAD` in the version step. - **`production` tag**: Always overwritten on each release — correct behavior for a "latest stable" pointer. - **Discord notifications**: `if: success()` and `if: failure()` now fire unconditionally on tag-triggered runs (previously gated on branch name). This is the correct behavior — tag pushes are always release events. - **Removed `gitea-tag` step**: The auto-tagging-on-merge step is correctly dropped since tags are now created manually before the workflow fires. - **`sha_short` and `timestamp` outputs**: Computed in the version step and used in Build Summary and Discord notifications. Not used in Docker tags (appropriate — version tag is the canonical identifier). - **CLAUDE.md update**: Removes the 5-line `next-release` release workflow and replaces it with a single accurate line. Matches the parent `CLAUDE.md` which already states the `next-release` staging pattern is retired. #### Security - No secrets introduced or exposed. `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`, and `DISCORD_WEBHOOK` continue to be sourced from repository secrets. - No shell injection risk — `GITHUB_REF` is a trusted context variable provided by the runner, not user input. #### Style & Conventions - Workflow structure follows the existing step-by-step pattern in the file. - Inline version extraction replaces three reusable actions with a single 4-line shell block — reduces external dependencies and makes the workflow fully self-contained. Matches the "Major Domo build on tag" pattern referenced in the PR body. - Build cache added via `type=registry` — standard BuildKit pattern, was previously absent. #### Suggestions - The top comment block (lines 1-8 in the file) will be updated by this PR to reflect the new trigger behavior. This is complete and accurate as written. - No suggestions — the change is clean and minimal. ### Verdict: APPROVED Clean, focused CI refactor. Trigger, version extraction, Docker tagging, and Discord notifications are all correct. CLAUDE.md update accurately reflects the new workflow and removes the stale `next-release` documentation that the parent CLAUDE.md already marked as retired. No correctness issues, no security concerns, no convention violations. --- *Automated review by Claude PR Reviewer*
Claude removed the
ai-reviewing
label 2026-03-23 16:16:54 +00:00
Claude added the
ai-reviewing
label 2026-03-23 16:45:07 +00:00
Claude approved these changes 2026-03-23 16:46:15 +00:00
Dismissed
Claude left a comment
Collaborator

AI Code Review

Files Reviewed

  • .gitea/workflows/build.yml (modified)
  • CLAUDE.md (modified)

Findings

Correctness

  • Trigger pattern '20*' correctly matches CalVer tags like 2026.3.11 and 2026.3.42.
  • VERSION=${GITHUB_REF#refs/tags/} is the standard shell prefix-stripping pattern for tag refs — produces the bare tag value as expected.
  • SHA_SHORT via git rev-parse --short HEAD and timestamp via date -u are both correct inline replacements for the removed calver reusable action outputs.
  • Docker tags (<version> + production) correctly replace the old multi-channel (stable/rc/dev) logic. The production floating tag gives operators a stable pull target.
  • Build cache config (cache-from/cache-to via registry, mode=max) is correct buildx syntax and was genuinely missing before.
  • Discord if: success() and if: failure() are now unconditional — this is correct because the workflow only runs on tag pushes, so the old branch-name guards were redundant noise.
  • The Tag release step (which used cal/gitea-actions/gitea-tag@main to create a git tag on merge) is correctly removed — the tag now exists as the trigger, so creating one inside the job would be a no-op or conflict.
  • CLAUDE.md accurately reflects the new workflow: the stale 5-step next-release release flow is removed, replaced with the two-command release recipe. This aligns with the parent CLAUDE.md note that "next-release staging pattern is retired."

Security

  • No secrets introduced or exposed. DOCKERHUB_USERNAME, DOCKERHUB_TOKEN, and DISCORD_WEBHOOK continue to be consumed from repository secrets — unchanged.
  • The buildcache tag is pushed to the same Docker Hub repo. No new attack surface; standard registry-backed cache pattern.

Style & Conventions

  • Workflow follows the same structure as other Paper Dynasty workflows (checkout → buildx setup → Docker login → build → notify).
  • Comment block at the top is updated to match the new behavior — no stale documentation left in the file.
  • fetch-depth: 0 retained (comment explaining it removed, but the value is kept — acceptable since the full history is still useful for git rev-parse correctness on shallow clones).

Suggestions

  • The fetch-depth: 0 comment removal is minor, but if someone wonders why full history is needed here (it isn't strictly required for rev-parse --short HEAD), a note would be self-documenting. Non-blocking.
  • buildcache is a shared mutable tag. If two tags are pushed in rapid succession, the second build's cache push will race with the first. This is benign (worst case: slightly suboptimal cache hit) but worth being aware of.

Verdict: APPROVED

Clean, focused CI refactor. The implementation exactly matches what the PR body describes — tag-based trigger, inline version extraction, simplified tags, build cache added, stale multi-channel logic removed. No correctness issues, no security regressions. CLAUDE.md update is accurate and consistent with the parent repo's "next-release is retired" convention.


Automated review by Claude PR Reviewer

## AI Code Review ### Files Reviewed - `.gitea/workflows/build.yml` (modified) - `CLAUDE.md` (modified) ### Findings #### Correctness - Trigger pattern `'20*'` correctly matches CalVer tags like `2026.3.11` and `2026.3.42`. - `VERSION=${GITHUB_REF#refs/tags/}` is the standard shell prefix-stripping pattern for tag refs — produces the bare tag value as expected. - `SHA_SHORT` via `git rev-parse --short HEAD` and `timestamp` via `date -u` are both correct inline replacements for the removed `calver` reusable action outputs. - Docker tags (`<version>` + `production`) correctly replace the old multi-channel (stable/rc/dev) logic. The `production` floating tag gives operators a stable pull target. - Build cache config (`cache-from`/`cache-to` via registry, `mode=max`) is correct buildx syntax and was genuinely missing before. - Discord `if: success()` and `if: failure()` are now unconditional — this is correct because the workflow only runs on tag pushes, so the old branch-name guards were redundant noise. - The `Tag release` step (which used `cal/gitea-actions/gitea-tag@main` to create a git tag on merge) is correctly removed — the tag now exists as the trigger, so creating one inside the job would be a no-op or conflict. - CLAUDE.md accurately reflects the new workflow: the stale 5-step `next-release` release flow is removed, replaced with the two-command release recipe. This aligns with the parent CLAUDE.md note that "`next-release` staging pattern is retired." #### Security - No secrets introduced or exposed. `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`, and `DISCORD_WEBHOOK` continue to be consumed from repository secrets — unchanged. - The `buildcache` tag is pushed to the same Docker Hub repo. No new attack surface; standard registry-backed cache pattern. #### Style & Conventions - Workflow follows the same structure as other Paper Dynasty workflows (checkout → buildx setup → Docker login → build → notify). - Comment block at the top is updated to match the new behavior — no stale documentation left in the file. - `fetch-depth: 0` retained (comment explaining it removed, but the value is kept — acceptable since the full history is still useful for `git rev-parse` correctness on shallow clones). #### Suggestions - The `fetch-depth: 0` comment removal is minor, but if someone wonders why full history is needed here (it isn't strictly required for `rev-parse --short HEAD`), a note would be self-documenting. Non-blocking. - `buildcache` is a shared mutable tag. If two tags are pushed in rapid succession, the second build's cache push will race with the first. This is benign (worst case: slightly suboptimal cache hit) but worth being aware of. ### Verdict: APPROVED Clean, focused CI refactor. The implementation exactly matches what the PR body describes — tag-based trigger, inline version extraction, simplified tags, build cache added, stale multi-channel logic removed. No correctness issues, no security regressions. CLAUDE.md update is accurate and consistent with the parent repo's "next-release is retired" convention. --- *Automated review by Claude PR Reviewer*
Claude removed the
ai-reviewing
label 2026-03-23 16:46:26 +00:00
Claude added the
ai-reviewing
label 2026-03-23 17:15:47 +00:00
Claude approved these changes 2026-03-23 17:16:39 +00:00
Dismissed
Claude left a comment
Collaborator

AI Code Review

Files Reviewed

  • .gitea/workflows/build.yml (modified)
  • CLAUDE.md (modified)

Findings

Correctness

  • Tag extraction is correct: ${GITHUB_REF#refs/tags/} is the standard shell parameter expansion for stripping the refs/tags/ prefix from the Gitea/GitHub ref. Produces the bare CalVer string (e.g., 2026.3.11).
  • fetch-depth: 0 is retained — correct, needed so git rev-parse --short HEAD resolves against the full history rather than a shallow clone.
  • The version step is positioned before Set up Docker Buildx and Login to Docker Hub in the new workflow. This reordering is safe — extraction is pure shell, has no Docker dependencies, and the outputs are not consumed until the Build and push step.
  • Both Docker tags (<version> and production) are well-formed; production serves as the stable pull target for deployments without needing to know the exact version.
  • Build cache configuration (cache-from/cache-to with mode=max) is correct and was genuinely missing before.
  • Discord failure notification now fires on any failure (previously gated on branch name), which is correct since the new trigger is tag-only — there's no branch filter needed.

Security

  • No secrets are introduced or exposed. DOCKERHUB_USERNAME, DOCKERHUB_TOKEN, and DISCORD_WEBHOOK continue to be referenced via ${{ secrets.* }} — no change here.
  • The tag glob '20*' is deliberately broad. Any tag starting with 20 triggers a build and push. This is acceptable for a single-owner repo but worth noting: a mis-pushed tag like 2000-oops would trigger a real Docker Hub push. A tighter pattern like '20[0-9][0-9].[0-9]*' would be marginally more defensive, but this is a non-blocking style preference.
  • No hardcoded credentials or tokens in the diff.

Style & Conventions

  • The build.yml comment block at the top (lines 1–8) is updated to match the new trigger model — accurate and consistent with the existing commenting style.
  • The inline To release: note in the comment block is a nice addition for discoverability.
  • CLAUDE.md update replaces the now-stale 5-step next-release release workflow (which the parent CLAUDE.md already retired) with the two-line tag-push command — accurate and concise.
  • The YYYY.M.BUILD format in the CLAUDE.md release line uses .M. (single-digit month) while CalVer tags in the PR body and comments use YYYY.M.BUILD. This is self-consistent within the PR and matches the tag pattern 20*.

Suggestions

  • The 'production' tag is overwritten on every release. If the deployment pull command is docker pull manticorum67/paper-dynasty-database:production, operators don't need to know the version tag — convenient. If they ever need to roll back, they'd need to pull by version tag explicitly. This is a workflow decision, not a bug.
  • Consider whether mode=max cache is appropriate for a single-runner setup. mode=max caches all intermediate layers (more cache hits, more storage). For a low-frequency release workflow this is fine.

Verdict: APPROVED

Clean, focused CI simplification. The tag extraction, Docker build/push, and CLAUDE.md update are all correct. The new workflow is simpler, easier to reason about, and eliminates the multi-channel complexity that was no longer needed after next-release was retired. No correctness issues, no security regressions, no convention violations.


Automated review by Claude PR Reviewer

## AI Code Review ### Files Reviewed - `.gitea/workflows/build.yml` (modified) - `CLAUDE.md` (modified) ### Findings #### Correctness - Tag extraction is correct: `${GITHUB_REF#refs/tags/}` is the standard shell parameter expansion for stripping the `refs/tags/` prefix from the Gitea/GitHub ref. Produces the bare CalVer string (e.g., `2026.3.11`). - `fetch-depth: 0` is retained — correct, needed so `git rev-parse --short HEAD` resolves against the full history rather than a shallow clone. - The `version` step is positioned before `Set up Docker Buildx` and `Login to Docker Hub` in the new workflow. This reordering is safe — extraction is pure shell, has no Docker dependencies, and the outputs are not consumed until the `Build and push` step. - Both Docker tags (`<version>` and `production`) are well-formed; `production` serves as the stable pull target for deployments without needing to know the exact version. - Build cache configuration (`cache-from`/`cache-to` with `mode=max`) is correct and was genuinely missing before. - Discord failure notification now fires on any failure (previously gated on branch name), which is correct since the new trigger is tag-only — there's no branch filter needed. #### Security - No secrets are introduced or exposed. `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`, and `DISCORD_WEBHOOK` continue to be referenced via `${{ secrets.* }}` — no change here. - The tag glob `'20*'` is deliberately broad. Any tag starting with `20` triggers a build and push. This is acceptable for a single-owner repo but worth noting: a mis-pushed tag like `2000-oops` would trigger a real Docker Hub push. A tighter pattern like `'20[0-9][0-9].[0-9]*'` would be marginally more defensive, but this is a non-blocking style preference. - No hardcoded credentials or tokens in the diff. #### Style & Conventions - The `build.yml` comment block at the top (lines 1–8) is updated to match the new trigger model — accurate and consistent with the existing commenting style. - The inline `To release:` note in the comment block is a nice addition for discoverability. - CLAUDE.md update replaces the now-stale 5-step `next-release` release workflow (which the parent `CLAUDE.md` already retired) with the two-line tag-push command — accurate and concise. - The `YYYY.M.BUILD` format in the CLAUDE.md release line uses `.M.` (single-digit month) while CalVer tags in the PR body and comments use `YYYY.M.BUILD`. This is self-consistent within the PR and matches the tag pattern `20*`. #### Suggestions - The `'production'` tag is overwritten on every release. If the deployment pull command is `docker pull manticorum67/paper-dynasty-database:production`, operators don't need to know the version tag — convenient. If they ever need to roll back, they'd need to pull by version tag explicitly. This is a workflow decision, not a bug. - Consider whether `mode=max` cache is appropriate for a single-runner setup. `mode=max` caches all intermediate layers (more cache hits, more storage). For a low-frequency release workflow this is fine. ### Verdict: APPROVED Clean, focused CI simplification. The tag extraction, Docker build/push, and CLAUDE.md update are all correct. The new workflow is simpler, easier to reason about, and eliminates the multi-channel complexity that was no longer needed after `next-release` was retired. No correctness issues, no security regressions, no convention violations. --- *Automated review by Claude PR Reviewer*
Claude added
ai-reviewed
and removed
ai-reviewing
labels 2026-03-23 17:16:48 +00:00
cal reviewed 2026-03-23 17:21:14 +00:00
cal left a comment
Author
Owner

Reviewed by pd-ops (Claude). Changes are correct and match the Major Domo tag-based CI pattern.

  • Trigger correctly converted to push.tags: ['20*'] only — removes branch/PR build noise
  • Inline version extraction via ${GITHUB_REF#refs/tags/} is clean and removes dependency on calver/docker-tags/gitea-tag reusable actions
  • Docker tags <version> + production are correct
  • Build cache added (was missing) — good improvement
  • Build summary and Discord notification steps updated consistently throughout
  • CLAUDE.md correctly removes the stale next-release workflow and documents the new tag-push release process

Approved to merge.

Reviewed by pd-ops (Claude). Changes are correct and match the Major Domo tag-based CI pattern. - Trigger correctly converted to `push.tags: ['20*']` only — removes branch/PR build noise - Inline version extraction via `${GITHUB_REF#refs/tags/}` is clean and removes dependency on calver/docker-tags/gitea-tag reusable actions - Docker tags `<version>` + `production` are correct - Build cache added (was missing) — good improvement - Build summary and Discord notification steps updated consistently throughout - CLAUDE.md correctly removes the stale next-release workflow and documents the new tag-push release process Approved to merge.
Claude approved these changes 2026-03-23 17:21:33 +00:00
Claude left a comment
Collaborator

Reviewed and approved by pd-ops (Claude). Tag-based CI conversion is correct — matches Major Domo pattern, removes calver/docker-tags/gitea-tag reusable actions, adds build cache, updates CLAUDE.md.

Reviewed and approved by pd-ops (Claude). Tag-based CI conversion is correct — matches Major Domo pattern, removes calver/docker-tags/gitea-tag reusable actions, adds build cache, updates CLAUDE.md.
cal merged commit 9ca9ea4f80 into main 2026-03-23 17:22:08 +00:00
cal deleted branch ci/tag-based-docker-builds 2026-03-23 17:22:08 +00:00
Sign in to join this conversation.
No description provided.