ajhahn.de
← eeco
Shell 40 lines
#!/usr/bin/env bash
# Verify the README version badge stays in lockstep with the latest release tag.
#
# The badge is a static shields badge on purpose: the dynamic github/v/release
# badge fails intermittently with shields' "Unable to select next GitHub token
# from pool" error (its shared GitHub-API token pool runs dry). A static badge
# never calls the API, so it can never show that error -- but it must be bumped
# at release time. This gate fails if it ever drifts behind the latest tag.
#
# Semantics mirror eeco's own version_anchor=tag: badge >= latest tag is OK (a
# release commit may bump the badge ahead of the not-yet-pushed tag); a badge
# behind the latest tag fails.
#
# Run locally: bash scripts/check-version-badge.sh
# CI: a step in the verify job (.github/workflows/ci.yml), after make gates.
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
README="$ROOT/README.md"

badge="$(grep -oE 'badge/version-v[0-9]+\.[0-9]+\.[0-9]+-' "$README" | head -1 | sed -E 's#badge/version-v([0-9.]+)-#\1#')"
if [ -z "$badge" ]; then
  echo "check-version-badge: no static version badge found in README.md" >&2
  exit 1
fi

tag="$(git -C "$ROOT" describe --tags --abbrev=0 2>/dev/null | sed 's/^v//')"
if [ -z "$tag" ]; then
  echo "check-version-badge: no git tag found; skipping lockstep check" >&2
  exit 0
fi

newest="$(printf '%s\n%s\n' "$tag" "$badge" | sort -V | tail -1)"
if [ "$newest" != "$badge" ]; then
  echo "check-version-badge: README badge v$badge is behind latest tag v$tag -- bump the badge" >&2
  exit 1
fi

echo "check-version-badge: README badge v$badge >= latest tag v$tag -- in lockstep"