Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,24 @@ def is_resolve_success(val: ResolveResult) -> TypeGuard[ResolveSuccess]:


def _ref_specificity(ref: str) -> int:
"""Sort key for refs that share a SHA: PR head, then merge-queue, then rest."""
"""Sort key for refs that share a SHA, lowest wins.

PR head, then merge-queue, then a branch, then a tag, then anything else
(e.g. the symbolic ``HEAD`` that ``ls-remote`` lists alongside the branch
it points at — never a useful dist tag on its own). A branch is preferred
over a tag because the SHA path resolves a commit-under-test: the branch
case flags it as a ``head`` so it is built from source, whereas a tag that
happens to point at the same commit would not be.
"""
if ref.startswith("refs/pull/"):
return 0
if re.match(MERGE_QUEUE_REGEX, ref):
return 1
return 2
if ref.startswith("refs/heads/"):
return 2
if ref.startswith("refs/tags/"):
return 3
return 4


def _classify_sha_match(
Expand Down
28 changes: 28 additions & 0 deletions otdf-sdk-mgr/tests/test_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,34 @@ def test_single_match_branch_flagged_head(self):
assert result.get("head") is True
assert result["tag"] == "feature--my-branch"

def test_head_and_branch_prefers_branch(self):
# On a push to main the tip SHA is listed by ls-remote as both the
# symbolic HEAD and refs/heads/main. Prefer the branch so the dist tag
# is "main" (built as a head), not the useless "HEAD".
ls = make_ls_remote(
(SHA40, "HEAD"),
(SHA40, "refs/heads/main"),
)
with patch_git(ls):
result = resolve("go", SHA40, None)
assert is_resolve_success(result)
assert result["tag"] == "main"
assert result.get("head") is True

def test_branch_preferred_over_tag(self):
# A commit-under-test that is both a branch tip and a release tag must
# resolve to the branch so it gets head=True (and a source build),
# rather than a tag that would not be built.
ls = make_ls_remote(
(SHA40, "refs/tags/otdfctl/v0.33.0"),
(SHA40, "refs/heads/main"),
)
with patch_git(ls):
result = resolve("go", SHA40, None)
assert is_resolve_success(result)
assert result["tag"] == "main"
assert result.get("head") is True


# ---------------------------------------------------------------------------
# resolve() — refs/pull/NNN
Expand Down
Loading