1
0
Fork 0
bag-of-tricks/migrate_repos_gh_to_forgejo.py

99 lines
2.4 KiB
Python

"""
Repository migration script
Facilitates the migration from Github to Forgejo by importing
all public/private repositories owned by the user attached to
the personal token included.
Expects a single argument that points to a json configuration
shaped like Config.
"""
# /// script
# dependencies = [
# "httpx",
# "pydantic"
# ]
# ///
import sys
import httpx
import pydantic
class Config(pydantic.BaseModel):
gh_user: str
gh_token: str
gh_host: str
gh_api_host: str
forgejo_host: str
forgejo_user: str
forgejo_token: str
def get_config(path: str) -> Config:
return Config.parse_file(path)
def get_gh_client(config: Config):
return httpx.Client(
headers={
"Authorization": f"Bearer {config.gh_token}",
"X-Github-Api-Version": "2022-11-28",
},
base_url=config.gh_api_host,
)
def get_forgejo_client(config: Config):
return httpx.Client(
headers={"Authorization": f"token {config.forgejo_token}"},
base_url=config.forgejo_host,
)
def get_repositories_from_github(config: Config) -> list[str]:
"""Gets all repositories for given user."""
with get_gh_client(config) as client:
response = client.get(
f"/user/repos", params={"per_page": 100, "affiliation": "owner"}
)
for repository in response.json():
full_name = repository["full_name"]
if not full_name.startswith(config.gh_user):
print(f"Skipped {full_name}: not owned.")
continue
yield full_name
def migrate_to_forgejo(repository_name: str, config: Config):
with get_forgejo_client(config) as client:
response = client.post(
"/repos/migrate",
data={
"auth_username": config.gh_user,
"auth_token": config.gh_token,
"clone_addr": f"{config.gh_host}/{repository_name}.git",
"repo_name": repository_name.split("/")[1],
},
timeout=None,
)
if response.status_code == 409:
print(f"Did not migrate {repository_name}: already exists")
elif response.status_code == 201:
print(f"Migrated {repository_name}")
if __name__ == "__main__":
config = get_config(sys.argv[1])
for repo in get_repositories_from_github(config):
print(f"Migrating {repo}...")
migrate_to_forgejo(repo, config)