diff options
Diffstat (limited to 'packages/import-gh-to-gitea')
-rw-r--r-- | packages/import-gh-to-gitea/README.org | 12 | ||||
-rwxr-xr-x | packages/import-gh-to-gitea/archive-projects.py | 49 | ||||
-rwxr-xr-x | packages/import-gh-to-gitea/delete-gh-repositories.py | 84 | ||||
-rwxr-xr-x | packages/import-gh-to-gitea/import-gh-to-gitea.py | 62 |
4 files changed, 207 insertions, 0 deletions
diff --git a/packages/import-gh-to-gitea/README.org b/packages/import-gh-to-gitea/README.org new file mode 100644 index 0000000..2e26b88 --- /dev/null +++ b/packages/import-gh-to-gitea/README.org @@ -0,0 +1,12 @@ +#+TITLE: Import GitHub repositories to gitea + +Scripts to move my repositories from GitHub to my instance of [[https://git.fcuny.net][gitea]]. + +* import repositories +#+begin_src sh +python3.10 import-gh-to-gitea.py -g (pass api/github/terraform|psub) -G (pass api/git.fcuny.net/gh-import|psub) +#+end_src +* archiving repositories +#+begin_src sh +python3.10 archive-projects.py -t (pass api/git.fcuny.net/gh-import|psub) +#+end_src diff --git a/packages/import-gh-to-gitea/archive-projects.py b/packages/import-gh-to-gitea/archive-projects.py new file mode 100755 index 0000000..41bd898 --- /dev/null +++ b/packages/import-gh-to-gitea/archive-projects.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +import argparse + +import requests + + +def main(api_token): + s = requests.Session() + s.headers.update({"Authorization": f"token {api_token}"}) + s.headers.update({"Accept": "application/json"}) + s.headers.update({"Content-Type": "application/json"}) + + not_done = True + page = 1 + while not_done: + url = f"https://git.fcuny.net/api/v1/user/repos?page={page}&limit=10" + res = s.get( + url, + timeout=5, + ) + res.raise_for_status() + + repos = res.json() + if len(repos) == 0: + not_done = False + else: + page = page + 1 + + for repo in repos: + if repo.get("owner").get("login") == "attic": + if repo.get("archived") is False: + name = repo.get("name") + data = {"archived": True} + res = s.patch( + f"https://git.fcuny.net/api/v1/repos/attic/{name}", json=data + ) + res.raise_for_status() + print(f"set {name} to archived: {res.status_code}") + + +if __name__ == "__main__": + argp = argparse.ArgumentParser() + argp.add_argument("-t", "--token-file", nargs=1, type=argparse.FileType("r")) + + args = argp.parse_args() + api_token = args.token_file[0].readline().strip() + + main(api_token) diff --git a/packages/import-gh-to-gitea/delete-gh-repositories.py b/packages/import-gh-to-gitea/delete-gh-repositories.py new file mode 100755 index 0000000..b87c0f6 --- /dev/null +++ b/packages/import-gh-to-gitea/delete-gh-repositories.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3.10 + +import argparse + +import requests + + +def main(gitea_api_token, gh_api_token): + gitea = requests.Session() + gitea.headers.update({"Authorization": f"token {gitea_api_token}"}) + gitea.headers.update({"Accept": "application/json"}) + gitea.headers.update({"Content-Type": "application/json"}) + + not_done = True + page = 1 + + gitea_repos = [] + while not_done: + url = f"https://git.fcuny.net/api/v1/user/repos?page={page}&limit=10" + res = gitea.get( + url, + timeout=5, + ) + res.raise_for_status() + + repos = res.json() + if len(repos) == 0: + not_done = False + else: + page = page + 1 + + for repo in repos: + name = repo.get("name") + gitea_repos.append(name) + + github = requests.Session() + github.headers.update({"Authorization": f"token {gh_api_token}"}) + github.headers.update({"Accept": "application/vnd.github.v3+json"}) + + not_done = True + page = 1 + github_repos = [] + while not_done: + url = f"https://api.github.com/user/repos?page={page}&type=all" + res = github.get( + url, + timeout=5, + ) + res.raise_for_status() + repos = res.json() + if len(repos) == 0: + not_done = False + else: + page = page + 1 + + for repo in repos: + name = repo.get("name") + if ( + repo.get("owner").get("login") == "fcuny" + and repo.get("private") == True + ): + github_repos.append(name) + + for repo in github_repos: + if repo in gitea_repos: + url = f"https://api.github.com/repos/fcuny/{repo}" + print(f"deleting {url}") + res = github.delete( + url, + timeout=5, + ) + res.raise_for_status() + + +if __name__ == "__main__": + argp = argparse.ArgumentParser() + argp.add_argument("-t", "--gt-file", nargs=1, type=argparse.FileType("r")) + argp.add_argument("-T", "--gh-file", nargs=1, type=argparse.FileType("r")) + + args = argp.parse_args() + gitea_api_token = args.gt_file[0].readline().strip() + github_api_token = args.gh_file[0].readline().strip() + + main(gitea_api_token, github_api_token) diff --git a/packages/import-gh-to-gitea/import-gh-to-gitea.py b/packages/import-gh-to-gitea/import-gh-to-gitea.py new file mode 100755 index 0000000..b59c8eb --- /dev/null +++ b/packages/import-gh-to-gitea/import-gh-to-gitea.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + + +import argparse + +import requests + + +def main(gh_api_token, gitea_api_token): + s = requests.Session() + s.headers.update({"Authorization": f"token {gh_api_token}"}) + s.headers.update({"Accept": "application/vnd.github.v3+json"}) + + # hardcoded number of items per page, pagination is not handled. + res = s.get("https://api.github.com/user/repos?per_page=200&type=all", timeout=5) + res.raise_for_status() + + repos = res.json() + + gts = requests.Session() + gts.headers.update({"Accept": "application/json"}) + gts.headers.update({"Content-Type": "application/json"}) + gts.headers.update({"Authorization": f"token {gitea_api_token}"}) + for repo in repos: + # archived projects go to the attic. + owner = "" + if repo.get("archived"): + owner = "attic" + else: + owner = "fcuny" + + data = { + "auth_username": "fcuny", + "auth_token": gh_api_token, + "clone_addr": repo.get("html_url"), + "mirror": False, + "private": repo.get("private"), + "repo_name": repo.get("name"), + "repo_owner": owner, + "service": "git", + "description": repo.get("description"), + } + print(f"importing {data['repo_name']} from {data['clone_addr']}") + res = gts.post( + "https://git.fcuny.net/api/v1/repos/migrate", + json=data, + ) + try: + res.raise_for_status() + except Exception as e: + print(f"failed for {data['repo_name']} with {e}") + + +if __name__ == "__main__": + argp = argparse.ArgumentParser() + argp.add_argument("-g", "--gh-token-file", nargs=1, type=argparse.FileType("r")) + argp.add_argument("-G", "--gitea-token-file", nargs=1, type=argparse.FileType("r")) + args = argp.parse_args() + + gh_api_token = args.gh_token_file[0].readline().strip() + gitea_api_token = args.gitea_token_file[0].readline().strip() + main(gh_api_token, gitea_api_token) |