Skip to content

Commit a833bc6

Browse files
fix(versioning): allow prerelease tags in release svt gate (#84)
Co-authored-by: GitHub Copilot Agent <github-actions[bot]@users.noreply.github.com>
1 parent 8d65a52 commit a833bc6

1 file changed

Lines changed: 27 additions & 8 deletions

File tree

tools/ci/check-versioning-svt.sh

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ violations = []
6060
checks = []
6161
require_release_tag = os.environ.get("REQUIRE_RELEASE_TAG", "0") == "1"
6262
expected_release_tag = os.environ.get("EXPECTED_RELEASE_TAG", "").strip()
63+
release_tag_regex = re.compile(r"^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$")
64+
65+
66+
def semver_core(version: str) -> str:
67+
m = re.match(r"^([0-9]+\.[0-9]+\.[0-9]+)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$", version or "")
68+
return m.group(1) if m else ""
6369
6470
6571
def rel(p: Path) -> str:
@@ -118,7 +124,7 @@ try:
118124
raw_tags = subprocess.check_output(["git", "-C", str(repo_root), "tag", "--points-at", "HEAD"], text=True)
119125
for line in raw_tags.splitlines():
120126
t = line.strip()
121-
if re.match(r"^v[0-9]+\.[0-9]+\.[0-9]+$", t):
127+
if release_tag_regex.match(t):
122128
head_tags.append(t)
123129
except Exception as ex:
124130
fail("git.tag_lookup", "command succeeds", "failed", ".git", f"Failed to resolve HEAD tags: {ex}")
@@ -128,8 +134,8 @@ expected_version = ""
128134
# workflow_dispatch releases provide EXPECTED_RELEASE_TAG explicitly.
129135
# tag-push releases derive the expected version from the exact release tag on HEAD.
130136
if expected_release_tag:
131-
if not re.match(r"^v[0-9]+\.[0-9]+\.[0-9]+$", expected_release_tag):
132-
fail("svt.expected_release_tag", "vX.Y.Z", expected_release_tag, "env:EXPECTED_RELEASE_TAG", "Invalid EXPECTED_RELEASE_TAG format")
137+
if not release_tag_regex.match(expected_release_tag):
138+
fail("svt.expected_release_tag", "vX.Y.Z[-prerelease]", expected_release_tag, "env:EXPECTED_RELEASE_TAG", "Invalid EXPECTED_RELEASE_TAG format")
133139
else:
134140
expected_version = expected_release_tag[1:]
135141
checks.append({
@@ -141,9 +147,9 @@ if expected_release_tag:
141147
})
142148
elif len(head_tags) == 0:
143149
if require_release_tag:
144-
fail("svt.head_tag", "exactly one tag vX.Y.Z on HEAD", "none", ".git", "No exact release tag on HEAD")
150+
fail("svt.head_tag", "exactly one tag vX.Y.Z[-prerelease] on HEAD", "none", ".git", "No exact release tag on HEAD")
145151
elif len(head_tags) > 1:
146-
fail("svt.head_tag", "exactly one tag vX.Y.Z on HEAD", ",".join(head_tags), ".git", "Multiple release tags on HEAD")
152+
fail("svt.head_tag", "exactly one tag vX.Y.Z[-prerelease] on HEAD", ",".join(head_tags), ".git", "Multiple release tags on HEAD")
147153
else:
148154
expected_version = head_tags[0][1:]
149155
# --- repo SSOT version consistency (no mixed versions) ---
@@ -179,7 +185,13 @@ else:
179185
fail("repo.ssot.RepoVersion.semver", "X.Y.Z", repo_version, rel(repo_props), "RepoVersion is not semver X.Y.Z")
180186
# if tag defines the release version, RepoVersion must match exactly
181187
if expected_version:
182-
check("repo.ssot.RepoVersion", expected_version, repo_version, rel(repo_props))
188+
expected_core_version = semver_core(expected_version)
189+
if expected_core_version == "":
190+
fail("repo.ssot.RepoVersion.tag.semver", "X.Y.Z[-prerelease]", expected_version, "env:EXPECTED_RELEASE_TAG", "Expected release version is not semver-compatible")
191+
elif "-" in expected_version:
192+
check("repo.ssot.RepoVersion.core", expected_core_version, repo_version, rel(repo_props))
193+
else:
194+
check("repo.ssot.RepoVersion", expected_version, repo_version, rel(repo_props))
183195
184196
check_csproj_uses_repo_version(repo_root / "samples" / "PortableConsumer" / "PortableConsumer.csproj", "PortableConsumerPackageVersion")
185197
check_csproj_uses_repo_version(repo_root / "tests" / "PackageBacked.Tests" / "PackageBacked.Tests.csproj", "PackageBackedVersion")
@@ -210,8 +222,15 @@ if isinstance(project_files, list) and len(project_files) > 0:
210222
check("vbproj.Version_vs_PackageVersion", vbproj_version, vbproj_package_version, rel(project_path))
211223
212224
if expected_version and project_path is not None and project_path.exists():
213-
check("svt.tag_vs_vbproj.Version", expected_version, vbproj_version, rel(project_path))
214-
check("svt.tag_vs_vbproj.PackageVersion", expected_version, vbproj_package_version, rel(project_path))
225+
expected_core_version = semver_core(expected_version)
226+
if expected_core_version == "":
227+
fail("svt.expected_version.semver", "X.Y.Z[-prerelease]", expected_version, "env:EXPECTED_RELEASE_TAG", "Derived expected version is not semver-compatible")
228+
elif "-" in expected_version:
229+
check("svt.tag_core_vs_vbproj.Version", expected_core_version, vbproj_version, rel(project_path))
230+
check("svt.tag_core_vs_vbproj.PackageVersion", expected_core_version, vbproj_package_version, rel(project_path))
231+
else:
232+
check("svt.tag_vs_vbproj.Version", expected_version, vbproj_version, rel(project_path))
233+
check("svt.tag_vs_vbproj.PackageVersion", expected_version, vbproj_package_version, rel(project_path))
215234
216235
nupkg_dir = repo_root / "artifacts" / "nuget"
217236
nupkg_files = sorted([p for p in nupkg_dir.glob("*.nupkg") if not p.name.endswith(".snupkg")])

0 commit comments

Comments
 (0)