scripts/build_release_package.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
OUT_DIR="${1:-$SKILL_DIR/dist}"
STAMP="$(date +%Y%m%d-%H%M%S)"
PKG_NAME="x-knowledge-base-skill-$STAMP"
STAGE="$OUT_DIR/$PKG_NAME"
ARCHIVE="$OUT_DIR/$PKG_NAME.tar.gz"
mkdir -p "$OUT_DIR"
rm -rf "$STAGE"
mkdir -p "$STAGE"
copy_path() {
local src="$1"
if [ -e "$SKILL_DIR/$src" ]; then
mkdir -p "$STAGE/$(dirname "$src")"
cp -a "$SKILL_DIR/$src" "$STAGE/$src"
fi
}
# Core metadata/docs
copy_path "SKILL.md"
copy_path "README.md"
copy_path "README.zh.md"
copy_path ".env.example"
copy_path ".gitignore"
# Reusable assets/config/docs
copy_path "assets"
copy_path "config/category-rules.json"
copy_path "config/llm.json"
copy_path "config/recommendation-topics.json"
copy_path "config/tiege-queue.example.json"
copy_path "config/examples"
copy_path "docs/data-flow.md"
copy_path "docs/security-audit-response.md"
copy_path "docs/xkb-inference-adapter-spec.md"
copy_path "docs/xkb-vnext-roadmap-draft.md"
copy_path "docs/xkb-memory-service.md"
copy_path "docs/RUNTIME_PATHS.md"
copy_path "docs/PUBLISHING_CHECKLIST.md"
copy_path "references"
copy_path "evals"
# Code
copy_path "scripts"
copy_path "tools"
# Sanitized wiki shell only; no personal topics/staging/logs
mkdir -p "$STAGE/wiki/topics"
copy_path "wiki/WIKI-SCHEMA.md"
copy_path "wiki/README.md"
if [ -f "$SKILL_DIR/wiki/.gitignore" ]; then copy_path "wiki/.gitignore"; fi
: > "$STAGE/wiki/topics/.gitkeep"
# Demo source without generated output/build deps
copy_path "demo/generate_graph.py"
copy_path "demo/sample-notes"
copy_path "demo/xkb-demo-ui/README.md"
copy_path "demo/xkb-demo-ui/package.json"
copy_path "demo/xkb-demo-ui/package-lock.json"
copy_path "demo/xkb-demo-ui/tsconfig.json"
copy_path "demo/xkb-demo-ui/next.config.ts"
copy_path "demo/xkb-demo-ui/postcss.config.mjs"
copy_path "demo/xkb-demo-ui/app"
copy_path "demo/xkb-demo-ui/components"
copy_path "demo/xkb-demo-ui/public/graph-data.sample.json"
# Remove runtime/build/private artifacts defensively.
find "$STAGE" -type d \( -name '.git' -o -name '.next' -o -name 'node_modules' -o -name '__pycache__' -o -name '.secrets' \) -prune -exec rm -rf {} +
find "$STAGE" -type f \( -name '*.pyc' -o -name '*.pyo' -o -name '.env' -o -name '*.env' \) -delete
rm -f "$STAGE/demo/xkb-demo-ui/public/graph-data.json"
rm -f "$STAGE/wiki/log.md" "$STAGE/wiki/review-decisions.json" "$STAGE/wiki/topic-map.json" "$STAGE/wiki/index.md"
rm -rf "$STAGE/wiki/_staging"
find "$STAGE/wiki/topics" -type f ! -name '.gitkeep' -delete
# Safety scan: fail on obvious hardcoded secrets, not env-var placeholders.
python3 - <<'PY' "$STAGE"
import re, sys
from pathlib import Path
stage = Path(sys.argv[1])
patterns = [
re.compile(r'(?:BIRD_AUTH_TOKEN|BIRD_CT0|auth_token|ct0)\s*[=:]\s*["\']?([A-Za-z0-9_%-]{40,})'),
re.compile(r'(?:API_KEY|TOKEN|SECRET)\s*[=:]\s*["\']?(sk-[A-Za-z0-9_-]{20,}|[A-Za-z0-9_-]{48,})'),
]
allow_fragments = ['${', '***', 'your_', 'YOUR_', '<', 'example', 'placeholder']
hits=[]
for p in stage.rglob('*'):
if not p.is_file():
continue
try:
text = p.read_text(errors='ignore')
except Exception:
continue
for i,line in enumerate(text.splitlines(),1):
for pat in patterns:
m = pat.search(line)
if not m:
continue
val = m.group(1)
if any(f in line for f in allow_fragments):
continue
hits.append(f'{p}:{i}: {line[:220]}')
if hits:
print('Refusing to package: potential hardcoded secret found', file=sys.stderr)
print('\n'.join(hits), file=sys.stderr)
sys.exit(1)
PY
tar -czf "$ARCHIVE" -C "$OUT_DIR" "$PKG_NAME"
SIZE="$(du -h "$ARCHIVE" | awk '{print $1}')"
COUNT="$(find "$STAGE" -type f | wc -l | tr -d ' ')"
echo "release_dir=$STAGE"
echo "archive=$ARCHIVE"
echo "size=$SIZE"
echo "files=$COUNT"