Skip to content

build!: release from version tags - #112

Merged
uniqueg merged 8 commits into
devfrom
build/release-from-tags
Oct 20, 2026
Merged

uniqueg merged 8 commits into
devfrom
build/release-from-tags

Conversation

@uniqueg

@uniqueg uniqueg commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Summary

Releases now come from signed version tags, like FOCA's (#81), without PyPI:

  • Version: taken from Git tags with setuptools-scm (version is dynamic in pyproject.toml); builds without Git metadata fall back to 0.0.0.dev0. The Docker build takes the version via the build argument SETUPTOOLS_SCM_PRETEND_VERSION.
  • Release workflow (.github/workflows/release.yaml), on v* tags:
    • checks the tag: canonical vX.Y.Z or pre-release vX.Y.Z(a|b|rc)N, annotated, signature verified by GitHub, commit on main;
    • packages the Helm chart with version and appVersion from the tag (pre-releases as SemVer X.Y.Z-rcN);
    • after approval in the release environment: builds the image once, checks that it reports the release version, pushes it as X.Y.Z, then decides latest (highest stable release on main, never pre-releases) and creates the GitHub release with the chart attached.
  • Dev images: merges to dev publish dev and sha-<commit> in the dev-images environment; date tags and philips-software/docker-ci-scripts are gone.
  • Chart: the image tag comes from the new value cloud_registry.tag, defaulting to the chart's appVersion; images with a tag or digest in cloud_registry.image keep working. Chart.yaml holds placeholders (version: 0.0.0, appVersion: dev), set from the tag at release.
  • Docs: README "Versioning and releases" (release steps for maintainers and the repository settings the workflows rely on), deployment README "Image".

Closes #81

Breaking change

Docker Hub latest now points to the latest release, not to the latest dev build; use dev or sha-<commit> for those. Date-tagged images are no longer pushed.

Verification

Locally (Python 3.10 venv with the dev requirements, Helm 3.18.6):

  • ruff check ., ruff format --check .: passed
  • mypy cloud_registry tests: no issues in 26 files
  • ast-grep scan, ast-grep test: passed
  • pytest (chart tests included): 258 passed
  • helm lint --strict (with and without MongoDB auth): passed
  • actionlint: passed (without shellcheck); zizmor (offline): no findings in the changed lines
  • semgrep (.semgrep), gitleaks: no findings
  • Version from tags checked with a temporary repository and with SETUPTOOLS_SCM_PRETEND_VERSION; tag regex and chart version mapping checked for stable, a, b, rc and malformed tags
  • Two review rounds (adversarial and quality); all findings fixed.

Not run locally (no Docker): image builds and the Compose smoke test (run in CI). The release job's Docker steps, the GitHub signature check and the latest step first run at the first release.

CI: all checks passed (static code analysis; tests on Python 3.10 and 3.12; Helm chart; Docker Compose, including the new version check; Read the Docs, after fixing the docs version in db40156).

Notes

  • Repository settings needed before the first release: environments release (required reviewer, tag rule v*) and dev-images (branch dev), each with the Docker Hub secrets; then remove the repository-level Docker Hub secrets.
  • The Docker steps of the release workflow can only run at the first release; the dev-image and Compose steps run in this PR's CI and on merge.

🤖 Generated with Claude Code

Summary by Sourcery

Adopt signed Git tags as the single source for application, image, chart, and GitHub release versions.

New Features:

  • Add signed Git-tag-driven releases that publish versioned Docker images, Helm charts, and GitHub releases without PyPI.
  • Publish development images from the dev branch using stable dev and commit-specific tags.
  • Support configurable Helm image tags with release-aware defaults and preserve compatibility with tagged or digested image references.

Enhancements:

  • Derive application versions from Git tags with a development fallback and propagate versions consistently into Docker images, Compose, documentation, and API docs.

Build:

  • Pass explicit package versions into Docker and Compose builds when Git metadata is unavailable.

CI:

  • Replace date-tagged image publishing with environment-protected dev image publishing and add image version verification.
  • Add automated release validation for tag format, signatures, main-branch ancestry, chart packaging, image versions, and latest-tag selection.

Documentation:

  • Document tag-based release procedures, image tags, repository settings, and Helm image selection behavior.

Tests:

  • Add coverage for Git-derived and fallback package versions, image version propagation, and Helm image/tag resolution.

uniqueg and others added 4 commits October 20, 2026 22:09
Take the package version from Git tags (setuptools-scm). Signed `vX.Y.Z`
tags on `main` trigger a release workflow: it builds and pushes the
image as `X.Y.Z` (and `latest` for the highest release), packages the
Helm chart with version and appVersion from the tag, and creates a
GitHub release with the chart attached, after approval in the `release`
environment. Images from `dev` are tagged `dev` and `sha-<commit>` in
the `dev-images` environment; the date tags and
philips-software/docker-ci-scripts are gone. The chart takes the image
tag from the new value `cloud_registry.tag`, which defaults to the
chart's appVersion.

Closes #81

BREAKING CHANGE: Docker Hub `latest` now points to the latest release,
not to the latest `dev` build; use `dev` or `sha-<commit>` for those.
Date-tagged images are no longer pushed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Scope the release concurrency group per tag, so that a run waiting
  for approval is not cancelled by the run of another tag.
- Decide `latest` in the `publish` job, after approval, from stable
  release tags merged into `main`, so that re-runs of older releases
  and stray tags do not move or freeze it.
- Accept pre-release tags (`vX.Y.ZaN`, `bN`, `rcN`): GitHub
  pre-release, chart version `X.Y.Z-rcN`, never `latest`.
- Check out the commit verified by `prepare` in `publish`.
- Build and load the release image first, check that the app reports
  the release version, then push.
- Pass the version build argument in Docker Compose, and check it in
  the smoke test.
- Pin setuptools-scm for dev image versions in requirements_dev.txt
  (as a constraint), where Dependabot updates it.
- README: tag requirements, pre-releases, environment-only Docker Hub
  secrets and the tag ruleset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Check that the installed package version and the setuptools-scm
fallback version are valid PEP 440 versions. Compare the default image
tag with the chart's appVersion, package charts with pre-release
versions, and cover registries with a port and a tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Build the release image once, check its version, then push exactly
  that image; log in to Docker Hub only after the check.
- Push the version tag first; decide `latest` last, from freshly
  fetched tags on `main`, then push `latest` and pass the same decision
  to the GitHub release (also on reruns).
- Accept canonical versions only (no leading zeros), also when ranking
  stable releases for `latest`.
- Require a signature verified by GitHub (API of the tag object)
  instead of looking for an armored signature block.
- Tests: use `packaging` for PEP 440 versions, check that
  SETUPTOOLS_SCM_PRETEND_VERSION is honoured and that a tag `v1.2.3`
  yields `1.2.3`; cover `a`/`b` pre-release chart versions. Declare
  `packaging` and `tomli` (Python 3.10) in requirements_dev.txt.
- Chart placeholder `version: 0.0.0`; docs: verified signatures, the
  repository settings the workflows rely on, and no release number
  before the first release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

The PR establishes signed Git tags as the single release source, derives package, image, and Helm versions consistently, separates protected dev and release publishing workflows, and updates chart image configuration and documentation for the new lifecycle.

Sequence diagram for the signed tag release workflow

sequenceDiagram
    participant Maintainer
    participant GitHub
    participant Prepare as ReleasePrepare
    participant Approval as ReleaseEnvironment
    participant Publish as ReleasePublish
    participant DockerHub
    participant GitHubRelease

    Maintainer->>GitHub: git push vX.Y.Z
    GitHub->>Prepare: Trigger release workflow
    Prepare->>Prepare: git merge-base --is-ancestor
    Prepare->>GitHub: gh api verification
    Prepare->>Prepare: helm package
    Prepare->>GitHub: Upload chart artifact
    Prepare->>Approval: Request environment approval
    Approval-->>Publish: Approve release
    Publish->>Publish: docker build with SETUPTOOLS_SCM_PRETEND_VERSION
    Publish->>Publish: docker run version check
    Publish->>DockerHub: docker push X.Y.Z
    Publish->>Publish: Determine highest stable release
    opt Highest stable release
        Publish->>DockerHub: docker push latest
    end
    Publish->>GitHubRelease: gh release create with chart
Loading

File-Level Changes

Change Details Files
Moved package and container versioning from committed constants/date tags to Git-tag-derived releases with Docker/build fallbacks.
  • Made setuptools-scm the dynamic version source with a 0.0.0.dev0 fallback and updated documentation version lookup.
  • Added Docker Compose and image-build support for SETUPTOOLS_SCM_PRETEND_VERSION, including runtime version verification.
  • Added tests covering tagged, fallback, and pretend versions.
pyproject.toml
Dockerfile
docker-compose.yaml
requirements_dev.txt
docs/api/conf.py
docs/api/requirements.txt
tests/test_version.py
.github/workflows/checks.yaml
Replaced the previous image publishing mechanism with protected dev-image and signed-tag release workflows.
  • Changed dev merges to publish dev and immutable commit-SHA tags through the dev-images environment, removing date tags and latest publication.
  • Added release preparation checks for canonical annotated, GitHub-verified tags whose commits are on main.
  • Built each release image once, verified its embedded version, pushed the version tag, conditionally updated latest, and created a GitHub release with the packaged chart.
  • Added release concurrency, environment protection, Docker Hub authentication, and repository-setting guidance.
.github/workflows/checks.yaml
.github/workflows/release.yaml
README.md
Made Helm chart image selection release-aware while preserving explicit image tag and digest compatibility.
  • Changed chart metadata to release-populated placeholders with dev as the repository chart appVersion.
  • Added cloud_registry.tag, defaulting to appVersion, and a helper that rejects conflicts with tagged or digested image references.
  • Updated deployment documentation and expanded chart tests for defaults, releases, overrides, and conflicts.
deployment/Chart.yaml
deployment/values.yaml
deployment/values.schema.json
deployment/templates/_helpers.tpl
deployment/templates/cloud-registry-deploy.yaml
deployment/README.md
tests/helm.py
tests/test_chart.py
Updated repository metadata and ignore configuration to support generated release/build artifacts.
  • Adjusted ignored files for the new packaging workflow.
.gitignore

Assessment against linked issues

Issue Objective Addressed Explanation
#81 Use one authoritative version source and keep package, service metadata, documentation, chart release metadata, and the default image tag consistent. ✅
#81 Release from version tags, creating traceable Docker images with release SemVer tags and commit-identifying tags for development images. ✅
#81 Ensure the released chart's appVersion and default image tag match the package and released image version. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (c672828) to head (8d15276).

Additional details and impacted files
@@            Coverage Diff            @@
##               dev      #112   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            9         9           
  Lines          573       573           
=========================================
  Hits           573       573           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

uniqueg and others added 2 commits October 20, 2026 22:44
The Sphinx config read the version from pyproject.toml, which no longer
has one, so the Read the Docs build failed. Derive it with
setuptools-scm instead (the package is not installed for the docs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
They are generated by sphinx-apidoc on each build and were committed by
mistake; ignore them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@uniqueg
uniqueg marked this pull request as ready for review October 20, 2026 20:51

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. The workflow can publish an incorrectly versioned image under a release tag or latest, and the chart now defaults to the mutable dev image. Reverting the change would not remove published tags or release artifacts, nor switch deployments that already pulled the image back.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

uniqueg and others added 2 commits October 20, 2026 23:03
# Conflicts:
#	deployment/Chart.yaml
#	deployment/values.yaml
#	tests/helm.py
#	tests/test_chart.py
With charts released from Git tags (0.3.0 and later) and the
repository chart at 0.0.0, there is no chart version 4. Refer to the
charts 2.x and 3.0.0 as the legacy charts and to the new one as the
current chart, in the upgrade guide, the template comments and the
error messages of the removed `cloud_registry.appName` and of upgrades
of legacy releases, and in the tests that match them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@uniqueg
uniqueg merged commit 2737709 into dev Oct 20, 2026
11 checks passed
@uniqueg
uniqueg deleted the build/release-from-tags branch October 20, 2026 21:39
uniqueg added a commit that referenced this pull request Oct 20, 2026
#112 was squash-merged into dev (2737709); its tree equals the
branch base 8d15276, so conflicts are resolved with this branch's
versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release: single version source, traceable images

1 participant