diff --git a/scripts/validate-plugins.sh b/scripts/validate-plugins.sh index cb8911901f..d20f3c1edf 100755 --- a/scripts/validate-plugins.sh +++ b/scripts/validate-plugins.sh @@ -52,7 +52,19 @@ if ! command -v node >/dev/null 2>&1; then echo "error: node not on PATH" >&2 exit 2 fi -node scripts/validate-plugin-contracts.mjs || exit 1 +# A contract WARNING fails here too. scripts/validate-plugin-contracts.test.sh +# asserts the shipping tree draws none, but the selection runs that suite only +# when the change reaches it, so a warning a pull request introduces would +# otherwise pass its own run and fail first in the merge queue (#6215). +contracts=$(node scripts/validate-plugin-contracts.mjs 2>&1) || { + printf '%s\n' "$contracts" + exit 1 +} +printf '%s\n' "$contracts" +if grep -q '^warning: ' <<<"$contracts"; then + echo "error: the plugin contract validator printed a warning; the tree must draw none" >&2 + exit 1 +fi bash scripts/check-publisher-token-alignment.sh || exit 1 node scripts/generate-catalog.mjs --check || exit 1 node scripts/generate-cheatsheet.mjs --check || exit 1 diff --git a/scripts/validate-plugins.test.sh b/scripts/validate-plugins.test.sh index fd6b19fb4e..1120d7481e 100755 --- a/scripts/validate-plugins.test.sh +++ b/scripts/validate-plugins.test.sh @@ -27,4 +27,19 @@ expect_usage "--only with a stray second argument is a usage error" "usage: vali expect_usage "a name that is not a plugin is refused" "'no-such-plugin' is not a plugin" --only "guardrails no-such-plugin" expect_usage "a path in place of a name is refused" "is not a plugin" --only "../scripts" +# A contract warning fails the run (#6215), before any later pass runs. A +# stand-in `node` plays the contract validator: exit 0, one warning line. +TMP_ROOT="$(mktemp -d)" +trap 'rm -rf "$TMP_ROOT"' EXIT +printf '#!/usr/bin/env bash\necho "warning: plugins/x/.claude-plugin/plugin.json: probe" >&2\nexit 0\n' >"$TMP_ROOT/node" +chmod +x "$TMP_ROOT/node" +rc=0 +out="$(PATH="$TMP_ROOT:$PATH" bash "$SCRIPT" --only "" 2>&1)" || rc=$? +if [[ "$rc" -eq 1 && "$out" == *"warning: plugins/x/.claude-plugin/plugin.json: probe"* && + "$out" == *"printed a warning"* && "$out" != *"=== validate"* ]]; then + ok "a contract warning fails the run and is printed" +else + fail "a contract warning should fail the run with the warning shown, got rc=$rc: $out" +fi + test_harness::report