Two instances run on the box (dev /ops + prod /shopdb); each needs its own base-path build. Build both on every --dist so prod never ships a stale frontend. tools/ is excluded from publication, so this is dev-tooling only.
135 lines
5.2 KiB
Bash
Executable File
135 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Export the working repo to the GitHub publication repo and emit a bundle.
|
|
#
|
|
# Pipeline: working repo (full history, internal refs) -> pruned/scrubbed
|
|
# tree -> commit in ~/projects/shopdb-flask-pub (the local mirror of what
|
|
# enterprise GitHub holds) -> full git bundle in /home/camp/pxe-images/ for
|
|
# transfer to the work PC, which pushes it to GitHub.
|
|
#
|
|
# Usage:
|
|
# tools/export-github.sh "Commit message for the publication commit"
|
|
# tools/export-github.sh --dist # also rebuild BOTH frontend dists
|
|
# # (/ops = dev, /shopdb = prod)
|
|
#
|
|
# This script lives in tools/, which is itself excluded from publication.
|
|
set -euo pipefail
|
|
|
|
WORK=/home/camp/projects/shopdb-flask
|
|
PUB=/home/camp/projects/shopdb-flask-pub
|
|
OUT=/home/camp/pxe-images/github
|
|
|
|
BUILD_DIST=0
|
|
MSG=""
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--dist) BUILD_DIST=1 ;;
|
|
*) MSG="$arg" ;;
|
|
esac
|
|
done
|
|
[ -n "$MSG" ] || { echo "usage: $0 [--dist] \"commit message\""; exit 1; }
|
|
[ -d "$PUB/.git" ] || { echo "publication repo missing at $PUB"; exit 1; }
|
|
|
|
# --- 1. sync the tree (working -> pub), minus everything never published ---
|
|
rsync -a --delete \
|
|
--exclude '.git' \
|
|
--exclude '.gitea' \
|
|
--exclude 'docs' \
|
|
--exclude 'tools' \
|
|
--exclude 'start-api.sh' \
|
|
--exclude 'start-ui.sh' \
|
|
--exclude 'CLAUDE.md' \
|
|
--exclude 'frontend/CLAUDE.md' \
|
|
--exclude 'tests/test_docs_contract.py' \
|
|
--exclude 'tests/test_plugins/test_geenforce_parity.py' \
|
|
--exclude 'tests/test_plugins/test_zabbix_live.py' \
|
|
--exclude 'venv' \
|
|
--exclude 'node_modules' \
|
|
--exclude 'frontend/dist*' \
|
|
--exclude 'frontend/src/.plugins-staged' \
|
|
--exclude 'frontend/src/router/routes.gen.js' \
|
|
--exclude 'instance' \
|
|
--exclude '.env' \
|
|
--exclude '__pycache__' \
|
|
--exclude '*.pyc' \
|
|
--exclude 'scripts/site_imports/wjf/idmap.json' \
|
|
"$WORK/" "$PUB/"
|
|
|
|
cd "$PUB"
|
|
|
|
# --- 2. re-apply the publication wording (idempotent) ---
|
|
# docs/ lives only in the wiki on the GitHub side.
|
|
grep -rlZ 'docs/' --include='*.py' --include='*.md' --include='*.sh' \
|
|
--include='*.tmpl' --include='*.vue' --include='*.example' . 2>/dev/null |
|
|
while IFS= read -r -d '' f; do
|
|
case "$f" in ./CHANGELOG.md) continue ;; esac
|
|
sed -i -E \
|
|
-e 's/\[`?docs\/([A-Za-z0-9_-]+)\.md`?\]\((\.\.\/)*docs\/[A-Za-z0-9_-]+\.md\)/the \1 page in the project wiki/g' \
|
|
-e 's/docs\/proposals\/ge-enforce-plugin\.md/the ge-enforce-plugin proposal in the project wiki/g' \
|
|
-e 's/`docs\/([A-Za-z0-9_-]+)\.md`/the \1 wiki page/g' \
|
|
-e 's/docs\/([A-Za-z0-9_-]+)\.md/the \1 wiki page/g' "$f"
|
|
done
|
|
sed -i 's|<code>docs/GE-ENFORCE.md</code>|the GE-ENFORCE page in the project wiki|' \
|
|
frontend/src/views/geenforce/ManifestEditor.vue 2>/dev/null || true
|
|
# internal infra never named on GitHub; this repo's own URL maps to the
|
|
# real GitHub home, anything else degrades to a placeholder.
|
|
GITHUB_URL='https://github.com/ge-aero/shopdb-flask'
|
|
grep -rlZ 'gitea\.proudtech\.net' . 2>/dev/null | while IFS= read -r -d '' f; do
|
|
sed -i -e "s|https://gitea\.proudtech\.net/ge-aerospace/shopdb-flask|$GITHUB_URL|g" \
|
|
-e 's|gitea\.proudtech\.net|<git-host>|g' "$f"
|
|
done
|
|
grep -rlZi 'gitea' --exclude-dir=.git . 2>/dev/null | while IFS= read -r -d '' f; do
|
|
sed -i -e 's/the GE Aerospace Gitea/the internal GE Aerospace git server/g' \
|
|
-e 's/Gitea Actions CI/CI/g' \
|
|
-e 's/Gitea Actions/CI/g' "$f"
|
|
done
|
|
# CHANGELOG compare/release link definitions reference tags that do not
|
|
# exist on GitHub (history is squashed there) - drop them.
|
|
sed -i '/^\[[^]]*\]: .*\/\(compare\|releases\)\//d' CHANGELOG.md
|
|
# frontend/CLAUDE.md publishes under a neutral name
|
|
if [ -f "$WORK/frontend/CLAUDE.md" ]; then
|
|
cp "$WORK/frontend/CLAUDE.md" frontend/DEVELOPMENT-STANDARDS.md
|
|
fi
|
|
sed -i "s/rootpassword/changeme/g" shopdb/config.py 2>/dev/null || true
|
|
|
|
# --- 3. scrub gate: refuse to commit if anything internal leaks ---
|
|
LEAKS=$(grep -rlIiE 'claude|anthropic|fable 5|gitea|proudtech|home/camp|rootpassword' \
|
|
--exclude-dir=.git . || true)
|
|
if [ -n "$LEAKS" ]; then
|
|
echo "SCRUB GATE FAILED - internal references in:"; echo "$LEAKS"; exit 1
|
|
fi
|
|
|
|
# --- 4. commit (no-op safe) ---
|
|
git add -A
|
|
if git diff --cached --quiet; then
|
|
echo "no changes vs publication tree - nothing to export"
|
|
else
|
|
git commit -m "$MSG"
|
|
fi
|
|
git log --oneline -3
|
|
|
|
# --- 5. bundle for transfer (full bundle: stateless, fetch takes only new) ---
|
|
git bundle create "$OUT/shopdb-flask-pub.bundle" HEAD main --tags
|
|
git bundle verify "$OUT/shopdb-flask-pub.bundle" >/dev/null
|
|
echo "bundle: $OUT/shopdb-flask-pub.bundle"
|
|
|
|
# --- 6. optional per-instance dists (both bases: /ops = dev, /shopdb = prod) ---
|
|
# Two instances run on the box; each needs its own base-path build. Always
|
|
# rebuild BOTH so prod never ships a stale frontend.
|
|
if [ "$BUILD_DIST" = 1 ]; then
|
|
cd "$WORK/frontend"
|
|
for base in ops shopdb; do
|
|
VITE_BASE_PATH=/$base/ npm run build --silent
|
|
rm -rf "$OUT/frontend-dist-subpath-$base"
|
|
cp -r dist "$OUT/frontend-dist-subpath-$base"
|
|
echo "dist: $OUT/frontend-dist-subpath-$base/ (base /$base/)"
|
|
done
|
|
fi
|
|
|
|
cat <<'EOF'
|
|
|
|
On the work PC (in the shopdb-flask-pub clone):
|
|
git fetch <path-to>\shopdb-flask-pub.bundle main
|
|
git merge --ff-only FETCH_HEAD
|
|
git push origin main
|
|
EOF
|