Restore v6 development version semantics

This commit is contained in:
rcourtman 2026-04-04 23:02:58 +01:00
parent 7e0f84a40f
commit 283f2e25ae
20 changed files with 323 additions and 29 deletions

View file

@ -66,7 +66,7 @@ PROFILE_PATH_FIELDS = {
"registry_schema",
"subsystem_contract_template",
}
PRERELEASE_VERSION_PATTERN = re.compile(r"-(?:rc|alpha|beta)\.[0-9]+$")
PRERELEASE_VERSION_PATTERN = re.compile(r"-(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)(?:\+[0-9A-Za-z.-]+)?$")
COMPLETION_RULE_BLOCKING_LEVELS = {
"repo_ready": ("repo-ready",),
"rc_ready": ("repo-ready", "rc-ready"),

View file

@ -168,6 +168,7 @@ class ControlPlaneAuditTest(unittest.TestCase):
def test_release_branch_for_version_uses_profile_branch_policy(self) -> None:
self.assertEqual(release_branch_for_version("6.0.0-rc.1", control_plane=VALID_PAYLOAD), "pulse/v6-release")
self.assertEqual(release_branch_for_version("6.0.0-dev", control_plane=VALID_PAYLOAD), "pulse/v6-release")
self.assertEqual(release_branch_for_version("6.0.0", control_plane=VALID_PAYLOAD), "pulse/v6-release")
def test_audit_flags_stale_active_target(self) -> None:

View file

@ -13,7 +13,7 @@ from typing import Callable
from repo_file_io import REPO_ROOT, git_env
SEMVER_PRERELEASE_RE = re.compile(r"-(?:rc|alpha|beta)\.\d+$")
SEMVER_PRERELEASE_RE = re.compile(r"-(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)(?:\+[0-9A-Za-z.-]+)?$")
def normalize_tag(value: str) -> str:

View file

@ -9,6 +9,22 @@ import resolve_release_promotion as resolver
class ResolveReleasePromotionTest(unittest.TestCase):
def test_dev_prerelease_uses_prerelease_path(self) -> None:
metadata = resolver.resolve_metadata(
version="6.0.0-dev",
promoted_from_tag_input="",
rollback_version_input="5.1.14",
ga_date_input="",
v5_eos_date_input="",
hotfix_exception=False,
hotfix_reason_input="",
release_notes_input="",
tag_exists_fn=lambda tag: tag == "v5.1.14",
)
self.assertEqual(metadata["rollback_tag"], "v5.1.14")
self.assertEqual(metadata["promoted_from_tag"], "")
self.assertEqual(metadata["soak_hours"], "")
def test_prerelease_requires_explicit_stable_rollback(self) -> None:
metadata = resolver.resolve_metadata(
version="6.0.0-rc.2",

View file

@ -20,7 +20,7 @@ GA_DATE_RE = re.compile(
V5_EOS_RE = re.compile(
r"existing v5 users until `(?P<v5_eos_date>\[v5-eos-date\]|\d{4}-\d{2}-\d{2})`\."
)
PRERELEASE_RE = re.compile(r"^(?P<stable>\d+\.\d+\.\d+)-(?:rc|alpha|beta)\.\d+$")
PRERELEASE_RE = re.compile(r"^(?P<stable>\d+\.\d+\.\d+)-(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)$")
TAG_LITERAL_RE = re.compile(r"`(v\d+\.\d+\.\d+-rc\.\d+)`")
ACCIDENTAL_RC_TAG_DECISION_ID = "accidental-prerelease-tags-do-not-count-as-shipped-rcs"
RELEASE_DRY_RUN_WORKFLOW = ".github/workflows/release-dry-run.yml"

View file

@ -241,7 +241,7 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
def test_blocked_record_tracks_current_target_and_candidate_version(self) -> None:
blocked = read("docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-blocked-2026-04-04.md")
self.assertIn("origin/pulse/v6-release", blocked)
self.assertIn("VERSION=6.0.0-rc.1", blocked)
self.assertIn("VERSION=6.0.0-dev", blocked)
self.assertIn("artifact-owned candidate stable tag", blocked)
self.assertIn("artifact-owned promotion channel", blocked)
self.assertIn("artifact-owned promoted prerelease tag", blocked)

View file

@ -13,7 +13,7 @@ from typing import Callable
from repo_file_io import REPO_ROOT, git_env
SEMVER_PRERELEASE_RE = re.compile(r"-(?:rc|alpha|beta)\.\d+$")
SEMVER_PRERELEASE_RE = re.compile(r"-(?:[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)(?:\+[0-9A-Za-z.-]+)?$")
def normalize_tag(value: str) -> str:

View file

@ -9,6 +9,22 @@ import resolve_release_promotion as resolver
class ResolveReleasePromotionTest(unittest.TestCase):
def test_dev_prerelease_uses_prerelease_path(self) -> None:
metadata = resolver.resolve_metadata(
version="6.0.0-dev",
promoted_from_tag_input="",
rollback_version_input="5.1.14",
ga_date_input="",
v5_eos_date_input="",
hotfix_exception=False,
hotfix_reason_input="",
release_notes_input="",
tag_exists_fn=lambda tag: tag == "v5.1.14",
)
self.assertEqual(metadata["rollback_tag"], "v5.1.14")
self.assertEqual(metadata["promoted_from_tag"], "")
self.assertEqual(metadata["soak_hours"], "")
def test_prerelease_requires_explicit_stable_rollback(self) -> None:
metadata = resolver.resolve_metadata(
version="6.0.0-rc.2",