Initial own-git docs, configs, scripts, and hardening pack

This commit is contained in:
PTah
2026-04-21 21:37:43 +10:00
commit f5899ebc56
25 changed files with 1843 additions and 0 deletions
+156
View File
@@ -0,0 +1,156 @@
#!/usr/bin/env bash
set -euo pipefail
# Массовая миграция репозиториев GitHub -> Gitea.
# Переносит всю git-историю через mirror push. Может переносить LFS (опционально).
: "${GITHUB_TOKEN:?Set GITHUB_TOKEN}"
: "${GITHUB_OWNER:?Set GITHUB_OWNER (user or org on GitHub)}"
: "${GITHUB_OWNER_TYPE:?Set GITHUB_OWNER_TYPE=user|org}"
: "${GITEA_URL:?Set GITEA_URL, e.g. https://git.papatramp.ru}"
: "${GITEA_TOKEN:?Set GITEA_TOKEN (Gitea PAT)}"
: "${GITEA_OWNER:?Set GITEA_OWNER (target user/org in Gitea)}"
: "${GITEA_OWNER_TYPE:?Set GITEA_OWNER_TYPE=user|org}"
WORKDIR="${WORKDIR:-$PWD/migration-workdir}"
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
mkdir -p "$WORKDIR"
need_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "Missing command: $1"; exit 1; }; }
need_cmd curl
need_cmd jq
need_cmd git
if [[ "$MIGRATE_LFS" == "true" ]]; then
need_cmd git-lfs
fi
gh_api() {
local url="$1"
curl -fsSL \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
"$url"
}
gitea_api() {
local method="$1"
local url="$2"
local data="${3:-}"
if [[ -n "$data" ]]; then
curl -sS -o /tmp/gitea_resp.json -w "%{http_code}" \
-X "$method" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "$data" \
"$url"
else
curl -sS -o /tmp/gitea_resp.json -w "%{http_code}" \
-X "$method" \
-H "Authorization: token $GITEA_TOKEN" \
"$url"
fi
}
create_gitea_repo_if_needed() {
local repo_name="$1"
local private="$2"
local payload endpoint code
payload="$(jq -n --arg name "$repo_name" --argjson private "$private" \
'{name:$name, private:$private, auto_init:false}')"
if [[ "$GITEA_OWNER_TYPE" == "org" ]]; then
endpoint="$GITEA_URL/api/v1/orgs/$GITEA_OWNER/repos"
else
endpoint="$GITEA_URL/api/v1/user/repos"
fi
code="$(gitea_api POST "$endpoint" "$payload")"
if [[ "$code" == "201" ]]; then
echo " [OK] Created: $GITEA_OWNER/$repo_name"
elif [[ "$code" == "409" ]]; then
echo " [SKIP] Exists: $GITEA_OWNER/$repo_name"
else
echo " [ERR] Create repo failed: HTTP $code"
cat /tmp/gitea_resp.json
return 1
fi
}
push_mirror() {
local mirror_dir="$1"
local repo_name="$2"
local remote_url
if [[ "$PUSH_WITH_SSH" == "true" ]]; then
remote_url="ssh://git@${GITEA_SSH_HOST}:${GITEA_SSH_PORT}/${GITEA_OWNER}/${repo_name}.git"
else
: "${GITEA_USERNAME:?Set GITEA_USERNAME when PUSH_WITH_SSH=false}"
remote_url="https://${GITEA_USERNAME}:${GITEA_TOKEN}@${GITEA_URL#https://}/${GITEA_OWNER}/${repo_name}.git"
fi
if git -C "$mirror_dir" remote | grep -q '^gitea$'; then
git -C "$mirror_dir" remote set-url gitea "$remote_url"
else
git -C "$mirror_dir" remote add gitea "$remote_url"
fi
git -C "$mirror_dir" push --mirror gitea
}
migrate_repo() {
local full_name="$1"
local private="$2"
local repo_name="${full_name##*/}"
local mirror_dir="$WORKDIR/${repo_name}.git"
echo "=== $full_name (private=$private) ==="
rm -rf "$mirror_dir"
git -c http.extraHeader="Authorization: Bearer $GITHUB_TOKEN" \
clone --mirror "https://github.com/${full_name}.git" "$mirror_dir"
create_gitea_repo_if_needed "$repo_name" "$private"
push_mirror "$mirror_dir" "$repo_name"
if [[ "$MIGRATE_LFS" == "true" ]]; then
git -C "$mirror_dir" lfs fetch --all || true
git -C "$mirror_dir" lfs push --all gitea || true
fi
echo " [DONE] $full_name"
}
main() {
local page=1
local per_page=100
local url repos_json count
while true; do
if [[ "$GITHUB_OWNER_TYPE" == "org" ]]; then
url="https://api.github.com/orgs/${GITHUB_OWNER}/repos?type=all&per_page=${per_page}&page=${page}"
else
url="https://api.github.com/users/${GITHUB_OWNER}/repos?type=owner&per_page=${per_page}&page=${page}"
fi
repos_json="$(gh_api "$url")"
count="$(echo "$repos_json" | jq 'length')"
[[ "$count" -eq 0 ]] && break
while IFS=$'\t' read -r full_name private; do
migrate_repo "$full_name" "$private"
done < <(echo "$repos_json" | jq -r '.[] | [.full_name, .private] | @tsv')
((page++))
done
echo "All repositories migrated."
}
main