diff --git a/tools/export-github.sh b/tools/export-github.sh index d9f29af..0df5317 100755 --- a/tools/export-github.sh +++ b/tools/export-github.sh @@ -50,9 +50,9 @@ done rsync -a --delete \ --exclude '.git' \ --exclude '.gitea' \ - --exclude 'docs' \ - --exclude 'tools' \ - --exclude 'mcp' \ + --exclude '/docs' \ + --exclude '/tools' \ + --exclude '/mcp' \ --exclude 'start-api.sh' \ --exclude 'start-ui.sh' \ --exclude 'CLAUDE.md' \ @@ -69,7 +69,7 @@ rsync -a --delete \ --exclude 'frontend/dist*' \ --exclude 'frontend/src/.plugins-staged' \ --exclude 'frontend/src/router/routes.gen.js' \ - --exclude 'instance' \ + --exclude '/instance' \ --exclude '.env' \ --exclude '__pycache__' \ --exclude '.pytest_cache' \ @@ -80,6 +80,26 @@ rsync -a --delete \ --exclude 'scripts/site_imports/wjf/idmap.json' \ "$WORK/" "$PUB/" +# --- 1b. every bundled plugin must have survived the sync --- +# +# The excludes above are rsync patterns, and a pattern with no leading slash +# matches at ANY depth. 'tools' was meant to drop the repo-root tools/ dir (this +# script lives in it) and silently dropped plugins/tools/ as well, so a plugin +# was committed, exported, bundled and deployed without ever being in the +# payload - the failure only surfaced as a missing manifest.json on the server. +# The excludes are anchored now; this check is what makes a recurrence loud. +missing="" +for manifest in "$WORK"/plugins/*/manifest.json; do + [ -e "$manifest" ] || continue + plugin=$(basename "$(dirname "$manifest")") + [ -f "$PUB/plugins/$plugin/manifest.json" ] || missing="$missing $plugin" +done +if [ -n "$missing" ]; then + echo "ERROR: bundled plugin(s) missing from the publication tree:$missing" >&2 + echo " an rsync --exclude above is matching them; anchor it with a leading slash." >&2 + exit 1 +fi + cd "$PUB" # --- 2. re-apply the publication wording (idempotent) ---