Files
getsentry__sentry-for-ai/scripts/validate-built-links.sh
Evan Purkhiser da5b79c583 fix(ci): validate that every skill link resolves (#312)
Skill link checking has been silently off. build-skill-tree.sh has a
breadcrumb-link check, but it opens by skipping any skill that is neither a
router nor categorized:

    if [[ "$role" != "router" && -z "$cat" ]]; then
      continue
    fi

Every skill is standalone now, so every skill takes that branch and no link is
checked at all. It was not turned off deliberately -- the guard was written when
standalone skills were the exception, and going flat quietly disabled it for
everything. That leaves the failure #308 fixed with nothing guarding it.

Check the built plugin trees rather than the source. A skill only becomes
self-contained once the build hydrates its declared references in, so the source
tree cannot answer the question on its own -- any check there has to
re-implement the hydrator's glob semantics and can drift from it. Building
first removes the simulation: what gets validated is the tree a user installs,
per agent, including each agent's own transform.

Every agent is built and checked, since layout and transforms differ between
them and a link can survive one while breaking another. The builds need no
network or credentials and take well under a second each, so the whole sweep
costs a few seconds per pull request.

Passing the source library in as well buys a cause instead of a symptom: a
target missing from the built skill but present in the library means the
manifest never declared it, so the error says to fix references.yml rather than
leaving a bare dangling-link report.

Runs in the existing validate job, which gains a uv install matching the one
deploy-plugins already uses.
2026-08-04 14:42:17 -04:00

56 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# validate-built-links.sh — Build every agent's plugin and check its links.
#
# The skills we ship are only self-contained *after* the build: references are
# hydrated in from the shared library, and each agent applies its own transform.
# So the tree worth validating is the built one, per agent — that is what a user
# installs, and it is the only place a missing reference actually shows up.
#
# Each build is well under a second and needs no network or credentials, so this
# is cheap enough to run on every pull request.
#
# Usage: validate-built-links.sh
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT
status=0
for build in src/plugins/*/build.sh; do
agent="$(basename "$(dirname "$build")")"
target="$WORK_DIR/$agent"
mkdir -p "$target"
# Builders are chatty about hydration counts; keep the signal to failures.
if ! "$build" "$target" > "$WORK_DIR/$agent.log" 2>&1; then
echo "error: $agent build failed" >&2
cat "$WORK_DIR/$agent.log" >&2
status=1
continue
fi
# Agents disagree on layout (Codex nests under plugins/<name>/), so locate
# the skills dir by finding where the SKILL.md files actually landed.
skills_dir="$(find "$target" -name SKILL.md -exec dirname {} \; \
| xargs -n1 dirname | sort -u | head -1)"
if [[ -z "$skills_dir" ]]; then
echo "error: $agent build produced no skills" >&2
status=1
continue
fi
./scripts/validate-skill-links.py \
--skills "$skills_dir" \
--references src/references \
--label "$agent" || status=1
done
exit $status