Skip to content

Commit 792af63

Browse files
author
Alon Yeshurun
committed
Enhance
1 parent 6e58233 commit 792af63

4 files changed

Lines changed: 222 additions & 148 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import os
2+
import re
3+
import subprocess
4+
from collections import defaultdict
5+
6+
# Regex patterns for Conventional Commits
7+
feat_pattern = re.compile(r"^feat(\([^)]+\))?:", re.IGNORECASE)
8+
feat_breaking_pattern = re.compile(r"^feat!|^feat!\([^)]*\):", re.IGNORECASE)
9+
fix_pattern = re.compile(r"^fix(\([^)]+\))?:", re.IGNORECASE)
10+
11+
12+
def get_version_bump_from_commits(last_tag: str | None) -> str | None:
13+
"""
14+
Determines the version bump type ('major', 'minor', 'patch') from commit messages.
15+
"""
16+
try:
17+
if last_tag:
18+
commits = subprocess.check_output(
19+
["git", "log", f"{last_tag}..HEAD", "--merges", "--pretty=format:%B"],
20+
text=True,
21+
).strip()
22+
else:
23+
commits = subprocess.check_output(
24+
["git", "log", "--merges", "--pretty=format:%B"], text=True
25+
).strip()
26+
except Exception as exc:
27+
print(f"Error getting commits: {exc}")
28+
commits = ""
29+
30+
if not commits:
31+
return None
32+
33+
commit_lines = [c.strip() for c in commits.splitlines() if c.strip()]
34+
bump_commits = defaultdict(list)
35+
36+
for c in commit_lines:
37+
if feat_breaking_pattern.match(c):
38+
bump_commits["major"].append(c)
39+
elif feat_pattern.match(c):
40+
bump_commits["minor"].append(c)
41+
elif fix_pattern.match(c):
42+
bump_commits["patch"].append(c)
43+
44+
if bump_commits["major"]:
45+
bump_type = "major"
46+
elif bump_commits["minor"]:
47+
bump_type = "minor"
48+
elif bump_commits["patch"]:
49+
bump_type = "patch"
50+
else:
51+
bump_type = None
52+
53+
print(f"\nVersion bump type from commits: {bump_type}")
54+
for bt in ["major", "minor", "patch"]:
55+
if bump_commits[bt]:
56+
print(f"\n{bt.upper()} commits ({len(bump_commits[bt])}):")
57+
for commit in bump_commits[bt]:
58+
print(f" {commit}")
59+
60+
return bump_type
61+
62+
63+
def main():
64+
"""
65+
Main function to determine version bump part and current version.
66+
"""
67+
# Determine version part
68+
part = os.environ.get("VERSION_PART_INPUT")
69+
if not part:
70+
try:
71+
last_tag = (
72+
subprocess.check_output(["git", "describe", "--tags", "--abbrev=0"])
73+
.decode()
74+
.strip()
75+
)
76+
except subprocess.CalledProcessError as exc:
77+
print(
78+
f"Could not get last tag, probably because there are no tags yet. Error: {exc}"
79+
)
80+
last_tag = None
81+
print(f"Last tag: {last_tag}")
82+
part = get_version_bump_from_commits(last_tag)
83+
else:
84+
print(f"Got version bump part from input: {part}")
85+
86+
# Set outputs
87+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
88+
if part:
89+
f.write(f"part={part}\n")
90+
f.write("bump_needed=true\n")
91+
else:
92+
f.write("bump_needed=false\n")
93+
print("No version bump needed.")
94+
95+
96+
if __name__ == "__main__":
97+
main()
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import os
2+
import re
3+
4+
5+
def increment_version(version, part):
6+
if "rc" in version:
7+
if ".rc" in version:
8+
base_version, rc_part = version.split(".rc")
9+
else:
10+
base_version, rc_part = version.split("rc")
11+
major, minor, patch = map(int, base_version.split("."))
12+
rc_num = int(rc_part)
13+
else:
14+
major, minor, patch = map(int, version.split("."))
15+
rc_num = None
16+
17+
if part == "major":
18+
major += 1
19+
minor = 0
20+
patch = 0
21+
rc_num = None
22+
elif part == "minor":
23+
minor += 1
24+
patch = 0
25+
rc_num = None
26+
elif part == "patch":
27+
patch += 1
28+
rc_num = None
29+
elif part == "rc":
30+
if rc_num is not None:
31+
rc_num += 1
32+
else:
33+
rc_num = 0
34+
elif part == "release":
35+
rc_num = None
36+
else:
37+
raise ValueError(
38+
"Part must be one of 'major', 'minor', 'patch', 'rc', or 'release'"
39+
)
40+
41+
return (
42+
f"{major}.{minor}.{patch}"
43+
if rc_num is None
44+
else f"{major}.{minor}.{patch}.rc{rc_num}"
45+
)
46+
47+
48+
def main():
49+
part = os.environ["PART"]
50+
# Get current version from pyproject.toml
51+
with open("pyproject.toml", "r") as file:
52+
content = file.read()
53+
current_version_match = re.search(
54+
r'version\s*=\s*"(\d+\.\d+\.\d+(?:\.?rc\d+)?)', content
55+
)
56+
if not current_version_match:
57+
raise RuntimeError("Could not find version in pyproject.toml")
58+
current_version = current_version_match.group(1)
59+
new_version = increment_version(current_version, part)
60+
61+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
62+
f.write(f"new_version={new_version}\n")
63+
64+
65+
if __name__ == "__main__":
66+
main()

‎.github/scripts/update_files.py‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import re
3+
4+
5+
def update_file(file_path, old_version, new_version):
6+
with open(file_path, "r") as file:
7+
content = file.read()
8+
9+
# Use word boundaries to avoid replacing parts of other strings
10+
old_version_pattern = r"\b" + re.escape(old_version) + r"\b"
11+
content = re.sub(old_version_pattern, new_version, content)
12+
13+
with open(file_path, "w") as file:
14+
file.write(content)
15+
16+
17+
def main():
18+
files_to_update = [
19+
"pyproject.toml",
20+
"src/fabric_cli/__init__.py",
21+
"src/fabric_cli/core/fab_constant.py",
22+
]
23+
24+
old_version = os.environ["OLD_VERSION"]
25+
new_version = os.environ["NEW_VERSION"]
26+
27+
for file_path in files_to_update:
28+
update_file(file_path, old_version, new_version)
29+
print(f"Updated {file_path} from {old_version} to {new_version}")
30+
31+
32+
if __name__ == "__main__":
33+
main()

0 commit comments

Comments
 (0)