diff --git a/scripts/build-release.sh b/scripts/build-release.sh index 338dbc20..12a2c013 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -117,18 +117,63 @@ mkdir -p "$STAGE_DIR/scripts" cp "$PROJECT_DIR/api/prisma/init-nocodb-db.sh" "$STAGE_DIR/scripts/" cp "$PROJECT_DIR/api/prisma/init-gancio-db.sh" "$STAGE_DIR/scripts/" -# Runtime scripts -for script in nocodb-init.sh gitea-init.sh mkdocs-entrypoint.sh \ - backup.sh restore.sh \ - upgrade.sh upgrade-check.sh upgrade-watcher.sh \ - uninstall.sh test-deployment.sh \ - validate-env.sh pangolin-teardown.sh ccp-deregister.sh; do +# Explicit allow/deny lists for scripts/*.sh. Every shell script in scripts/ +# must appear in exactly one of these arrays — the parity check below aborts +# the build if anything is unaccounted for. This catches the "added a new +# script, forgot to add it to the release" drift bug. +RUNTIME_SCRIPTS=( + # Ship in the release tarball — user-facing or invoked by containers/upgrades + install.sh + nocodb-init.sh gitea-init.sh mkdocs-entrypoint.sh + backup.sh restore.sh + upgrade.sh upgrade-check.sh upgrade-watcher.sh + uninstall.sh test-deployment.sh + validate-env.sh pangolin-teardown.sh ccp-deregister.sh register-with-ccp.sh + update-env.sh +) + +DEV_ONLY_SCRIPTS=( + # Deliberately NOT shipped — dev-machine tooling (build/release/mirror/CI) + build-and-push.sh build-release.sh + mirror-images.sh validate-compose-parity.sh +) + +# --- Parity check: every scripts/*.sh must be classified --- +declare -A KNOWN_SCRIPTS +for s in "${RUNTIME_SCRIPTS[@]}" "${DEV_ONLY_SCRIPTS[@]}"; do + KNOWN_SCRIPTS[$s]=1 +done + +UNCLASSIFIED=() +for f in "$PROJECT_DIR"/scripts/*.sh; do + [[ -f "$f" ]] || continue + name=$(basename "$f") + if [[ -z "${KNOWN_SCRIPTS[$name]:-}" ]]; then + UNCLASSIFIED+=("$name") + fi +done + +if [[ ${#UNCLASSIFIED[@]} -gt 0 ]]; then + error "build-release.sh parity check failed — unclassified scripts/*.sh:" + for name in "${UNCLASSIFIED[@]}"; do + echo " - $name" >&2 + done + echo "" >&2 + echo " Every script in scripts/*.sh must be classified as either:" >&2 + echo " RUNTIME_SCRIPTS — ships in the release tarball" >&2 + echo " DEV_ONLY_SCRIPTS — stays on dev/build machines only" >&2 + echo " Edit scripts/build-release.sh and add each to the correct array." >&2 + exit 1 +fi + +# Copy the runtime scripts +for script in "${RUNTIME_SCRIPTS[@]}"; do if [[ -f "$PROJECT_DIR/scripts/$script" ]]; then cp "$PROJECT_DIR/scripts/$script" "$STAGE_DIR/scripts/" fi done -# MkDocs build trigger +# MkDocs build trigger (python, not in the allowlist because it's .py) if [[ -f "$PROJECT_DIR/scripts/mkdocs-build-trigger.py" ]]; then cp "$PROJECT_DIR/scripts/mkdocs-build-trigger.py" "$STAGE_DIR/scripts/" fi @@ -138,9 +183,6 @@ if [[ -d "$PROJECT_DIR/scripts/systemd" ]]; then cp -r "$PROJECT_DIR/scripts/systemd" "$STAGE_DIR/scripts/" fi -# Install script (for reference) -cp "$PROJECT_DIR/scripts/install.sh" "$STAGE_DIR/scripts/" - chmod +x "$STAGE_DIR/scripts/"*.sh 2>/dev/null || true info "Scripts ($(ls "$STAGE_DIR/scripts/" | wc -l) files)"