11#!/usr/bin/env python3
2+ # force build
23"""
34Breadbox Version Bumping and Publishing Script
45=============================================
2930import re
3031import argparse
3132
32-
33- VERSION_TAG_PATTERN = "breadbox- (\\ d+.\\ d+.\\ d+)"
33+ TAG_PREFIX = "breadbox-"
34+ VERSION_TAG_PATTERN = TAG_PREFIX + " (\\ d+.\\ d+.\\ d+)"
3435IGNORE_CONVENTIONAL_COMMIT_TYPES = ["build" , "chore" , "ci" , "docs" , "style" , "refactor" , "perf" , "test" ]
3536PATCH_CONVENTIONAL_COMMIT_TYPES = ["fix" , "revert" ]
3637MINOR_CONVENTIONAL_COMMIT_TYPES = ["feat" ]
@@ -69,30 +70,24 @@ def main():
6970 print ("Starting version bump process..." )
7071 bump_rules = []
7172
72- last_commit = None
73- last_version = None
74- print ("Analyzing git history for version tags and conventional commits..." )
75- for commit_hash , version , bump_rule , commit_subject in get_sem_versions_and_bumps ():
76- if bump_rule is not None :
77- bump_rules .append ((commit_hash , commit_subject , bump_rule ))
73+ last_version = get_last_sem_version ()
74+ if last_version is None :
75+ raise AssertionError ("No previous version tag found. Cannot proceed without a base version." )
7876
79- if last_commit is None :
80- last_commit = commit_hash
77+ # Create tag name from last version
78+ last_tag = f" { TAG_PREFIX } { '.' . join ( map ( str , last_version )) } "
8179
82- if version is not None :
83- last_version = version
84- print (f"Found version tag: { '.' .join (map (str , version ))} " )
85- break
80+ print (f"Looking at git history starting at { last_tag } for conventional commits..." )
8681
87- if last_version is None :
88- raise AssertionError ( "No previous version tag found. Cannot proceed without a base version." )
82+ for commit_hash , bump_rule , commit_subject in get_bumps ( last_tag ) :
83+ bump_rules . append (( commit_hash , commit_subject , bump_rule ) )
8984
9085 if len (bump_rules ) == 0 :
9186 print (
9287 f"No changes found which require updating version" )
9388 return
9489
95- print (f"Applying { len (bump_rules )} version bump rules, starting with { last_version } to generate version for { last_commit } ... " )
90+ print (f"Applying { len (bump_rules )} version bump rules, starting with { last_version } " )
9691 bump_rules .reverse ()
9792 for commit_hash , commit_subject , bump_rule in bump_rules :
9893 old_version = last_version
@@ -126,8 +121,9 @@ def update_version_in_files(version_str, dryrun=False):
126121 content = file .read ()
127122
128123 # Update version using regex
129- updated_content = re .sub (r'version\s*=\s*"[^"]+"' , f'version = "{ version_str } "' , content )
130-
124+ updated_content = re .sub (r'^version\s*=\s*"[^"]+"$' , f'version = "{ version_str } "' , content , flags = re .MULTILINE )
125+ assert updated_content != content , "Version should have changed, but result after substituting was the same"
126+
131127 # Write updated content back
132128 with open (filename , 'w' ) as file :
133129 file .write (updated_content )
@@ -165,14 +161,14 @@ def update_version_in_files(version_str, dryrun=False):
165161 print (" DRY RUN: Would commit version changes" )
166162
167163def tag_repo (version_str ):
168- tag_name = f"breadbox- { version_str } "
164+ tag_name = f"{ TAG_PREFIX } { version_str } "
169165 print (f" Creating git tag: { tag_name } ..." )
170166 try :
171167 # Create an annotated tag
172168 subprocess .run (["git" , "tag" , "-a" , tag_name , "-m" , f"Release { version_str } " ], check = True )
173169 # Push the tag to remote
174170 print (" Pushing tag to remote..." )
175- subprocess .run (["git" , "push" , "origin" , tag_name ], check = True )
171+ subprocess .run (["git" , "push" , "origin" , tag_name , "master" ], check = True )
176172 except Exception as e :
177173 print (f"Error tagging repository: { str (e )} " )
178174 raise
@@ -186,7 +182,8 @@ def publish():
186182
187183 # Build and publish the package
188184 print (" Building and publishing package..." )
189- subprocess .run (["poetry" , "publish" , "--build" , "--repository" , "public-python" ], check = True )
185+ subprocess .run (["poetry" , "build" ], check = True )
186+ subprocess .run (["poetry" , "publish" , "--repository" , "public-python" ], check = True )
190187 print (" Package published successfully!" )
191188 except Exception as e :
192189 print (f"Error publishing package: { str (e )} " )
@@ -204,36 +201,50 @@ def rule_from_conventional_commit_type(commit_type, is_breaking):
204201 else :
205202 return None
206203
207- def get_sem_versions_and_bumps ():
208- print (" Retrieving git commit history..." )
204+ def get_last_sem_version ():
209205 try :
210- output = subprocess .check_output (
211- ["git" , "log" , "--pretty=format:%H%x09%s%x09%D" ],
206+ # Get all tags
207+ tags_output = subprocess .check_output (
208+ ["git" , "tag" ],
212209 text = True
213- )
210+ ).strip ().split ('\n ' )
211+
212+ # Get highest version from tags
213+ highest_version = to_sem_version (tags_output )
214214 except Exception as e :
215215 print (f"Error retrieving git history: { str (e )} " )
216216 raise
217+ return highest_version
217218
218- for line in output .splitlines ():
219- commit_hash , subject , refs = line .split ("\t " , 2 )
220- tags = [r .strip () for r in refs .split ("," ) if r .strip ().startswith ("tag: " )]
221- tags = [t .replace ("tag: " , "" ) for t in tags ]
222-
223- version = to_sem_version (tags )
219+ def get_bumps (last_tag ):
220+ print (" Retrieving git commit history..." )
221+
222+
223+ # Get commits from HEAD to the last version tag
224+ commit_output = subprocess .check_output (
225+ ["git" , "log" , f"{ last_tag } ..HEAD" , "--pretty=format:%H%x09%s" ],
226+ text = True
227+ )
224228
225- bump_rule = rule_from_conventional_commit (subject )
226- if bump_rule is not None or version is not None :
227- # print(f" Found conventional commit at {commit_hash[:8]}: {subject}")
228- yield commit_hash , version , bump_rule , subject
229+ # Then yield all conventional commits
230+ for line in commit_output .splitlines ():
231+ parts = line .split ("\t " , 1 )
232+ if len (parts ) == 2 :
233+ commit_hash , subject = parts
234+ bump_rule = rule_from_conventional_commit (subject )
235+ if bump_rule is not None :
236+ yield commit_hash , bump_rule , subject
229237
230238def to_sem_version (tags ):
231239 """
232- given a list of tags, extract the semantic version number using VERSION_TAG_PATTERN. If there are multiple, returns the max .
233- If there are no tags or none match, returns None .
240+ Given a list of tags, extract the semantic version numbers using VERSION_TAG_PATTERN.
241+ Returns the highest version found, or None if no valid version tags exist .
234242 """
235243 versions = []
236244 for tag in tags :
245+ if not tag : # Skip empty tags
246+ continue
247+
237248 match = re .match (VERSION_TAG_PATTERN , tag )
238249 if match :
239250 # Extract version number from the tag using regex group
0 commit comments