From 94d1f84caa9947a8f3143e3c2067f11a3cc35f17 Mon Sep 17 00:00:00 2001 From: codex Date: Wed, 8 Jul 2026 12:39:16 +0200 Subject: [PATCH] tools: batch Gitea-to-Forgejo migration script Wraps promote-repo-to-forgejo.sh for all local checkouts still on gitea-remote origin; patches State Hub remote_url after each push. --- tools/migrate-gitea-repos-to-forgejo.sh | 104 ++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 tools/migrate-gitea-repos-to-forgejo.sh diff --git a/tools/migrate-gitea-repos-to-forgejo.sh b/tools/migrate-gitea-repos-to-forgejo.sh new file mode 100755 index 0000000..f6835db --- /dev/null +++ b/tools/migrate-gitea-repos-to-forgejo.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +# Batch-promote local coulomb repos from gitea-remote origin to forgejo-remote. +# Uses railiance-enablement/tools/promote-repo-to-forgejo.sh per repo. +set -euo pipefail + +ROOT="${HOME}" +PROMOTE="${PROMOTE_SCRIPT:-$HOME/railiance-enablement/tools/promote-repo-to-forgejo.sh}" +PATCH="${PATCH_SCRIPT:-$HOME/the-custodian/tools/patch-forgejo-remote-urls.sh}" +API_BASE="${API_BASE:-http://127.0.0.1:8000}" +DRY_RUN="${DRY_RUN:-0}" +SKIP_CI="${SKIP_CI:-0}" + +usage() { + cat <<'USAGE' +Usage: migrate-gitea-repos-to-forgejo.sh [repo ...] + + With no args: migrate every ~/ checkout whose origin is gitea-remote. + With slugs: migrate only those repos (must exist under ~/). + +Environment: + DRY_RUN=1 List targets only; do not push or patch + SKIP_CI=1 Skip ci-smoke workflow commit in promote script (set PROMOTE_CI_TEMPLATE=/dev/null) +USAGE +} + +is_gitea_origin() { + local path="$1" + local url + url="$(git -C "$path" remote get-url origin 2>/dev/null || true)" + [[ "$url" == gitea-remote:* ]] || [[ "$url" == *gitea.coulomb.social* ]] +} + +collect_targets() { + local slug path + if [[ $# -gt 0 ]]; then + for slug in "$@"; do + path="${ROOT}/${slug}" + if [[ ! -d "${path}/.git" ]]; then + echo "SKIP ${slug} (no git checkout at ${path})" >&2 + continue + fi + if is_gitea_origin "$path"; then + echo "$slug" + else + echo "SKIP ${slug} (origin not gitea-remote)" >&2 + fi + done + return + fi + for path in "${ROOT}"/*/; do + [[ -d "${path}/.git" ]] || continue + slug="$(basename "$path")" + if is_gitea_origin "$path"; then + echo "$slug" + fi + done +} + +mapfile -t TARGETS < <(collect_targets "$@") +if [[ ${#TARGETS[@]} -eq 0 ]]; then + echo "No gitea-remote repos to migrate." + exit 0 +fi + +echo "=== Gitea → Forgejo migration (${#TARGETS[@]} repos) ===" +printf ' %s\n' "${TARGETS[@]}" + +if [[ "$DRY_RUN" == "1" ]]; then + echo "DRY_RUN=1 — no changes made." + exit 0 +fi + +if [[ ! -x "$PROMOTE" ]]; then + echo "ERROR: promote script not found: $PROMOTE" >&2 + exit 1 +fi + +FAILED=() +OK=() + +for slug in "${TARGETS[@]}"; do + echo "" + echo ">>> ${slug}" + if [[ "$SKIP_CI" == "1" ]]; then + export PROMOTE_CI_TEMPLATE=/dev/null + fi + if "$PROMOTE" "$slug" "${ROOT}/${slug}"; then + if [[ -x "$PATCH" ]]; then + "$PATCH" "$slug" || true + fi + OK+=("$slug") + else + echo "FAIL ${slug}" >&2 + FAILED+=("$slug") + fi +done + +echo "" +echo "=== Summary ===" +echo "OK (${#OK[@]}): ${OK[*]:-none}" +if [[ ${#FAILED[@]} -gt 0 ]]; then + echo "FAILED (${#FAILED[@]}): ${FAILED[*]}" + exit 1 +fi \ No newline at end of file