diff --git a/.env.example b/.env.example index 93719f5..7e8099a 100644 --- a/.env.example +++ b/.env.example @@ -21,3 +21,7 @@ GITEA_USERNAME=your_gitea_username # Optional behavior MIGRATE_LFS=true WORKDIR=./migration-workdir + +# Только указанные репозитории GitHub (полное имя owner/repo). Если задано — общий список с GitHub не опрашивается. +# GITHUB_REPOS=PTah/repo1,PTah/repo2 +# GITHUB_REPOS_FILE=/path/repos-to-migrate.txt diff --git a/README.md b/README.md index bbd25c3..3bbd99e 100644 --- a/README.md +++ b/README.md @@ -262,6 +262,18 @@ ssh -T git-papatramp - делает `git clone --mirror` + `git push --mirror`; - умеет мигрировать LFS (опционально). +**Только выбранные репозитории** (не весь аккаунт): + +- переменная **`GITHUB_REPOS`** — через запятую полные имена **`owner/repo`**; +- и/или **`GITHUB_REPOS_FILE`** — путь к файлу, по одному **`owner/repo`** в строке, строки с **`#`** — комментарии. + +Пример: + +```bash +export GITHUB_REPOS="PTah/app1,PTah/app2" +# или: export GITHUB_REPOS_FILE=/root/repos-to-migrate.txt +``` + Пуш в Gitea по умолчанию идёт по **SSH**. Если скрипт запускается **на самом сервере Gitea** (или под `root`) и там **нет SSH-ключа**, добавленного в ваш аккаунт Gitea, будет `Permission denied (publickey)`. Тогда используйте пуш по HTTPS: **`export PUSH_WITH_SSH=false`** и **`export GITEA_USERNAME=`** ваш логин в Gitea (пароль — ваш **`GITEA_TOKEN`**). Пример запуска: diff --git a/scripts/migrate-github-to-gitea.sh b/scripts/migrate-github-to-gitea.sh index 5a8d518..5587919 100644 --- a/scripts/migrate-github-to-gitea.sh +++ b/scripts/migrate-github-to-gitea.sh @@ -6,6 +6,11 @@ set -euo pipefail # # Пуш в Gitea: PUSH_WITH_SSH=true — нужен SSH-ключ на ЭТОЙ машине (добавлен в Gitea). # На сервере без ключа — PUSH_WITH_SSH=false и GITEA_USERNAME + GITEA_TOKEN (HTTPS). +# +# Только выбранные репозитории (вместо полного списка с GitHub): +# GITHUB_REPOS="owner/repo1,owner/repo2" +# и/или +# GITHUB_REPOS_FILE=/path/to/list.txt # по одному owner/repo на строку, # — комментарий : "${GITHUB_TOKEN:?Set GITHUB_TOKEN}" : "${GITHUB_OWNER:?Set GITHUB_OWNER (user or org on GitHub)}" @@ -21,6 +26,9 @@ PUSH_WITH_SSH="${PUSH_WITH_SSH:-true}" # true/false GITEA_SSH_HOST="${GITEA_SSH_HOST:-git.papatramp.ru}" GITEA_SSH_PORT="${GITEA_SSH_PORT:-2222}" MIGRATE_LFS="${MIGRATE_LFS:-false}" # true/false +# См. шапку: если задано — мигрируются только эти репозитории (полный вид owner/name). +GITHUB_REPOS="${GITHUB_REPOS:-}" +GITHUB_REPOS_FILE="${GITHUB_REPOS_FILE:-}" mkdir -p "$WORKDIR" @@ -133,7 +141,68 @@ migrate_repo() { echo " [DONE] $full_name" } +migrate_repo_from_github_api() { + local full_name="$1" + local repo_json private + repo_json="$(gh_api "https://api.github.com/repos/${full_name}")" + if ! echo "$repo_json" | jq -e '.full_name' >/dev/null 2>&1; then + echo "[ERR] Репозиторий недоступен или не найден на GitHub: ${full_name}" + echo "$repo_json" | jq -r '.message // .' 2>/dev/null || echo "$repo_json" + exit 1 + fi + private="$(echo "$repo_json" | jq -r '.private')" + migrate_repo "$full_name" "$private" +} + +migrate_selected_repos() { + local names=() line part + if [[ -n "$GITHUB_REPOS_FILE" ]]; then + if [[ ! -f "$GITHUB_REPOS_FILE" ]]; then + echo "[ERR] GITHUB_REPOS_FILE не найден: $GITHUB_REPOS_FILE" + exit 1 + fi + while IFS= read -r line || [[ -n "$line" ]]; do + line="${line%%#*}" + line="$(echo "$line" | xargs)" + [[ -z "$line" ]] && continue + names+=("$line") + done <"$GITHUB_REPOS_FILE" + fi + if [[ -n "$GITHUB_REPOS" ]]; then + local -a repo_parts + IFS=',' read -ra repo_parts <<<"${GITHUB_REPOS}" + for part in "${repo_parts[@]}"; do + part="$(echo "$part" | xargs)" + [[ -z "$part" ]] && continue + names+=("$part") + done + fi + + if [[ "${#names[@]}" -eq 0 ]]; then + echo "[ERR] Указаны GITHUB_REPOS / GITHUB_REPOS_FILE, но список имён пуст." + exit 1 + fi + + echo "[INFO] Режим выборочной миграции, репозиториев: ${#names[@]}" + + local fn + for fn in "${names[@]}"; do + if [[ "$fn" != */* ]]; then + echo "[ERR] Ожидается полное имя owner/repo, получено: $fn" + exit 1 + fi + migrate_repo_from_github_api "$fn" + done + + echo "Выбранные репозитории обработаны." +} + main() { + if [[ -n "$GITHUB_REPOS" || -n "$GITHUB_REPOS_FILE" ]]; then + migrate_selected_repos + return 0 + fi + local page=1 local per_page=100 local url repos_json count