#!/usr/bin/env bash # ============================================================================= # push-to-gitea.sh — Push current branch to Gitea (Tailscale Funnel) # # Usage: # bash scripts/push-to-gitea.sh [BRANCH] # # BRANCH defaults to the current checked-out branch. # # Gitea base URL is resolved from (in order): # 1. GITEA_URL env var # 2. GITEA_URL in .env.local # 3. Hard-coded Tailscale Funnel fallback # # Token is resolved from (in order): # 1. GITEA_TOKEN env var # 2. .gitea-credentials file in repo root (gitignored, one line: the token) # ============================================================================= set -euo pipefail GITEA_USER="${GITEA_USER:-replit}" REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${CYAN}[gitea]${NC} $*"; } ok() { echo -e "${GREEN}[ok]${NC} $*"; } warn() { echo -e "${YELLOW}[warn]${NC} $*"; } die() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; } # ─── 1. Resolve Gitea base URL ─────────────────────────────────────────────── GITEA_BASE="${GITEA_URL:-}" if [[ -z "$GITEA_BASE" && -f "$REPO_ROOT/.env.local" ]]; then GITEA_BASE="$(grep '^GITEA_URL=' "$REPO_ROOT/.env.local" | cut -d= -f2- | tr -d '[:space:]')" fi # Fallback: Tailscale Funnel (permanent, no port changes) GITEA_BASE="${GITEA_BASE:-https://mm.tailb74b2d.ts.net}" # Strip trailing slash GITEA_BASE="${GITEA_BASE%/}" # ─── 2. Load token ─────────────────────────────────────────────────────────── CREDS_FILE="$REPO_ROOT/.gitea-credentials" if [[ -z "${GITEA_TOKEN:-}" && -f "$CREDS_FILE" ]]; then GITEA_TOKEN="$(tr -d '[:space:]' < "$CREDS_FILE")" fi if [[ -z "${GITEA_TOKEN:-}" ]]; then die "GITEA_TOKEN is not set. Set it in one of two ways: a) Export in your shell: export GITEA_TOKEN= b) Save to .gitea-credentials: echo > .gitea-credentials Get your token from: ${GITEA_BASE}/user/settings/applications" fi # ─── 3. Verify Gitea is reachable ──────────────────────────────────────────── info "Checking Gitea at ${GITEA_BASE} …" if ! curl -sf --max-time 8 "${GITEA_BASE}/api/v1/version" -o /dev/null 2>/dev/null; then die "Gitea is not reachable at ${GITEA_BASE}. Check that your Tailscale Funnel is running: tailscale funnel status tailscale funnel 3000 # to start it" fi ok "Gitea reachable at ${GITEA_BASE}" # ─── 4. Detect repo and branch ─────────────────────────────────────────────── EXISTING_REMOTE="$(git -C "$REPO_ROOT" remote get-url gitea 2>/dev/null || true)" if [[ "$EXISTING_REMOTE" =~ /([^/]+)\.git$ ]]; then REPO_NAME="${BASH_REMATCH[1]}" else REPO_NAME="$(basename "$REPO_ROOT")" fi BRANCH="${1:-$(git -C "$REPO_ROOT" rev-parse --abbrev-ref HEAD)}" if [[ "$BRANCH" == "HEAD" ]]; then die "Detached HEAD state — check out a branch before pushing." fi info "Repo: ${REPO_NAME}" info "Branch: ${BRANCH}" # ─── 5. Update (or add) the gitea remote ───────────────────────────────────── REMOTE_URL_WITH_CREDS="${GITEA_BASE/https:\/\//https://${GITEA_USER}:${GITEA_TOKEN}@}/${GITEA_USER}/${REPO_NAME}.git" if git -C "$REPO_ROOT" remote get-url gitea &>/dev/null; then git -C "$REPO_ROOT" remote set-url gitea "$REMOTE_URL_WITH_CREDS" else git -C "$REPO_ROOT" remote add gitea "$REMOTE_URL_WITH_CREDS" info "Added 'gitea' remote." fi # ─── 6. Push ───────────────────────────────────────────────────────────────── info "Pushing ${BRANCH} → gitea …" echo "" if git -C "$REPO_ROOT" push gitea "HEAD:${BRANCH}"; then echo "" ok "Pushed ${BRANCH} to gitea." echo "" echo " Branch: ${GITEA_BASE}/${GITEA_USER}/${REPO_NAME}/src/branch/${BRANCH}" echo " Open PR: ${GITEA_BASE}/${GITEA_USER}/${REPO_NAME}/compare/main...${BRANCH}" echo "" else EXIT_CODE=$? echo "" die "git push failed (exit ${EXIT_CODE}). See error above." fi