ci: auto-tag per merge + republish stack only when compose changes#7
Conversation
Reworks publish-stack.yml from "publish on a v* tag" to a two-job release workflow on push to main (a merged PR): - `tag` job: derive the version from pyproject.toml, create+push the `v<version>` git tag (so tags track the PyPI release 1:1), then gate — set publish=true only when docker-compose.yml differs from the previous tag (or there is no previous tag). Idempotent: skips if the tag exists. - `publish-stack` job: runs only when publish=true; unchanged publish steps (validate compose, GHCR login, `docker compose publish` :version + :latest, attach docker-compose.yml to the Release). Net effect: every merge gets a version tag (parity with the PyPI release from publish.yml), but the stack OCI image is republished only when the substrate actually changed — no more byte-identical churn on CLI-only releases. `workflow_dispatch` with a tag input force-(re)publishes a specific version. Docs: docs/stack-image.md + CLAUDE.md updated. Version 0.5.0 -> 0.5.2 (0.5.1 is held by the open Sonar-hygiene PR #6). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
/agentic_review |
Code Review by Qodo
Context used✅ Compliance rules (platform):
15 rules 1.
|
PR Summary by QodoCI: auto-tag merges and publish stack only when docker-compose changes Description
Diagram
High-Level Assessment
Files changed (5)
|
The tag job early-exited with publish=false whenever the version tag already existed, so a re-run could never repair a release that failed *after* the tag was pushed but before the OCI artifact / release asset were created — the artifacts stayed stranded until a manual dispatch. Drop the early-exit. Compute the previous tag as the highest v* EXCLUDING the current TAG, then run the compose-change gate normally. Tag creation stays idempotent (skipped when the tag exists); only *publishing* is gated. A re-run now re-evaluates and can re-publish to recover. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ated-stack # Conflicts: # CHANGELOG.md # pyproject.toml
|



Release model: auto-tag every merge, republish the stack only when it changes
Implements the chosen release model (auto-tag per merge; GHCR stack image only on a real substrate change). Reworks
publish-stack.ymlfrom "publish on av*tag" into a two-job release workflow that runs on push tomain(a merged PR):tagjob — derive the version frompyproject.toml, create + push thev<version>git tag (so tags track the PyPI release 1:1), then gate:publish=trueonly whendocker-compose.ymldiffers from the previous tag (or there's no previous tag). Idempotent — skips if the tag already exists.publish-stackjob — runs only whenpublish=true; the publish steps are unchanged (validate compose → GHCR login →docker compose publish:version+:latest→ attachdocker-compose.ymlto the Release).Why
Today every merge bumps the version (→ a PyPI release via
publish.yml), but the stack image only existed when someone hand-pushed av*tag. This gives:docker-compose.yml, so no more byte-identical OCI churn.workflow_dispatchwith ataginput still force-(re)publishes a specific version's stack, regardless of the gate.Notes
0.5.2; the open Sonar-hygiene PR chore: per-version Sonar wiring + clear 4 stack.py smells #6 (0.5.1) should merge first. If they land out of order, the later one needs a trivial re-bump. CHANGELOG may need a one-line reorder on rebase — I'll handle it.v0.5.1won't get a tag (it merges before this workflow exists). Auto-tagging begins at the first push tomainafter this lands (which will tagv0.5.2; compose unchanged → tag only, no stack republish — exactly the intended behavior).publish.ymlchange — PyPI stays continuous per merge.CLAUDE.md/docs/stack-image.mdfor the description only (noculture.yaml/skills change → no sibling propagation).Gates
YAML valid; embedded
tag-job bash passesbash -n; markdownlint clean; pytest 135 passed (no Python changed); teken rubric 26/26. Version 0.5.0 → 0.5.2.