#!/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"