From 4d3789bd52a21fd16c4f6e539805061c8976d5bb Mon Sep 17 00:00:00 2001 From: MickLesk <47820557+MickLesk@users.noreply.github.com> Date: Thu, 12 Nov 2026 16:40:09 +0100 Subject: [PATCH 1/2] Find a pinned tag whether or not it is written with its v var_appversion=0.35.11 for a repo tagged v0.35.11 (TrailBase) asked for releases/tags/0.35.11, got a 404, retried it twice more and aborted. The lookup of a pinned tag now asks once more with the other spelling (v added or removed) and stops on a second 404 instead of retrying it. --- .github/workflows/verify-split-files.yml | 4 ++ lib/forge.func | 13 +++- tests/forge-tag-spelling.sh | 78 ++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 tests/forge-tag-spelling.sh diff --git a/.github/workflows/verify-split-files.yml b/.github/workflows/verify-split-files.yml index 361c586..9823dca 100644 --- a/.github/workflows/verify-split-files.yml +++ b/.github/workflows/verify-split-files.yml @@ -70,6 +70,7 @@ on: - "tests/vm-dialog-esc.sh" - "tests/forge-clean-install.sh" - "tests/db-helper-context.sh" + - "tests/forge-tag-spelling.sh" - "tests/cs-clear.sh" - "tests/forge-appversion-scope.sh" - "tests/forge-singlefile-compressed.sh" @@ -139,6 +140,7 @@ on: - "tests/vm-dialog-esc.sh" - "tests/forge-clean-install.sh" - "tests/db-helper-context.sh" + - "tests/forge-tag-spelling.sh" - "tests/cs-clear.sh" - "tests/forge-appversion-scope.sh" - "tests/forge-singlefile-compressed.sh" @@ -297,6 +299,8 @@ jobs: run: bash tests/forge-clean-install.sh - name: Database helpers outside an install tests run: bash tests/db-helper-context.sh + - name: Pinned tag with or without its v tests + run: bash tests/forge-tag-spelling.sh - name: Screen clear without a terminal tests run: bash tests/cs-clear.sh - name: App version pin and .deb stamp tests diff --git a/lib/forge.func b/lib/forge.func index 6f6a67e..72737d6 100644 --- a/lib/forge.func +++ b/lib/forge.func @@ -1699,7 +1699,7 @@ _forge_release_json() { fi local -a timeouts=(60 120 240) - local raw attempt=1 delay=2 code ok=false curl_rc + local raw attempt=1 delay=2 code ok=false curl_rc other_spelling="" raw="$(mktemp /tmp/tools-forge-rel-XXXXXX)" || return 73 [[ "$forge" == "github" ]] && _github_token_from_vars @@ -1787,6 +1787,17 @@ _forge_release_json() { return 22 fi + # A pinned tag written without the repo's v (var_appversion=0.35.11 for + # v0.35.11), or with one it does not use: ask once for the other spelling. + # A tag that is missing either way does not appear by retrying. + if [[ "$single" == "true" && "$code" == "404" ]]; then + [[ -n "$other_spelling" ]] && break + other_spelling="v${version}" + [[ "$version" == v* ]] && other_spelling="${version#v}" + api_url="${base}/${repo_path}${one}/${other_spelling//\//%2F}" + continue + fi + attempt=$((attempt + 1)) done diff --git a/tests/forge-tag-spelling.sh b/tests/forge-tag-spelling.sh new file mode 100644 index 0000000..962c9c5 --- /dev/null +++ b/tests/forge-tag-spelling.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -uo pipefail + +CORE_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" +eval "$(sed -n '/^_FORGE_JQ_VKEY_DEF=/,/^_FORGE_JQ_VKEY=/p' "$CORE_DIR/lib/forge.func")" +eval "$(awk '/^_forge_(descriptor|curl|designated_release|stable_filter|keep_raw|release_json|explain_failure|require_jq)[(][)] [{]/,/^}/' "$CORE_DIR/lib/forge.func")" + +TEST_DIR="$(mktemp -d)" +trap 'rm -rf -- "$TEST_DIR" "${TOOLS_GH_REL_JSON:-}"' EXIT +CALLS="$TEST_DIR/calls" +LOG="$TEST_DIR/log" +OUT="$TEST_DIR/out" +passed=0 failed=0 + +msg_info() { :; } +msg_ok() { :; } +msg_warn() { echo "warn: $*" >>"$LOG"; } +msg_error() { echo "error: $*" >>"$LOG"; } +getent() { return 0; } +sleep() { :; } +_github_release_noapi() { return 1; } +ensure_dependencies() { :; } +# Only the tags listed in TAGS exist; everything else is a 404. +curl() { + local out="" url="" i tag + local -a args=("$@") + for ((i = 0; i < ${#args[@]}; i++)); do + case "${args[$i]}" in + -o) out="${args[$((i + 1))]}" ;; + https://*) url="${args[$i]}" ;; + esac + done + echo "$url" >>"$CALLS" + tag="${url##*/}" + if [[ " $TAGS " == *" $tag "* ]]; then + printf '{"tag_name":"%s"}' "$tag" >"$out" + printf '200' + else + printf '{"message":"Not Found"}' >"$out" + printf '404' + fi +} + +check() { + if [[ "$3" == "$2" ]]; then + echo "PASS $1" + passed=$((passed + 1)) + else + echo "FAIL $1: expected <$2>, got <$3>" >&2 + sed 's/^/ /' "$CALLS" "$LOG" >&2 2>/dev/null + failed=$((failed + 1)) + fi +} +lookup() { + : >"$CALLS" + : >"$LOG" + : >"$OUT" + local rc=0 + _forge_release_json github owner/app "$1" "" "$OUT" >/dev/null 2>&1 || rc=$? + printf '%s %s' "$rc" "$(jq -r '.tag_name // empty' "$OUT" 2>/dev/null | tr -d '\r')" +} + +TAGS="v0.35.11" +check "pin without v finds the v tag" "0 v0.35.11" "$(lookup 0.35.11)" +check "and asks twice, not more" "2" "$(wc -l <"$CALLS" | tr -d ' ')" +check "pin with v still direct" "0 v0.35.11" "$(lookup v0.35.11)" +check "a direct hit asks once" "1" "$(wc -l <"$CALLS" | tr -d ' ')" + +TAGS="12.4" +check "pin with v finds the plain tag" "0 12.4" "$(lookup v12.4)" + +TAGS="v1.0.0" +check "a tag missing both ways fails" "22 " "$(lookup 9.9.9)" +check "without retrying the 404" "2" "$(wc -l <"$CALLS" | tr -d ' ')" +check "and names the HTTP code" "1" "$(grep -c 'HTTP 404' "$LOG")" + +echo "${passed} passed, ${failed} failed" +[[ "$failed" -eq 0 ]] From c253ab19557fa4079b60001204316deeea6c966c Mon Sep 17 00:00:00 2001 From: MickLesk <47820557+MickLesk@users.noreply.github.com> Date: Fri, 13 Nov 2026 15:43:08 +0100 Subject: [PATCH 2/2] Trim the comments to what a reader would get wrong --- lib/forge.func | 4 +--- tests/forge-tag-spelling.sh | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/forge.func b/lib/forge.func index 72737d6..2cdcbff 100644 --- a/lib/forge.func +++ b/lib/forge.func @@ -1787,9 +1787,7 @@ _forge_release_json() { return 22 fi - # A pinned tag written without the repo's v (var_appversion=0.35.11 for - # v0.35.11), or with one it does not use: ask once for the other spelling. - # A tag that is missing either way does not appear by retrying. + # Ask once for the other spelling of the pinned tag, with or without the v. if [[ "$single" == "true" && "$code" == "404" ]]; then [[ -n "$other_spelling" ]] && break other_spelling="v${version}" diff --git a/tests/forge-tag-spelling.sh b/tests/forge-tag-spelling.sh index 962c9c5..6ec3260 100644 --- a/tests/forge-tag-spelling.sh +++ b/tests/forge-tag-spelling.sh @@ -20,7 +20,6 @@ getent() { return 0; } sleep() { :; } _github_release_noapi() { return 1; } ensure_dependencies() { :; } -# Only the tags listed in TAGS exist; everything else is a 404. curl() { local out="" url="" i tag local -a args=("$@")