9
9
def get_current_version () -> str :
10
10
"""Get current version from pyproject.toml."""
11
11
content = Path ("pyproject.toml" ).read_text ()
12
- # More robust regex that matches the project version specifically
13
- # Look for version under [project] or [tool.poetry] sections
14
12
pattern = r'(?:^\[project\]|\[tool\.poetry\])[\s\S]*?^version\s*=\s*"([^"]+)"'
15
13
match = re .search (pattern , content , re .MULTILINE )
16
14
if not match :
@@ -20,7 +18,6 @@ def get_current_version() -> str:
20
18
21
19
def parse_version (version : str ) -> Tuple [int , int , int , Optional [str ]]:
22
20
"""Parse semantic version string."""
23
- # Handle versions with pre-release tags
24
21
match = re .match (r"(\d+)\.(\d+)\.(\d+)(?:-(.+))?" , version )
25
22
if not match :
26
23
raise ValueError (f"Invalid version format: { version } " )
@@ -42,7 +39,6 @@ def bump_version(current: str, bump_type: str) -> str:
42
39
return f"{ major } .{ minor } .{ patch + 1 } "
43
40
elif bump_type == "pre" :
44
41
if pre_release :
45
- # Increment pre-release number
46
42
match = re .match (r"(.+?)(\d+)$" , pre_release )
47
43
if match :
48
44
prefix , num = match .groups ()
@@ -53,19 +49,19 @@ def bump_version(current: str, bump_type: str) -> str:
53
49
54
50
55
51
def update_version_in_file (file_path : Path , old_version : str , new_version : str ) -> bool :
56
- """Update version in a file.
57
-
58
- Note: Currently only bedrock_agentcore/__init__.py contains version.
59
- This function is kept for potential future use.
60
- """
52
+ """Update version in a file."""
61
53
if not file_path .exists ():
62
54
return False
63
55
64
56
content = file_path .read_text ()
65
57
66
- # Only update __version__ assignments, not imports or other references
58
+ # Fix: Use re.sub with a function to avoid group reference issues
67
59
pattern = rf'^(__version__\s*=\s*["\'])({ re .escape (old_version )} )(["\'])'
68
- new_content = re .sub (pattern , rf"\1{ new_version } \3" , content , flags = re .MULTILINE )
60
+
61
+ def replacer (match ):
62
+ return f"{ match .group (1 )} { new_version } { match .group (3 )} "
63
+
64
+ new_content = re .sub (pattern , replacer , content , flags = re .MULTILINE )
69
65
70
66
if new_content != content :
71
67
file_path .write_text (new_content )
@@ -75,51 +71,32 @@ def update_version_in_file(file_path: Path, old_version: str, new_version: str)
75
71
76
72
def update_all_versions (old_version : str , new_version : str ):
77
73
"""Update version in all relevant files."""
78
- # Update pyproject.toml - be specific about which version field
74
+ # Update pyproject.toml - use simple string replacement to avoid regex issues
79
75
pyproject = Path ("pyproject.toml" )
80
76
content = pyproject .read_text ()
81
77
82
- # Only update the version in [project] or [tool.poetry] section
83
- # This prevents accidentally updating version constraints in dependencies
84
- lines = content .split ("\n " )
85
- in_project_section = False
86
- updated_lines = []
87
- version_updated = False
88
-
89
- for line in lines :
90
- if line .strip () == "[project]" or line .strip () == "[tool.poetry]" :
91
- in_project_section = True
92
- elif line .strip ().startswith ("[" ) and line .strip () != "[project]" :
93
- in_project_section = False
94
-
95
- if in_project_section and line .strip ().startswith ("version = " ):
96
- updated_lines .append (f'version = "{ new_version } "' )
97
- version_updated = True
98
- else :
99
- updated_lines .append (line )
78
+ # Simple string replacement instead of regex
79
+ old_version_line = f'version = "{ old_version } "'
80
+ new_version_line = f'version = "{ new_version } "'
100
81
101
- if not version_updated :
102
- raise ValueError ("Failed to update version in pyproject.toml" )
103
-
104
- pyproject .write_text ("\n " .join (updated_lines ))
105
- print ("✓ Updated pyproject.toml" )
82
+ if old_version_line in content :
83
+ content = content .replace (old_version_line , new_version_line , 1 )
84
+ pyproject .write_text (content )
85
+ print ("✓ Updated pyproject.toml" )
86
+ else :
87
+ raise ValueError (f'Could not find version = "{ old_version } " in pyproject.toml' )
106
88
107
89
# Update __init__.py files that contain version
108
- # Currently only bedrock_agentcore/__init__.py has __version__
109
90
init_file = Path ("src/bedrock_agentcore/__init__.py" )
110
91
if init_file .exists () and update_version_in_file (init_file , old_version , new_version ):
111
92
print (f"✓ Updated { init_file } " )
112
93
113
94
114
95
def format_git_log (git_log : str ) -> str :
115
- """Format git log entries for changelog.
116
-
117
- Groups commits by type and formats them nicely.
118
- """
96
+ """Format git log entries for changelog."""
119
97
if not git_log .strip ():
120
98
return ""
121
99
122
- # Parse commit messages
123
100
fixes = []
124
101
features = []
125
102
docs = []
@@ -130,10 +107,8 @@ def format_git_log(git_log: str) -> str:
130
107
if not line or not line .startswith ("-" ):
131
108
continue
132
109
133
- # Remove the leading "- " and extract commit message
134
110
commit_msg = line [2 :].strip ()
135
111
136
- # Categorize by conventional commit type
137
112
if commit_msg .startswith ("fix:" ) or commit_msg .startswith ("bugfix:" ):
138
113
fixes .append (commit_msg )
139
114
elif commit_msg .startswith ("feat:" ) or commit_msg .startswith ("feature:" ):
@@ -143,7 +118,6 @@ def format_git_log(git_log: str) -> str:
143
118
else :
144
119
other .append (commit_msg )
145
120
146
- # Build formatted output
147
121
sections = []
148
122
149
123
if features :
@@ -167,14 +141,12 @@ def get_git_log(since_tag: Optional[str] = None) -> str:
167
141
if since_tag :
168
142
cmd .append (f"{ since_tag } ..HEAD" )
169
143
else :
170
- # Get commits since last tag
171
144
try :
172
145
last_tag = subprocess .run (
173
146
["git" , "describe" , "--tags" , "--abbrev=0" ], capture_output = True , text = True , check = True
174
147
).stdout .strip ()
175
148
cmd .append (f"{ last_tag } ..HEAD" )
176
149
except subprocess .CalledProcessError :
177
- # No tags, get last 20 commits
178
150
cmd .extend (["-n" , "20" ])
179
151
180
152
result = subprocess .run (cmd , capture_output = True , text = True )
@@ -194,20 +166,20 @@ def update_changelog(new_version: str, changes: str = None):
194
166
entry = f"\n ## [{ new_version } ] - { date } \n \n "
195
167
196
168
if changes :
197
- # Use provided changelog
198
169
entry += "### Changes\n \n "
199
170
entry += changes + "\n "
200
171
else :
201
- # Warn about auto-generation
202
172
print ("\n ⚠️ No changelog provided. Auto-generating from commits." )
203
173
print ("💡 Tip: Use --changelog to provide meaningful release notes" )
204
- print (' Example: --changelog "Added new CLI commands for gateway management"' )
205
174
206
175
git_log = get_git_log ()
207
176
if git_log :
208
- entry += "### Changes (auto-generated from commits)\n \n "
209
- entry += git_log + "\n "
210
- entry += "\n *Note: Consider providing a custom changelog for better release notes*\n "
177
+ formatted_log = format_git_log (git_log )
178
+ if formatted_log :
179
+ entry += formatted_log + "\n "
180
+ else :
181
+ entry += "### Changes\n \n "
182
+ entry += git_log + "\n "
211
183
212
184
# Insert after header
213
185
if "# Changelog" in content :
0 commit comments