Skip to content

Commit 08ae191

Browse files
committed
Use actual repo (peeled) commits instead of annotated tag hashes
1 parent 170c204 commit 08ae191

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

release-automation/src/stackbrew_generator/git_operations.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def list_remote_tags(self, major_version: int) -> List[Tuple[str, str]]:
6767
console.print(f"[dim]Listing remote tags for v{major_version}.*[/dim]")
6868

6969
cmd = [
70-
"git", "ls-remote", "--refs", "--tags",
70+
"git", "ls-remote", "--tags",
7171
self.remote, f"refs/tags/v{major_version}.*"
7272
]
7373

@@ -76,11 +76,28 @@ def list_remote_tags(self, major_version: int) -> List[Tuple[str, str]]:
7676
if not result.stdout.strip():
7777
raise GitOperationError(f"No tags found for major version {major_version}")
7878

79-
tags = []
79+
tag_commits = {}
80+
81+
# always use peeled commits for annotated tags
82+
# for annotated tags git ls-remote prints tag object hash, then actual commit hash with ^{} suffix
83+
# https://stackoverflow.com/a/25996877
8084
for line in result.stdout.strip().split('\n'):
8185
if line:
8286
commit, ref = line.split('\t', 1)
83-
tags.append((commit, ref))
87+
if ref.endswith('^{}'):
88+
# This is a peeled ref - extract the tag name
89+
# always rewrite tag commits with peeled ref commits
90+
tag_name = ref[:-3] # Remove '^{}'
91+
tag_commits[tag_name] = commit
92+
else:
93+
# This is a regular tag
94+
# rewrite only if not yet exists
95+
if ref not in tag_commits:
96+
tag_commits[ref] = commit
97+
98+
tags = []
99+
for tag_ref, commit in tag_commits.items():
100+
tags.append((commit, tag_ref))
84101

85102
console.print(f"[dim]Found {len(tags)} tags[/dim]")
86103
return tags
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Tests for git operations."""
2+
3+
from unittest.mock import Mock, patch
4+
5+
from stackbrew_generator.git_operations import GitClient
6+
7+
8+
class TestGitClient:
9+
"""Tests for GitClient class."""
10+
11+
@patch('stackbrew_generator.git_operations.console')
12+
@patch.object(GitClient, '_run_command')
13+
def test_list_remote_tags(self, mock_run_command, mock_console):
14+
"""
15+
Test that list_remote_tags returns the expected format for peeled refs.
16+
17+
For tags with ^{} suffix, use the commit hash from that line.
18+
For tags without ^{} suffix, use the commit hash from the tag line.
19+
"""
20+
mock_result = Mock()
21+
mock_result.stdout = """101262a8cf05b98137d88bc17e77db90c24cc783\trefs/tags/v8.0.3
22+
2277e5ead99f0caacbd90e0d04693adb27ebfaa6\trefs/tags/v8.0.4^{}
23+
c0125f5be8786d556a9d3edd70f51974fe045c1a\trefs/tags/v8.0.4
24+
f76d8a1cc979be6202aed93efddd2a0ebbfa0209\trefs/tags/v8.2.2
25+
c5846c13383c8b284897ff171e0c946868ed4c8c\trefs/tags/v8.2.2^{}"""
26+
mock_run_command.return_value = mock_result
27+
28+
client = GitClient()
29+
result = client.list_remote_tags(8)
30+
31+
# Expected behavior:
32+
# - v8.0.3 has no peeled ref, so use the tag commit
33+
# - v8.0.4 has a peeled ref, so use the peeled commit (2277e5ead99f0caacbd90e0d04693adb27ebfaa6)
34+
# - v8.2.2 has a peeled ref, so use the peeled commit (c5846c13383c8b284897ff171e0c946868ed4c8c)
35+
expected_result = [
36+
("101262a8cf05b98137d88bc17e77db90c24cc783", "refs/tags/v8.0.3"), # No peeled ref
37+
("2277e5ead99f0caacbd90e0d04693adb27ebfaa6", "refs/tags/v8.0.4"), # Use peeled ref
38+
("c5846c13383c8b284897ff171e0c946868ed4c8c", "refs/tags/v8.2.2") # Use peeled ref
39+
]
40+
41+
assert result == expected_result

0 commit comments

Comments
 (0)