feat(migrate): GITHUB_REPOS and GITHUB_REPOS_FILE for selective import
Scripts And Docs Check / shellcheck (push) Has been cancelled
Scripts And Docs Check / markdown-links (push) Has been cancelled

Made-with: Cursor
This commit is contained in:
PTah
2026-04-22 15:46:09 +10:00
parent f6c805163a
commit 72746cf415
3 changed files with 85 additions and 0 deletions
+4
View File
@@ -21,3 +21,7 @@ GITEA_USERNAME=your_gitea_username
# Optional behavior # Optional behavior
MIGRATE_LFS=true MIGRATE_LFS=true
WORKDIR=./migration-workdir WORKDIR=./migration-workdir
# Только указанные репозитории GitHub (полное имя owner/repo). Если задано — общий список с GitHub не опрашивается.
# GITHUB_REPOS=PTah/repo1,PTah/repo2
# GITHUB_REPOS_FILE=/path/repos-to-migrate.txt
+12
View File
@@ -262,6 +262,18 @@ ssh -T git-papatramp
- делает `git clone --mirror` + `git push --mirror`; - делает `git clone --mirror` + `git push --mirror`;
- умеет мигрировать LFS (опционально). - умеет мигрировать 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`**). Пуш в Gitea по умолчанию идёт по **SSH**. Если скрипт запускается **на самом сервере Gitea** (или под `root`) и там **нет SSH-ключа**, добавленного в ваш аккаунт Gitea, будет `Permission denied (publickey)`. Тогда используйте пуш по HTTPS: **`export PUSH_WITH_SSH=false`** и **`export GITEA_USERNAME=`** ваш логин в Gitea (пароль — ваш **`GITEA_TOKEN`**).
Пример запуска: Пример запуска:
+69
View File
@@ -6,6 +6,11 @@ set -euo pipefail
# #
# Пуш в Gitea: PUSH_WITH_SSH=true — нужен SSH-ключ на ЭТОЙ машине (добавлен в Gitea). # Пуш в Gitea: PUSH_WITH_SSH=true — нужен SSH-ключ на ЭТОЙ машине (добавлен в Gitea).
# На сервере без ключа — PUSH_WITH_SSH=false и GITEA_USERNAME + GITEA_TOKEN (HTTPS). # На сервере без ключа — 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_TOKEN:?Set GITHUB_TOKEN}"
: "${GITHUB_OWNER:?Set GITHUB_OWNER (user or org on GitHub)}" : "${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_HOST="${GITEA_SSH_HOST:-git.papatramp.ru}"
GITEA_SSH_PORT="${GITEA_SSH_PORT:-2222}" GITEA_SSH_PORT="${GITEA_SSH_PORT:-2222}"
MIGRATE_LFS="${MIGRATE_LFS:-false}" # true/false MIGRATE_LFS="${MIGRATE_LFS:-false}" # true/false
# См. шапку: если задано — мигрируются только эти репозитории (полный вид owner/name).
GITHUB_REPOS="${GITHUB_REPOS:-}"
GITHUB_REPOS_FILE="${GITHUB_REPOS_FILE:-}"
mkdir -p "$WORKDIR" mkdir -p "$WORKDIR"
@@ -133,7 +141,68 @@ migrate_repo() {
echo " [DONE] $full_name" 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() { main() {
if [[ -n "$GITHUB_REPOS" || -n "$GITHUB_REPOS_FILE" ]]; then
migrate_selected_repos
return 0
fi
local page=1 local page=1
local per_page=100 local per_page=100
local url repos_json count local url repos_json count