Skip to content

Commit 6a8162a

Browse files
authored
Avoid remote default-branch lookup for PR builds
1 parent a8523f8 commit 6a8162a

2 files changed

Lines changed: 46 additions & 35 deletions

File tree

‎socketsecurity/core/git_interface.py‎

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -414,28 +414,45 @@ def _is_commit_and_branch_default(self) -> bool:
414414
True if commit is on default branch and we're processing the default branch
415415
"""
416416
try:
417-
# First check if the commit is reachable from the default branch
418-
if not self.is_commit_on_default_branch():
419-
log.debug("Commit is not on default branch")
420-
return False
421-
422-
# Check if we're processing the default branch via CI environment variables
423417
github_ref = os.getenv('GITHUB_REF') # e.g., 'refs/heads/main' or 'refs/pull/123/merge'
424418
gitlab_branch = os.getenv('CI_COMMIT_BRANCH')
425419
gitlab_mr_branch = os.getenv('CI_MERGE_REQUEST_SOURCE_BRANCH_NAME')
426420
bitbucket_branch = os.getenv('BITBUCKET_BRANCH')
421+
bitbucket_pr = os.getenv('BITBUCKET_PR_ID')
427422
buildkite_branch = os.getenv('BUILDKITE_BRANCH')
428423
buildkite_pr = os.getenv('BUILDKITE_PULL_REQUEST')
429424

430-
# Handle Buildkite before GitHub because some Buildkite pipelines
431-
# intentionally provide GitHub-compatible environment variables.
425+
# PR and non-branch builds cannot become the default branch head.
426+
# Decide that locally before default-branch lookup contacts origin.
432427
if buildkite_branch:
433428
if self._is_buildkite_pull_request(buildkite_pr):
434429
log.debug(
435430
f"Processing Buildkite pull request from branch: {buildkite_branch}, "
436431
"not default branch"
437432
)
438433
return False
434+
elif github_ref:
435+
if github_ref.startswith('refs/pull/'):
436+
log.debug("Processing a pull request, not default branch")
437+
return False
438+
if not github_ref.startswith('refs/heads/'):
439+
log.debug(f"Non-branch ref: {github_ref}, not default branch")
440+
return False
441+
elif gitlab_branch or gitlab_mr_branch:
442+
if gitlab_mr_branch:
443+
log.debug(f"Processing GitLab MR from branch: {gitlab_mr_branch}, not default branch")
444+
return False
445+
elif bitbucket_branch and bitbucket_pr:
446+
log.debug(f"Processing Bitbucket pull request from branch: {bitbucket_branch}, not default branch")
447+
return False
448+
449+
if not self.is_commit_on_default_branch():
450+
log.debug("Commit is not on default branch")
451+
return False
452+
453+
# Handle Buildkite before GitHub because some Buildkite pipelines
454+
# intentionally provide GitHub-compatible environment variables.
455+
if buildkite_branch:
439456
default_branch_name = self.get_default_branch_name()
440457
is_default = buildkite_branch == default_branch_name
441458
log.debug(
@@ -447,35 +464,16 @@ def _is_commit_and_branch_default(self) -> bool:
447464
# Handle GitHub Actions
448465
elif github_ref:
449466
log.debug(f"GitHub ref: {github_ref}")
450-
451-
# Handle pull requests - they're not on the default branch
452-
if github_ref.startswith('refs/pull/'):
453-
log.debug("Processing a pull request, not default branch")
454-
return False
455-
456-
# Handle regular branch pushes
457-
if github_ref.startswith('refs/heads/'):
458-
branch_from_ref = github_ref.replace('refs/heads/', '')
459-
default_branch_name = self.get_default_branch_name()
460-
is_default = branch_from_ref == default_branch_name
461-
log.debug(f"Branch from GITHUB_REF: {branch_from_ref}, Default: {default_branch_name}, Is default: {is_default}")
462-
return is_default
463-
464-
# Handle tags or other refs - not default branch
465-
log.debug(f"Non-branch ref: {github_ref}, not default branch")
466-
return False
467+
branch_from_ref = github_ref.removeprefix('refs/heads/')
468+
default_branch_name = self.get_default_branch_name()
469+
is_default = branch_from_ref == default_branch_name
470+
log.debug(f"Branch from GITHUB_REF: {branch_from_ref}, Default: {default_branch_name}, Is default: {is_default}")
471+
return is_default
467472

468473
# Handle GitLab CI
469474
elif gitlab_branch or gitlab_mr_branch:
470-
# If this is a merge request, use the source branch
471475
current_branch = gitlab_mr_branch or gitlab_branch
472476
default_branch_name = self.get_default_branch_name()
473-
474-
# For merge requests, they're typically not considered "default branch"
475-
if gitlab_mr_branch:
476-
log.debug(f"Processing GitLab MR from branch: {gitlab_mr_branch}, not default branch")
477-
return False
478-
479477
is_default = current_branch == default_branch_name
480478
log.debug(f"GitLab branch: {current_branch}, Default: {default_branch_name}, Is default: {is_default}")
481479
return is_default

‎tests/unit/test_git_interface.py‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ def test_pull_request_context_uses_local_refs_without_fetch(
132132
"_fetch_ref",
133133
side_effect=AssertionError("unexpected fetch"),
134134
)
135+
remote_lookup = mocker.patch.object(
136+
Git,
137+
"_default_branch_from_remote",
138+
side_effect=AssertionError("unexpected remote default-branch lookup"),
139+
)
135140
mocker.patch.object(Git, "ensure_safe_directory")
136141

137142
with caplog.at_level(logging.INFO, logger="socketdev"):
@@ -141,6 +146,7 @@ def test_pull_request_context_uses_local_refs_without_fetch(
141146
assert repository.changed_files == ["package.json"]
142147
assert repository.is_default_branch is False
143148
fetch.assert_not_called()
149+
remote_lookup.assert_not_called()
144150
assert any(
145151
f"source={expected_source}" in record.message
146152
for record in caplog.records
@@ -433,11 +439,18 @@ def test_github_event_payload_supplies_default_branch(
433439
remote_lookup.assert_not_called()
434440

435441

442+
@pytest.mark.parametrize(
443+
("branch_variable", "default_variable"),
444+
[
445+
("CI_COMMIT_BRANCH", "CI_DEFAULT_BRANCH"),
446+
("BUILDKITE_BRANCH", "BUILDKITE_PIPELINE_DEFAULT_BRANCH"),
447+
],
448+
)
436449
def test_ci_default_branch_variable_skips_remote_lookup(
437-
single_branch_checkout, monkeypatch, mocker
450+
single_branch_checkout, monkeypatch, mocker, branch_variable, default_variable
438451
):
439-
monkeypatch.setenv("CI_COMMIT_BRANCH", "dev")
440-
monkeypatch.setenv("CI_DEFAULT_BRANCH", "dev")
452+
monkeypatch.setenv(branch_variable, "dev")
453+
monkeypatch.setenv(default_variable, "dev")
441454
mocker.patch.object(Git, "ensure_safe_directory")
442455
remote_lookup = mocker.patch.object(Git, "_default_branch_from_remote")
443456

0 commit comments

Comments
 (0)