#!/usr/bin/env bash # Resolve the latest upstream version for a package and print it on stdout. # # Reads the package's .autoupdate manifest (srchost/srcmntr/srcname/verstrip). # # usage: latest-version.sh [package-dir] # # Exit 0 with a version on stdout, or exit 1 with a message on stderr. # # There is deliberately NO "returned nothing so assume no update" path. The old # workflow could not tell a broken query from a quiet night: pman-helper's # lookup hit a 404, produced an empty string, and push.sh treated it as a # version. "Query returned nothing" is an error, not a version. set -euo pipefail _here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=common.sh source "${_here}/common.sh" pkgdir="${1:-.}" manifest="${pkgdir}/.autoupdate" [ -f "$manifest" ] || die "no .autoupdate manifest in ${pkgdir}" # shellcheck disable=SC1090 source "$manifest" : "${srchost:?manifest is missing srchost}" : "${srcmntr:?manifest is missing srcmntr}" : "${srcname:?manifest is missing srcname}" verstrip="${verstrip:-}" GIT_HOST="${GIT_HOST:-git.bjphoster.com}" # curl that fails loudly on HTTP errors instead of returning an error page. fetch() { local url="$1"; shift local out rc=0 out="$(curl --silent --show-error --location --fail-with-body \ --retry 3 --retry-delay 2 --max-time 60 "$@" "$url" 2>&1)" || rc=$? if [ "$rc" -ne 0 ]; then printf '%s\n' "$out" >&2 die "request to ${url} failed (curl exit ${rc})" fi printf '%s' "$out" } case "$srchost" in github) url="https://api.github.com/repos/${srcmntr}/${srcname}/releases/latest" hdrs=(-H "Accept: application/vnd.github+json") # Optional: avoids the 60/hour unauthenticated rate limit in CI. [ -n "${GITHUB_TOKEN:-}" ] && hdrs+=(-H "Authorization: Bearer ${GITHUB_TOKEN}") body="$(fetch "$url" "${hdrs[@]}")" tag="$(printf '%s' "$body" | jq -r '.tag_name // empty')" [ -n "$tag" ] || die "no tag_name in the latest release of ${srcmntr}/${srcname}" ;; gitea) # NB: the correct Gitea path is /repos/{owner}/{repo}/tags. The old # workflows used /repos/{owner}/{repo}/repo/tags, which 404s. url="https://${GIT_HOST}/api/v1/repos/${srcmntr}/${srcname}/tags" body="$(fetch "$url" -H "Accept: application/json")" printf '%s' "$body" | jq -e 'type == "array"' >/dev/null 2>&1 \ || die "unexpected response shape from ${url}" tag="$(printf '%s' "$body" | jq -r '.[].name' | sort -V | tail -n1)" [ -n "$tag" ] || die "${srcmntr}/${srcname} has no tags" ;; *) die "unknown srchost '${srchost}' (expected 'github' or 'gitea')" ;; esac version="$tag" if [ -n "$verstrip" ]; then version="${version#"$verstrip"}" fi validate_version "$version" "resolved version (from tag '${tag}')" printf '%s\n' "$version"