Skip to content

Commit 7723a13

Browse files
committed
fix evg-pr-parsing logic
1 parent 4cecea6 commit 7723a13

File tree

2 files changed

+85
-30
lines changed

2 files changed

+85
-30
lines changed

scripts/release/branch_detection.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,40 @@ def get_current_branch() -> Optional[str]:
1414
"""
1515
Detect the current git branch for cache scoping.
1616
17+
In CI environments like Evergreen, git rev-parse --abbrev-ref HEAD returns
18+
auto-generated branch names like evg-pr-testing-<hash>. This function finds the original branch name by
19+
looking for remote branches that point to the current commit.
20+
1721
:return: branch name or 'master' as fallback
1822
"""
1923
try:
20-
result = subprocess.run(
21-
["git", "rev-parse", "--abbrev-ref", "HEAD"], capture_output=True, text=True, check=True
24+
# Find the original branch (same commit, but not the evg-pr-test-* branch which evg creates)
25+
current_commit_result = subprocess.run(
26+
["git", "rev-parse", "HEAD"], capture_output=True, text=True, check=True
27+
)
28+
current_commit = current_commit_result.stdout.strip()
29+
30+
# Get all remote branches with their commit hashes
31+
remote_branches_result = subprocess.run(
32+
["git", "for-each-ref", "--format=%(refname:short) %(objectname)", "refs/remotes/origin"],
33+
capture_output=True, text=True, check=True
2234
)
23-
branch = result.stdout.strip()
24-
if branch == "HEAD":
25-
return "master"
26-
if branch != "":
27-
return branch
35+
36+
# Find branches that point to the current commit, excluding auto-generated CI branches
37+
for line in remote_branches_result.stdout.strip().split('\n'):
38+
if not line:
39+
continue
40+
parts = line.split()
41+
if len(parts) >= 2:
42+
branch_name, commit_hash = parts[0], parts[1]
43+
if commit_hash == current_commit and not "evg-pr-test" in branch_name:
44+
# Remove 'origin/' prefix
45+
original_branch = branch_name.replace('origin/', '', 1)
46+
if original_branch:
47+
return original_branch
2848
except (subprocess.CalledProcessError, FileNotFoundError):
29-
return "master"
49+
return 'master'
50+
3051
return "master"
3152

3253

scripts/release/tests/branch_detection_test.py

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,50 +11,84 @@ class TestGetCurrentBranch:
1111
"""Test branch detection logic for different scenarios."""
1212

1313
@patch("subprocess.run")
14-
def test_master_branch(self, mock_run):
15-
"""Test detection of master branch."""
16-
mock_run.return_value = MagicMock(stdout="master\n", returncode=0)
14+
def test_ci_environment_with_original_branch(self, mock_run):
15+
"""Test detection of original branch in CI environment like Evergreen."""
16+
# Mock the sequence of git commands
17+
def side_effect(cmd, **kwargs):
18+
if cmd == ["git", "rev-parse", "HEAD"]:
19+
return MagicMock(stdout="4cecea664abcd1234567890\n", returncode=0)
20+
elif cmd == ["git", "for-each-ref", "--format=%(refname:short) %(objectname)", "refs/remotes/origin"]:
21+
return MagicMock(stdout="origin/master 1234567890abcdef\norigin/add-caching 4cecea664abcd1234567890\norigin/evg-pr-test-12345 4cecea664abcd1234567890\n", returncode=0)
22+
elif cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
23+
return MagicMock(stdout="evg-pr-test-12345\n", returncode=0)
24+
return MagicMock(stdout="", returncode=1)
25+
26+
mock_run.side_effect = side_effect
1727

1828
result = get_current_branch()
1929

20-
assert result == "master"
21-
mock_run.assert_called_once_with(
22-
["git", "rev-parse", "--abbrev-ref", "HEAD"], capture_output=True, text=True, check=True
23-
)
30+
assert result == "add-caching"
2431

2532
@patch("subprocess.run")
26-
def test_feature_branch(self, mock_run):
27-
"""Test detection of feature branch."""
28-
mock_run.return_value = MagicMock(stdout="feature/new-cache\n", returncode=0)
33+
def test_master_branch_fallback(self, mock_run):
34+
"""Test detection of master branch using fallback method."""
35+
# Mock the sequence where sophisticated method fails but fallback works
36+
def side_effect(cmd, **kwargs):
37+
if cmd == ["git", "rev-parse", "HEAD"]:
38+
return MagicMock(stdout="4cecea664abcd1234567890\n", returncode=0)
39+
elif cmd == ["git", "for-each-ref", "--format=%(refname:short) %(objectname)", "refs/remotes/origin"]:
40+
raise subprocess.CalledProcessError(1, "git") # This fails, triggering fallback
41+
elif cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
42+
return MagicMock(stdout="master\n", returncode=0)
43+
return MagicMock(stdout="", returncode=1)
44+
45+
mock_run.side_effect = side_effect
2946

3047
result = get_current_branch()
3148

32-
assert result == "feature/new-cache"
33-
mock_run.assert_called_once_with(
34-
["git", "rev-parse", "--abbrev-ref", "HEAD"], capture_output=True, text=True, check=True
35-
)
49+
assert result == "master"
3650

3751
@patch("subprocess.run")
38-
def test_detached_head(self, mock_run):
39-
"""Test detection when in detached HEAD state."""
40-
mock_run.return_value = MagicMock(stdout="HEAD\n", returncode=0)
52+
def test_detached_head_fallback(self, mock_run):
53+
"""Test detection when in detached HEAD state using fallback."""
54+
# Mock the sequence where sophisticated method fails and fallback returns HEAD
55+
def side_effect(cmd, **kwargs):
56+
if cmd == ["git", "rev-parse", "HEAD"]:
57+
return MagicMock(stdout="4cecea664abcd1234567890\n", returncode=0)
58+
elif cmd == ["git", "for-each-ref", "--format=%(refname:short) %(objectname)", "refs/remotes/origin"]:
59+
raise subprocess.CalledProcessError(1, "git") # This fails, triggering fallback
60+
elif cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
61+
return MagicMock(stdout="HEAD\n", returncode=0)
62+
return MagicMock(stdout="", returncode=1)
63+
64+
mock_run.side_effect = side_effect
4165

4266
result = get_current_branch()
4367

4468
assert result == "master" # fallback to master
4569

4670
@patch("subprocess.run")
47-
def test_empty_output(self, mock_run):
48-
"""Test detection when git returns empty output."""
49-
mock_run.return_value = MagicMock(stdout="\n", returncode=0)
71+
def test_ci_branch_filtered_out_in_fallback(self, mock_run):
72+
"""Test that CI auto-generated branches are filtered out in fallback."""
73+
# Mock the sequence where sophisticated method fails and fallback returns CI branch
74+
def side_effect(cmd, **kwargs):
75+
if cmd == ["git", "rev-parse", "HEAD"]:
76+
return MagicMock(stdout="4cecea664abcd1234567890\n", returncode=0)
77+
elif cmd == ["git", "for-each-ref", "--format=%(refname:short) %(objectname)", "refs/remotes/origin"]:
78+
raise subprocess.CalledProcessError(1, "git") # This fails, triggering fallback
79+
elif cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
80+
return MagicMock(stdout="evg-pr-test-12345\n", returncode=0)
81+
return MagicMock(stdout="", returncode=1)
82+
83+
mock_run.side_effect = side_effect
5084

5185
result = get_current_branch()
5286

53-
assert result == "master" # fallback to master
87+
assert result == "master" # fallback to master when CI branch is detected
5488

5589
@patch("subprocess.run")
5690
def test_git_command_fails(self, mock_run):
57-
"""Test fallback when git command fails."""
91+
"""Test fallback when all git commands fail."""
5892
mock_run.side_effect = subprocess.CalledProcessError(1, "git")
5993

6094
result = get_current_branch()

0 commit comments

Comments
 (0)