Skip to content

Commit 91e9141

Browse files
Enforce Cargo version sync
Co-authored-by: EvalOpsBot <EvalOpsBot@users.noreply.github.com>
1 parent 92d6698 commit 91e9141

File tree

5 files changed

+119
-2
lines changed

5 files changed

+119
-2
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env python3
2+
3+
from __future__ import annotations
4+
5+
import argparse
6+
import subprocess
7+
import sys
8+
import tomllib
9+
from pathlib import Path
10+
11+
12+
def parse_args() -> argparse.Namespace:
13+
parser = argparse.ArgumentParser(
14+
description="Verify Cargo.toml version is aligned with git tags."
15+
)
16+
parser.add_argument(
17+
"--cargo-toml",
18+
default="Cargo.toml",
19+
help="Path to the Cargo.toml file to validate.",
20+
)
21+
parser.add_argument(
22+
"--tag",
23+
help="Require Cargo.toml to match this exact git tag (for release workflows).",
24+
)
25+
return parser.parse_args()
26+
27+
28+
def normalize_version(raw: str) -> str:
29+
value = raw.strip()
30+
return value[1:] if value.startswith("v") else value
31+
32+
33+
def parse_version(raw: str) -> tuple[int, ...]:
34+
normalized = normalize_version(raw)
35+
parts = normalized.split(".")
36+
if not parts or any(not part.isdigit() for part in parts):
37+
raise ValueError(
38+
f"Unsupported version '{raw}'. Expected dotted numeric versions like 0.5.26."
39+
)
40+
return tuple(int(part) for part in parts)
41+
42+
43+
def read_cargo_version(cargo_toml: Path) -> str:
44+
with cargo_toml.open("rb") as handle:
45+
data = tomllib.load(handle)
46+
try:
47+
return str(data["package"]["version"])
48+
except KeyError as error:
49+
raise KeyError(f"Missing [package].version in {cargo_toml}") from error
50+
51+
52+
def latest_release_tag() -> str | None:
53+
completed = subprocess.run(
54+
["git", "tag", "--list", "v*", "--sort=-v:refname"],
55+
check=True,
56+
capture_output=True,
57+
text=True,
58+
)
59+
for line in completed.stdout.splitlines():
60+
candidate = line.strip()
61+
if candidate:
62+
return candidate
63+
return None
64+
65+
66+
def main() -> int:
67+
args = parse_args()
68+
cargo_toml = Path(args.cargo_toml)
69+
cargo_version = read_cargo_version(cargo_toml)
70+
cargo_tuple = parse_version(cargo_version)
71+
72+
if args.tag:
73+
tag_version = normalize_version(args.tag)
74+
if cargo_version != tag_version:
75+
print(
76+
f"Cargo.toml version {cargo_version} does not match release tag {args.tag}.",
77+
file=sys.stderr,
78+
)
79+
return 1
80+
print(f"Cargo.toml version {cargo_version} matches release tag {args.tag}.")
81+
return 0
82+
83+
latest_tag = latest_release_tag()
84+
if latest_tag is None:
85+
print(f"Cargo.toml version {cargo_version} validated (no release tags found).")
86+
return 0
87+
88+
latest_tuple = parse_version(latest_tag)
89+
if cargo_tuple < latest_tuple:
90+
print(
91+
(
92+
f"Cargo.toml version {cargo_version} is behind the latest tag {latest_tag}. "
93+
"Bump [package].version before merging."
94+
),
95+
file=sys.stderr,
96+
)
97+
return 1
98+
99+
print(
100+
f"Cargo.toml version {cargo_version} is aligned with latest tag {latest_tag}."
101+
)
102+
return 0
103+
104+
105+
if __name__ == "__main__":
106+
raise SystemExit(main())

.github/workflows/ci.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ env:
1010
CARGO_TERM_COLOR: always
1111

1212
jobs:
13+
version:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
- name: Verify Cargo version is not behind tags
20+
run: python3 .github/scripts/check_version_sync.py
21+
1322
lint:
1423
runs-on: ubuntu-latest
1524
steps:

.github/workflows/release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ jobs:
2222
steps:
2323
- name: Checkout code
2424
uses: actions/checkout@v4
25+
- name: Verify Cargo version matches tag
26+
run: python3 .github/scripts/check_version_sync.py --tag "${{ github.ref_name }}"
2527

2628
- name: Extract version
2729
id: get_version

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "diffscope"
3-
version = "0.5.3"
3+
version = "0.5.26"
44
edition = "2021"
55
rust-version = "1.88"
66
authors = ["Jonathan Haas <jonathan@haas.holdings>"]

0 commit comments

Comments
 (0)