-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAGENTS-release-check.sh
More file actions
executable file
·88 lines (80 loc) · 3.21 KB
/
AGENTS-release-check.sh
File metadata and controls
executable file
·88 lines (80 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env bash
# AGENTS.md end-of-turn check: every `v1.X:` commit on main must have
# a matching annotated tag, and every tag must have a published GitHub
# release. Exit code:
# 0 — everything in sync
# 1 — at least one version commit is missing a tag or release
# 2 — environment unusable (no git, no gh, not in this repo)
#
# Quiet by default; pass --verbose to also print the GOOD lines.
# This is a CHECK, not a fixer. It prints what's broken; you decide how
# to repair (usually: tag + push the missing commit, let the workflow
# build the release).
set -u
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$REPO_DIR" || { echo "cannot cd to $REPO_DIR" >&2; exit 2; }
command -v git >/dev/null 2>&1 || { echo "git not in PATH" >&2; exit 2; }
VERBOSE=0
[ "${1:-}" = "--verbose" ] || [ "${1:-}" = "-v" ] && VERBOSE=1
# Pull latest tag state from origin so we don't false-positive on a tag
# the user pushed but our local clone hasn't fetched.
git fetch origin --tags --quiet 2>/dev/null || true
missing_tags=0
missing_releases=0
historical_exception() {
local tag="$1" sha="$2"
# v1.10-v1.14 predate the release workflow and are explicitly documented in
# AGENTS.md as no-backfill-by-default history.
case "$tag" in
v1.10|v1.11|v1.12|v1.13|v1.14)
return 0
;;
esac
# Early post-policy history contains duplicate version subjects. The tag for
# each version points at the canonical release commit; these older subjects
# are preserved in git history but must not keep every future audit red.
case "$tag:$sha" in
v1.18:378a91620eb690ccf9469dbf4e24c55f0a637fba|\
v1.20:02aaed161dddc3536f655dcfb65707b7b5613139|\
v1.21:72c4845f962221feb1ddf7719279b478f65cb170)
return 0
;;
esac
return 1
}
# Walk every commit whose subject starts with `vX.Y[.Z]:`.
while IFS=$'\t' read -r sha subject; do
tag=$(printf '%s' "$subject" | awk '{print $1}' | tr -d ':')
if historical_exception "$tag" "$sha"; then
[ "$VERBOSE" = "1" ] && printf 'SKIP %s %s historical exception\n' "$tag" "$sha"
continue
fi
# The tag must (a) exist locally and (b) point at this same commit.
if ! git rev-parse --verify --quiet "refs/tags/$tag" >/dev/null; then
printf 'MISSING TAG %s %s\n' "$tag" "$sha"
missing_tags=$((missing_tags + 1))
continue
fi
tagged_sha=$(git rev-list -n 1 "refs/tags/$tag")
if [ "$tagged_sha" != "$sha" ]; then
printf 'TAG MISPOINTS %s expected %s got %s\n' "$tag" "$sha" "$tagged_sha"
missing_tags=$((missing_tags + 1))
continue
fi
if command -v gh >/dev/null 2>&1; then
if ! gh release view "$tag" >/dev/null 2>&1; then
printf 'MISSING RELEASE %s %s\n' "$tag" "$sha"
missing_releases=$((missing_releases + 1))
continue
fi
fi
[ "$VERBOSE" = "1" ] && printf 'OK %s %s\n' "$tag" "$sha"
done < <(git log --format='%H%x09%s' | awk -F'\t' '$2 ~ /^v[0-9]+\.[0-9]+(\.[0-9]+)?:/ {print}')
if [ "$missing_tags" -eq 0 ] && [ "$missing_releases" -eq 0 ]; then
[ "$VERBOSE" = "1" ] && echo "all version commits tagged + released"
exit 0
fi
echo
echo "summary: $missing_tags missing tag(s), $missing_releases missing release(s)"
echo "see AGENTS.md § Versioning + releases for the fix workflow"
exit 1