#!/usr/bin/env bash # ----------------------------------------------------------------------------- # publish-to-gitea.sh # # Publishes a SANITIZED copy of this repository to a remote git server (Gitea # by default). Runs entirely in a throw-away temp directory — your real # working tree, Replit workspace, and local git history are never touched. # # What gets stripped from the published mirror: # • Files: .replit, .replitignore, replit.nix, .local/, .agents/, # attached_assets/, every .replit-artifact/ directory, # every artifact.toml inside .replit-artifact/, .gitsafe-backup # • Commit messages: every line starting with "Replit-" is removed. # • Author/committer identity: rewritten to AUTHOR_NAME / AUTHOR_EMAIL # (default: Riyadh ; override via env vars). # # Usage: # ./scripts/publish-to-gitea.sh # dry run preview # ./scripts/publish-to-gitea.sh --push # actually force-push # AUTHOR_NAME="John" AUTHOR_EMAIL=a@b.c ./scripts/publish-to-gitea.sh --push # GITEA_REMOTE_URL=https://... ./scripts/publish-to-gitea.sh --push # GITEA_BRANCH=main ./scripts/publish-to-gitea.sh --push # ----------------------------------------------------------------------------- set -euo pipefail REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$REPO_ROOT" AUTHOR_NAME="${AUTHOR_NAME:-Riyadh}" AUTHOR_EMAIL="${AUTHOR_EMAIL:-dev@tx.local}" GITEA_REMOTE_URL="${GITEA_REMOTE_URL:-$(git config --get remote.origin.url || echo "")}" GITEA_BRANCH="${GITEA_BRANCH:-main}" PUSH=0 [[ "${1:-}" == "--push" ]] && PUSH=1 if [[ -z "$GITEA_REMOTE_URL" ]]; then echo "ERROR: no remote URL. Set GITEA_REMOTE_URL or add a git remote named 'origin'." >&2 exit 1 fi # Strip any embedded "user:token@" so we never echo credentials. Used for # all human-facing prints; the real $GITEA_REMOTE_URL (with token) is still # what gets handed to git for the actual push. sanitize_url() { # shellcheck disable=SC2001 echo "$1" | sed -E 's#^(https?://)[^/@]+@#\1#' } SAFE_REMOTE_URL="$(sanitize_url "$GITEA_REMOTE_URL")" echo "================================================================" echo " Publish-to-Gitea — sanitized history mirror" echo "----------------------------------------------------------------" echo " Source repo: $REPO_ROOT" echo " Target remote: $SAFE_REMOTE_URL" echo " Target branch: $GITEA_BRANCH" echo " New author: $AUTHOR_NAME <$AUTHOR_EMAIL>" echo " Mode: $([[ $PUSH == 1 ]] && echo 'PUSH (will force-push)' || echo 'DRY RUN (no push)')" echo "================================================================" echo WORK_DIR="$(mktemp -d -t tx-publish-XXXXXX)" trap 'rm -rf "$WORK_DIR"' EXIT # -- 1. Acquire git-filter-repo (single-file Python script) ------------------- FILTER_REPO="$WORK_DIR/git-filter-repo" if command -v git-filter-repo >/dev/null 2>&1; then FILTER_REPO="$(command -v git-filter-repo)" echo "[1/5] Using system git-filter-repo: $FILTER_REPO" else echo "[1/5] Downloading git-filter-repo into temp dir ..." if command -v curl >/dev/null 2>&1; then curl -fsSL -o "$FILTER_REPO" \ "https://raw.githubusercontent.com/newren/git-filter-repo/v2.47.0/git-filter-repo" elif command -v wget >/dev/null 2>&1; then wget -q -O "$FILTER_REPO" \ "https://raw.githubusercontent.com/newren/git-filter-repo/v2.47.0/git-filter-repo" else echo "ERROR: neither curl nor wget is available." >&2 exit 1 fi chmod +x "$FILTER_REPO" fi # -- 2. Mirror-clone the local repo into the temp dir ------------------------- MIRROR="$WORK_DIR/mirror" echo "[2/5] Cloning a fresh mirror of the local repo ..." git clone --no-local --bare "$REPO_ROOT" "$MIRROR" >/dev/null 2>&1 || \ git clone --bare "$REPO_ROOT" "$MIRROR" >/dev/null # -- 3. Strip Replit-only paths from the entire history ----------------------- echo "[3/5] Removing Replit-specific files from every commit ..." "$FILTER_REPO" --force --source "$MIRROR" --target "$MIRROR" \ --invert-paths \ --path .replit \ --path .replitignore \ --path replit.nix \ --path replit.md \ --path .local \ --path .agents \ --path attached_assets \ --path .gitsafe-backup \ --path PUBLISH.md \ --path MIGRATION_REPORT.md \ --path-glob '**/.replit-artifact' \ --path-glob '**/.replit-artifact/**' # -- 4. Rewrite commit messages and author identity --------------------------- echo "[4/5] Stripping 'Replit-*' trailers and rewriting author identity ..." MSG_CALLBACK=' import re text = message.decode("utf-8", errors="replace") # Drop every line that begins with "Replit-" cleaned = "\n".join( line for line in text.splitlines() if not re.match(r"^\s*Replit-", line) ) # Collapse trailing whitespace cleaned = re.sub(r"\n{3,}$", "\n\n", cleaned).rstrip() + "\n" return cleaned.encode("utf-8") ' NAME_BYTES="$(printf '%s' "$AUTHOR_NAME")" EMAIL_BYTES="$(printf '%s' "$AUTHOR_EMAIL")" NAME_CALLBACK="return b\"$NAME_BYTES\"" EMAIL_CALLBACK="return b\"$EMAIL_BYTES\"" "$FILTER_REPO" --force --source "$MIRROR" --target "$MIRROR" \ --message-callback "$MSG_CALLBACK" \ --name-callback "$NAME_CALLBACK" \ --email-callback "$EMAIL_CALLBACK" # -- 5. Push (or preview) ----------------------------------------------------- echo "[5/5] Final state of the sanitized mirror:" echo git --git-dir="$MIRROR" log --pretty=format:'%h %an <%ae> %s' -n 5 echo echo echo "Tip: inspect the cleaned tree with:" echo " git --git-dir=$MIRROR log --all --stat | less" echo if [[ $PUSH -eq 1 ]]; then # Auto-inject GITEA_TOKEN into the push URL if the remote is https:// # and has no credentials already. Keeps the token out of any echoed # output: $PUSH_URL is only ever passed to git, never printed. PUSH_URL="$GITEA_REMOTE_URL" if [[ -n "${GITEA_TOKEN:-}" && "$PUSH_URL" =~ ^https?:// && ! "$PUSH_URL" =~ @ ]]; then PUSH_USER="${GITEA_USERNAME:-rafraa}" PUSH_URL="$(echo "$PUSH_URL" | sed -E "s#^(https?://)#\1${PUSH_USER}:${GITEA_TOKEN}@#")" fi echo "Force-pushing branch '$GITEA_BRANCH' to $SAFE_REMOTE_URL ..." git --git-dir="$MIRROR" remote add gitea "$PUSH_URL" 2>/dev/null || \ git --git-dir="$MIRROR" remote set-url gitea "$PUSH_URL" git --git-dir="$MIRROR" push --force gitea "HEAD:refs/heads/$GITEA_BRANCH" echo echo "Done. Open $SAFE_REMOTE_URL to verify." else echo "DRY RUN complete — nothing was pushed." echo "Re-run with --push to publish: ./scripts/publish-to-gitea.sh --push" fi