@@ -57,12 +57,13 @@ def get_merge_commit_details(commit_hash):
5757 return []
5858
5959
60- def get_commits_between_releases (last_release , branch ):
61- """Get commits since the last release tag for release notes generation."""
60+ def get_commits_between_releases (last_release , current_tag ):
61+ """Get commits between two tags for release notes generation."""
6262 if last_release :
63- range_spec = f"{ last_release } ..{ branch } "
63+ range_spec = f"{ last_release } ..{ current_tag } "
6464 else :
65- range_spec = branch
65+ # If no previous release, get all commits up to current tag
66+ range_spec = current_tag
6667 print (f"Getting commits for release notes: { range_spec } " )
6768
6869 # Get merge commits with their hashes (these are the important ones in our flow)
@@ -131,29 +132,79 @@ class ReleaseNotes(BaseModel):
131132
132133
133134def get_version_from_version_py () -> str :
134- """Read version from app/core/version.py."""
135+ """Read version from app/core/version.py using regex (avoids import dependencies) ."""
135136 try :
136- from app .core .version import __version__
137-
138- print (f"Read version from app/core/version.py: { __version__ } " )
139- return __version__
140- except ImportError as e :
141- print (f"Error importing version from app.core.version: { e } " )
142- # Fallback: try to read the file directly
143- try :
144- version_path = project_root / "app" / "core" / "version.py"
145- if version_path .exists ():
146- content = version_path .read_text ()
147- match = re .search (r'__version__\s*=\s*"([^"]*)"' , content )
148- if match :
149- version = match .group (1 )
150- print (f"Read version from version.py (regex fallback): { version } " )
151- return version
152- except Exception as e2 :
153- print (f"Error reading version.py: { e2 } " )
137+ version_path = project_root / "app" / "core" / "version.py"
138+ if version_path .exists ():
139+ content = version_path .read_text ()
140+ match = re .search (r'__version__\s*=\s*"([^"]*)"' , content )
141+ if match :
142+ version = match .group (1 )
143+ print (f"Read version from version.py: { version } " )
144+ return version
145+ print ("Warning: version.py not found" )
146+ return "0.0.0"
147+ except Exception as e :
148+ print (f"Error reading version.py: { e } " )
154149 return "0.0.0"
155150
156151
152+ def is_prerelease (version : str ) -> bool :
153+ """Check if version is a pre-release (contains alpha, beta, rc, etc.)."""
154+ prerelease_patterns = [r"alpha" , r"beta" , r"rc" , r"pre" , r"dev" ]
155+ version_lower = version .lower ()
156+ return any (re .search (pattern , version_lower ) for pattern in prerelease_patterns )
157+
158+
159+ def get_all_tags () -> list [str ]:
160+ """Get all tags sorted by version."""
161+ try :
162+ result = subprocess .run (
163+ ["git" , "tag" , "--sort=-version:refname" ],
164+ capture_output = True ,
165+ text = True ,
166+ )
167+ if result .returncode == 0 :
168+ tags = [tag .strip () for tag in result .stdout .strip ().split ("\n " ) if tag .strip ()]
169+ return tags
170+ return []
171+ except Exception as e :
172+ print (f"Error getting tags: { e } " )
173+ return []
174+
175+
176+ def get_previous_release_tag (current_version : str ) -> str | None :
177+ """Get the appropriate previous release tag based on pre-release logic."""
178+ all_tags = get_all_tags ()
179+ current_is_prerelease = is_prerelease (current_version )
180+
181+ if not all_tags :
182+ return None
183+
184+ # Find current tag in the list
185+ try :
186+ current_index = all_tags .index (current_version )
187+ except ValueError :
188+ # Current version not in tags, use the first tag as reference
189+ current_index = 0
190+
191+ # If current is a pre-release, find previous pre-release or stable
192+ # If current is stable, find previous stable (skip pre-releases)
193+ for i in range (current_index + 1 , len (all_tags )):
194+ tag = all_tags [i ]
195+ tag_is_prerelease = is_prerelease (tag )
196+
197+ if current_is_prerelease :
198+ # For pre-releases, include any previous release (stable or pre-release)
199+ return tag
200+ else :
201+ # For stable releases, only include previous stable releases
202+ if not tag_is_prerelease :
203+ return tag
204+
205+ return None
206+
207+
157208def generate_release_notes (commits , last_release_tag ):
158209 prompt = (
159210 "Generate release notes for the given commits. Focus on user-facing changes and important technical"
@@ -246,15 +297,36 @@ def write_to_github_output(name, value):
246297
247298
248299def main ():
249- branch_name = get_current_branch ()
250- print (f"Current Branch Name: { branch_name } " )
251-
252- last_release_tag = get_last_release_tag ()
253- print (f"Latest Release Tag: { last_release_tag } " )
254- commits = get_commits_between_releases (last_release_tag , branch_name )
255-
256- # Read version from version.py (single source of truth)
257- version = get_version_from_version_py ()
300+ # Get current tag from environment (set by GitHub Actions) or from git
301+ current_tag = os .environ .get ("CURRENT_TAG" )
302+ if not current_tag :
303+ # Try to get from git ref
304+ try :
305+ result = subprocess .run (
306+ ["git" , "describe" , "--tags" , "--exact-match" , "HEAD" ],
307+ capture_output = True ,
308+ text = True ,
309+ )
310+ if result .returncode == 0 :
311+ current_tag = result .stdout .strip ()
312+ except Exception :
313+ pass
314+
315+ if not current_tag :
316+ # Fallback: read from version.py
317+ current_tag = get_version_from_version_py ()
318+ print (f"Warning: No tag found, using version from version.py: { current_tag } " )
319+
320+ print (f"Current Tag/Version: { current_tag } " )
321+
322+ # Get the appropriate previous release based on pre-release logic
323+ last_release_tag = get_previous_release_tag (current_tag )
324+ print (f"Previous Release Tag: { last_release_tag } " )
325+
326+ commits = get_commits_between_releases (last_release_tag , current_tag )
327+
328+ # Use current tag as version
329+ version = current_tag
258330
259331 if commits :
260332 print (f"Commits for release notes: { commits } " )
0 commit comments