From f394c8b11386b393523ab2b1bf2798c72600bed4 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Wed, 10 Jun 2026 10:17:23 -0700 Subject: [PATCH] fix(github): resolve latest release via REST API to avoid flaky GraphQL 401 `gh release list` uses GitHub's GraphQL API, which intermittently returns 401 Unauthorized for some organization repositories (~45% failure rate observed for getoutreach/stencil). This caused `github_test.bats` to fail flakily in CI when resolving the latest release tag. Switch `latest_github_release_version` to the equivalent REST endpoint (`gh api repos//releases`), which is unaffected, filtering drafts and pre-releases with the same semantics as before. Assisted-By: claude-opus-4.8 4.8 via opencode --- shell/lib/github.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/shell/lib/github.sh b/shell/lib/github.sh index 5516d4aa..44000ad5 100644 --- a/shell/lib/github.sh +++ b/shell/lib/github.sh @@ -46,16 +46,24 @@ github_token() { } # Determines the latest release version of a GitHub repository. +# +# This uses the REST API rather than `gh release list` because the +# latter relies on GitHub's GraphQL API, which intermittently returns +# 401 Unauthorized for some organization repositories. latest_github_release_version() { local slug="$1" local use_pre_releases="$2" - local gh_args=(--limit 1 --json tagName --jq '.[].tagName' --exclude-drafts) + # Filter out drafts, and pre-releases unless they're requested, then + # print the tag name of the most recent matching release. Releases are + # returned newest-first by the API. + local jq_filter='[.[] | select(.draft == false)' if [[ $use_pre_releases != "true" ]]; then - gh_args+=(--exclude-pre-releases) + jq_filter+=' | select(.prerelease == false)' fi + jq_filter+='] | first | .tag_name // empty' - run_gh release --repo "$slug" list "${gh_args[@]}" + run_gh api "repos/$slug/releases" --jq "$jq_filter" } # install_latest_github_release downloads the latest version of a tool