Skip to content

Commit a1032fe

Browse files
authored
chore(tools): add a script to bump versions (#268)
* Bump version * chore(tools): add a script to bump versions * update * update
1 parent 785d760 commit a1032fe

File tree

5 files changed

+187
-2
lines changed

5 files changed

+187
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.4] - 2025-11-15
9+
10+
### Fixed
11+
- `terraform_plan`: Fixed cases when using `*` as the resource_type and the attribute is not found, the provider outputs `null` insetad of `ProviderError`
812

913
## [1.0.3] - 2025-09-26
1014

Makefile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Makefile for Tirith
2+
3+
.PHONY: help bump-version
4+
5+
help:
6+
@echo "Tirith Development Makefile"
7+
@echo ""
8+
@echo "Available targets:"
9+
@echo " bump-version VERSION=X.Y.Z [TYPE=type] [DESC=description]"
10+
@echo " Bump version to X.Y.Z"
11+
@echo " Optional: TYPE (Added|Changed|Fixed|etc), DESC (description)"
12+
@echo ""
13+
@echo "Examples:"
14+
@echo " make bump-version VERSION=1.0.5"
15+
@echo " make bump-version VERSION=1.0.5 TYPE=Fixed DESC='Bug fix'"
16+
@echo " make bump-version VERSION=1.1.0 TYPE=Added DESC='New feature'"
17+
18+
bump-version:
19+
ifndef VERSION
20+
$(error VERSION is not set. Usage: make bump-version VERSION=X.Y.Z [TYPE=type] [DESC=description])
21+
endif
22+
ifdef TYPE
23+
ifdef DESC
24+
@python3 tools/bump_version.py $(VERSION) --change-type $(TYPE) --description "$(DESC)"
25+
else
26+
$(error If TYPE is set, DESC must also be set)
27+
endif
28+
else
29+
@python3 tools/bump_version.py $(VERSION)
30+
endif

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def read(*names, **kwargs):
2222

2323
setup(
2424
name="py-tirith",
25-
version="1.0.3",
25+
version="1.0.4",
2626
license="Apache",
2727
description="Tirith simplifies defining Policy as Code.",
2828
long_description_content_type="text/markdown",

src/tirith/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
tirith: Execute policies defined using Tirith (StackGuardian Policy Framework)
33
"""
44

5-
__version__ = "1.0.3"
5+
__version__ = "1.0.4"
66
__author__ = "StackGuardian"
77
__license__ = "Apache"

tools/bump_version.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Version Bump Script for Tirith
4+
5+
This script automatically bumps the version in all necessary files:
6+
- setup.py
7+
- src/tirith/__init__.py
8+
- CHANGELOG.md
9+
10+
Usage:
11+
python bump_version.py <new_version> [--change-type TYPE] [--description DESC]
12+
13+
Examples:
14+
python bump_version.py 1.0.5 --change-type Fixed --description "Bug fix for provider"
15+
python bump_version.py 1.1.0 --change-type Added --description "New feature"
16+
17+
"""
18+
19+
import re
20+
import sys
21+
import argparse
22+
from datetime import date
23+
from pathlib import Path
24+
25+
26+
class VersionBumper:
27+
def __init__(self, root_dir=None):
28+
# If no root_dir provided, use parent directory of the script (project root)
29+
self.root_dir = Path(root_dir) if root_dir else Path(__file__).parent.parent
30+
self.setup_py = self.root_dir / "setup.py"
31+
self.init_py = self.root_dir / "src" / "tirith" / "__init__.py"
32+
self.changelog = self.root_dir / "CHANGELOG.md"
33+
34+
def get_current_version(self):
35+
"""Extract current version from setup.py"""
36+
content = self.setup_py.read_text()
37+
match = re.search(r'version="([^"]+)"', content)
38+
if match:
39+
return match.group(1)
40+
raise ValueError("Could not find version in setup.py")
41+
42+
def validate_version(self, version):
43+
"""Validate version format (semantic versioning)"""
44+
pattern = r"^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$"
45+
if not re.match(pattern, version):
46+
raise ValueError(f"Invalid version format: {version}. Expected format: X.Y.Z or X.Y.Z-beta.N")
47+
return True
48+
49+
def update_setup_py(self, new_version):
50+
"""Update version in setup.py"""
51+
content = self.setup_py.read_text()
52+
updated = re.sub(r'version="[^"]+"', f'version="{new_version}"', content)
53+
self.setup_py.write_text(updated)
54+
print(f"✓ Updated {self.setup_py.relative_to(self.root_dir)}")
55+
56+
def update_init_py(self, new_version):
57+
"""Update version in src/tirith/__init__.py"""
58+
content = self.init_py.read_text()
59+
updated = re.sub(r'__version__ = "[^"]+"', f'__version__ = "{new_version}"', content)
60+
self.init_py.write_text(updated)
61+
print(f"✓ Updated {self.init_py.relative_to(self.root_dir)}")
62+
63+
def update_changelog(self, new_version, change_type=None, description=None):
64+
"""Add new version entry to CHANGELOG.md"""
65+
content = self.changelog.read_text()
66+
today = date.today().strftime("%Y-%m-%d")
67+
68+
# Find the position after the header
69+
header_end = content.find("## [")
70+
if header_end == -1:
71+
raise ValueError("Could not find version entries in CHANGELOG.md")
72+
73+
# Create new version entry
74+
new_entry = f"\n## [{new_version}] - {today}\n\n"
75+
76+
if change_type and description:
77+
new_entry += f"### {change_type}\n- {description}\n"
78+
else:
79+
new_entry += "### Changed\n- Version bump\n"
80+
81+
# Insert the new entry
82+
updated = content[:header_end] + new_entry + "\n" + content[header_end:]
83+
self.changelog.write_text(updated)
84+
print(f"✓ Updated {self.changelog.relative_to(self.root_dir)}")
85+
86+
def bump_version(self, new_version, change_type=None, description=None):
87+
"""Bump version in all files"""
88+
# Validate version format
89+
self.validate_version(new_version)
90+
91+
# Get current version
92+
current_version = self.get_current_version()
93+
print(f"Current version: {current_version}")
94+
print(f"New version: {new_version}\n")
95+
96+
# Update all files
97+
self.update_setup_py(new_version)
98+
self.update_init_py(new_version)
99+
self.update_changelog(new_version, change_type, description)
100+
101+
print(f"\n✓ Successfully bumped version from {current_version} to {new_version}")
102+
print("\nNext steps:")
103+
print("1. Review the changes")
104+
print("2. Commit with: git add -A && git commit -m 'Bump version'")
105+
print("3. Create a tag: git tag -a v{} -m 'Release v{}'".format(new_version, new_version))
106+
print("4. Push: git push && git push --tags")
107+
108+
109+
def main():
110+
parser = argparse.ArgumentParser(
111+
description="Bump version for Tirith project",
112+
formatter_class=argparse.RawDescriptionHelpFormatter,
113+
epilog="""
114+
Examples:
115+
%(prog)s 1.0.5
116+
%(prog)s 1.0.5 --change-type Fixed --description "Bug fix for provider"
117+
%(prog)s 1.1.0 --change-type Added --description "New feature X"
118+
%(prog)s 2.0.0-beta.1 --change-type Added --description "Beta release"
119+
120+
Change types:
121+
Added, Changed, Deprecated, Removed, Fixed, Security
122+
""",
123+
)
124+
125+
parser.add_argument("version", help="New version number (e.g., 1.0.5, 1.1.0, 2.0.0-beta.1)")
126+
127+
parser.add_argument(
128+
"--change-type",
129+
"-t",
130+
choices=["Added", "Changed", "Deprecated", "Removed", "Fixed", "Security"],
131+
help="Type of change (for CHANGELOG.md)",
132+
)
133+
134+
parser.add_argument("--description", "-d", help="Description of changes (for CHANGELOG.md)")
135+
136+
args = parser.parse_args()
137+
138+
# If one of change-type or description is provided, both must be provided
139+
if (args.change_type or args.description) and not (args.change_type and args.description):
140+
parser.error("--change-type and --description must be used together")
141+
142+
try:
143+
bumper = VersionBumper()
144+
bumper.bump_version(args.version, args.change_type, args.description)
145+
except Exception as e:
146+
print(f"Error: {e}", file=sys.stderr)
147+
sys.exit(1)
148+
149+
150+
if __name__ == "__main__":
151+
main()

0 commit comments

Comments
 (0)