Detect non-main default branches in single-branch CI checkouts - #383
Merged
Martin Torp (mtorp) merged 4 commits intoSep 30, 2026
Merged
Conversation
actions/checkout fetches one branch and leaves no origin/HEAD. Since 2.6.6 dropped the git fetch --all that recreated origin/HEAD, default-branch detection fell back to main/master, so scans on repos whose default branch is dev never became the branch head. When origin/HEAD is missing, read the default branch from the GitHub event payload, then from git ls-remote --symref origin HEAD, before the main/master fallback.
Martin Torp (mtorp)
deployed
to
socket-firewall
September 29, 2026 14:12 — with
GitHub Actions
Active
GitPython's kill_after_timeout is rejected on Windows and relies on ps --ppid, which macOS lacks. It also leaves git-remote-https holding the output pipe after the parent dies, so a stalled remote blocked startup past the timeout. Run git ls-remote in its own process group and kill the whole group on timeout, with taskkill /T on Windows.
Martin Torp (mtorp)
deployed
to
socket-firewall
September 29, 2026 14:40 — with
GitHub Actions
Active
GitLab's CI_DEFAULT_BRANCH and Buildkite's BUILDKITE_PIPELINE_DEFAULT_BRANCH only fed the final branch comparison. The commit-on-default check still went to the remote, so single-branch checkouts on those CIs paid for a git ls-remote call even when CI already knew the answer. Both variables now come first in get_default_branch_name. Also simplifies the remote lookup. start_new_session works on every platform because Windows ignores it and taskkill walks the tree by PID. The stalled-remote fixture is now a listener that never accepts, and the test clears proxy variables so it really waits for the timeout.
Martin Torp (mtorp)
deployed
to
socket-firewall
September 29, 2026 14:47 — with
GitHub Actions
Active
Martin Torp (mtorp)
marked this pull request as ready for review
September 29, 2026 14:51
Martin Torp (mtorp)
deployed
to
socket-firewall
September 29, 2026 14:51 — with
GitHub Actions
Active
Contributor
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6a8162a. Configure here.
lelia
approved these changes
Sep 30, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nightly
socketcli --reachscans on repos whose default branch isn'tmainormasterstopped becoming the branch head from 2.6.6 onward. Webflow'sdevanddevelopmentrepos have only shown GitHub App results on the Alerts page since August.Root Cause
#301 removed the
git fetch --allfromGit.__init__. On git 2.48 and later that fetch also createdrefs/remotes/origin/HEADwhen it was missing, and that side effect was the only way the CLI learned the default branch in CI.actions/checkoutfetches a single branch and leaves noorigin/HEAD. Without the fetch,get_default_branch_name()fell back tomain/master/main. SoGITHUB_REF=refs/heads/devnever matched,is_default_branchwas False, and the scan was never made the head. Repos onmainormasterkept working because the fallback guessed right. A plaingit clonealso worked because clone writesorigin/HEAD.Fix
get_default_branch_name()first reads GitLab'sCI_DEFAULT_BRANCHor Buildkite'sBUILDKITE_PIPELINE_DEFAULT_BRANCHwhen set, thenorigin/HEAD. Those two variables used to feed only the final branch comparison, so the commit-on-default check ignored them. When neither gives an answer, it checks, in order:repository.default_branchfrom the GitHub event payload atGITHUB_EVENT_PATH. No network needed.git ls-remote --symref origin HEAD. It's one round trip and downloads no objects, so it does not restore the broad fetch removed in Reduce scan startup time in large repositories #301. It runs withGIT_TERMINAL_PROMPT=0and a 30s timeout. The command runs in its own session, and a timeout kills the whole group (taskkill /Twalks the tree on Windows). That matters because git's HTTP helper otherwise keeps the output pipe open after git itself is killed, which kept startup blocked on a stalled remote.main/masterfallback.Known GitHub, Buildkite, GitLab, and Bitbucket PR/MR runs, plus non-branch GitHub refs, return before default-branch lookup and make no
ls-remotecall. Branch runs use CI metadata,origin/HEAD, and the GitHub event payload before querying the remote. The result is cached, since branch detection can call it twice. Branch names with slashes now resolve correctly fromorigin/HEADtoo.Tests cover an
actions/checkout-style single-branch checkout of adev-default repo; GitHub event metadata and GitLab/Buildkite default-branch variables; no remote default-branch query on GitHub, Buildkite, GitLab, and Bitbucket PR/MR runs; stalled HTTP remote timeout; and Windows process-tree cleanup. All 605 unit tests pass locally.Until this ships, passing
--default-branchon the nightly job works around it.Public Changelog
Fixed default-branch detection for repositories whose default branch isn't
mainormasterwhen scanning from a single-branch CI checkout such asactions/checkout.Fixes CE-482
Note
Medium Risk
Changes when scans become the default-branch head and may run
git ls-remoteduring CLI startup; logic is well-tested but affects core CI git behavior.Overview
Fixes default-branch detection when CI uses shallow single-branch checkouts (e.g.
actions/checkout) withoutorigin/HEAD, so repos whose default is notmain/mastercan mark scans as the branch head again.get_default_branch_name()now caches the result and resolves in order: GitLabCI_DEFAULT_BRANCH/ BuildkiteBUILDKITE_PIPELINE_DEFAULT_BRANCH, thenorigin/HEAD(viaremote_head, including names with slashes), thenrepository.default_branchfrom the GitHub event atGITHUB_EVENT_PATH, then a timedgit ls-remote --symref origin HEAD(30s, kills the process tree on timeout—including Windowstaskkill /T), then the existingmain/masterfallbacks._is_commit_and_branch_default()rejects PR/MR/non-branch refs before any default-branch lookup, and all CI providers now compare againstget_default_branch_name()so the CI default-branch env vars apply to commit-on-default checks too.Release 2.10.6 with changelog and expanded unit tests (single-branch
devcheckout, event payload, stalled remote timeout).Reviewed by Cursor Bugbot for commit 6a8162a. Configure here.