From e09fd831c3622170ce07f214f1b9b3613a209856 Mon Sep 17 00:00:00 2001 From: rabii-chaarani Date: Thu, 28 May 2026 15:13:54 +0930 Subject: [PATCH] fix(release): enforce strict semver release tags Release-please was deriving component-prefixed tags from the configured package name, while the production workflow intentionally accepts only vX.Y.Z tags. Disable component inclusion in generated tags and document the strict tag contract so the release workflow and release tool agree. Constraint: Production release tags must remain strict vX.Y.Z. Rejected: Relax the workflow regex to accept codebase-graph-vX.Y.Z | user explicitly required strict vX.Y.Z tags. Confidence: high Scope-risk: narrow Directive: Do not re-enable component-prefixed tags unless the production release gate is intentionally changed too. Tested: .venv/bin/python -m pytest tests/test_release_workflows.py -q Tested: .venv/bin/ruff check tests/test_release_workflows.py Tested: .venv/bin/python scripts/check_release_gate.py Tested: .venv/bin/ruff check . Tested: .venv/bin/python -m pytest -q Not-tested: Remote release recovery for the already-created codebase-graph-v0.1.0 tag. --- docs/release.md | 3 ++- release-please-config.json | 1 + tests/test_release_workflows.py | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/release.md b/docs/release.md index 86c8d00..5343e2c 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,6 +1,6 @@ # Release Process -`codebaseGraph` releases are managed by release-please. The release workflow opens and maintains a release pull request from Conventional Commit history. When that release pull request is merged, release-please creates the `vX.Y.Z` tag and GitHub Release, then the same workflow builds the source distribution and wheel from that tag, verifies that the package metadata version matches the tag, attaches the distributions to the GitHub Release, and publishes to PyPI with Trusted Publishing. +`codebaseGraph` releases are managed by release-please. The release workflow opens and maintains a release pull request from Conventional Commit history. When that release pull request is merged, release-please creates the strict `vX.Y.Z` tag and GitHub Release, then the same workflow builds the source distribution and wheel from that tag, verifies that the package metadata version matches the tag, attaches the distributions to the GitHub Release, and publishes to PyPI with Trusted Publishing. ## One-time PyPI setup @@ -72,6 +72,7 @@ fail on known vulnerable dependencies. Local setup stays offline-safe and must n implicitly; run local advisory scans explicitly when that disclosure is acceptable. The package version remains tag-derived through `setuptools_scm`; do not add a static `project.version` field to `pyproject.toml` just for release-please. +The release-please config intentionally disables component-prefixed tags so production releases stay in strict `vX.Y.Z` format. To force a specific next version, merge a commit whose body contains a `Release-As: X.Y.Z` trailer. diff --git a/release-please-config.json b/release-please-config.json index 5495177..6532d69 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -4,6 +4,7 @@ "release-type": "python", "package-name": "codebase-graph", "include-v-in-tag": true, + "include-component-in-tag": false, "changelog-path": "CHANGELOG.md" } } diff --git a/tests/test_release_workflows.py b/tests/test_release_workflows.py index 5bb7e59..370e62f 100644 --- a/tests/test_release_workflows.py +++ b/tests/test_release_workflows.py @@ -1,5 +1,6 @@ from __future__ import annotations +import json import re from pathlib import Path @@ -76,6 +77,16 @@ def test_release_please_is_skipped_during_pypi_environment_smoke() -> None: assert "release-please:\n name: release please\n if: ${{ !inputs.pypi-environment-smoke }}" in text +def test_release_please_uses_strict_semver_tags() -> None: + config = json.loads(Path("release-please-config.json").read_text(encoding="utf-8")) + root_package = config["packages"]["."] + + assert root_package["include-v-in-tag"] is True + assert root_package["include-component-in-tag"] is False + assert "release tag must match vX.Y.Z" in Path(".github/workflows/release.yml").read_text(encoding="utf-8") + assert "component-prefixed tags" in Path("docs/release.md").read_text(encoding="utf-8") + + def test_conda_recipe_uses_bounded_runtime_dependencies() -> None: text = Path("conda-forge/recipe/meta.yaml").read_text(encoding="utf-8")