From 938a20663df31ff447891e9a28c54edc85c2be65 Mon Sep 17 00:00:00 2001 From: MickLesk Date: Mon, 4 May 2026 16:43:19 +0200 Subject: [PATCH] fix(tools): get_latest_gh_tag - use matching-refs API for prefix filtering The /tags endpoint sorts tags by an undocumented order, not by date or semver. For repos with many tag families (e.g. mongodb/mongo-tools has r4.x and 100.x tags), the prefixed ones may not appear in the first 100 results. Using /git/matching-refs/tags/ gets ALL matching tags in a single API call, then 'sort -V' picks the highest version. --- misc/tools.func | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/misc/tools.func b/misc/tools.func index da0f954a3..c8c2f15c1 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -2079,15 +2079,33 @@ get_latest_gh_tag() { local temp_file temp_file=$(mktemp) - if ! github_api_call "https://api.github.com/repos/${repo}/tags?per_page=50" "$temp_file"; then - rm -f "$temp_file" - return 22 - fi - local tag="" + if [[ -n "$prefix" ]]; then - tag=$(jq -r --arg p "$prefix" '[.[] | select(.name | startswith($p))][0].name // empty' "$temp_file") + # Use git/matching-refs API for server-side prefix filtering. This avoids + # paging through unrelated tags (e.g. mongodb/mongo-tools where 100.x tags + # only appear after page 4 of /tags). Returns ALL tags matching the prefix + # in a single call, sorted lexicographically ascending; we pick the + # highest version using `sort -V`. + if ! github_api_call "https://api.github.com/repos/${repo}/git/matching-refs/tags/${prefix}" "$temp_file"; then + rm -f "$temp_file" + return 22 + fi + + local count + count=$(jq 'length' "$temp_file" 2>/dev/null || echo 0) + if [[ "$count" -gt 0 ]]; then + tag=$(jq -r '.[].ref' "$temp_file" \ + | sed 's|^refs/tags/||' \ + | sort -V \ + | tail -n1) + fi else + # No prefix: just take the first (newest) tag from /tags + if ! github_api_call "https://api.github.com/repos/${repo}/tags?per_page=1" "$temp_file"; then + rm -f "$temp_file" + return 22 + fi tag=$(jq -r '.[0].name // empty' "$temp_file") fi