diff --git a/gitlab2gitea/gitlab2gitea.py b/gitlab2gitea/gitlab2gitea.py index 8106206..ebed5f4 100644 --- a/gitlab2gitea/gitlab2gitea.py +++ b/gitlab2gitea/gitlab2gitea.py @@ -280,6 +280,16 @@ def _error(message): # PROGRAM +def gitlab2gitea_visibility(visibility: str) -> str: + if visibility == 'private': + return 'private' + elif visibility == 'internal': + return 'limited' + elif visibility == 'public': + return 'public' + else: + return 'private' + # Endpoint: GET /api/{GITLAB_API_VERSION}/version def check_gitlab(): _debug(f'REQUEST: GET {GITLAB_URL}/api/{GITLAB_API_VERSION}/version') @@ -364,11 +374,51 @@ def get_gitlab_group(group_id: int) -> dict: # Endpoint: GET /api/{GITLAB_API_VERSION}/users def get_gitlab_users() -> list: - pass + + users = [] + + _debug(f'REQUEST: GET {GITLAB_URL}/api/{GITLAB_API_VERSION}/users') + + response = requests.get(f'{GITLAB_URL}/api/{GITLAB_API_VERSION}/users', + headers={ + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': f'Bearer {GITLAB_TOKEN}' + }) + + _trace(f'RESPONSE: {response.json()}') + + if response.status_code != 200: + response_message = response.json()['message'] if 'message' in response.json() else 'Unknown error' + raise Exception(f'Failed to get GitLab users: {response_message}') + else: + users = response.json() + + return users # Endpoint: GET /api/{GITLAB_API_VERSION}/projects def get_gitlab_projects() -> list: - pass + + projects = [] + + _debug(f'REQUEST: GET {GITLAB_URL}/api/{GITLAB_API_VERSION}/projects') + + response = requests.get(f'{GITLAB_URL}/api/{GITLAB_API_VERSION}/projects', + headers={ + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': f'Bearer {GITLAB_TOKEN}' + }) + + _trace(f'RESPONSE: {response.json()}') + + if response.status_code != 200: + response_message = response.json()['message'] if 'message' in response.json() else 'Unknown error' + raise Exception(f'Failed to get GitLab projects: {response_message}') + else: + projects = response.json() + + return projects # Endpoint: GET /api/{GITEA_API_VERSION}/orgs def get_gitea_groups() -> list: @@ -393,36 +443,70 @@ def get_gitea_groups() -> list: # Endpoint: GET /api/{GITEA_API_VERSION}/users def get_gitea_users() -> list: - pass + + users = [] + + _debug(f'REQUEST: GET {GITEA_URL}/api/{GITEA_API_VERSION}/users/search') + + response = requests.get(f'{GITEA_URL}/api/{GITEA_API_VERSION}/users/search', + headers={ + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': f'token {GITEA_TOKEN}' + }) + + _trace(f'RESPONSE: {response.json()}') + + if response.status_code != 200: + response_message = response.json()['message'] if 'message' in response.json() else 'Unknown error' + raise Exception(f'Failed to get Gitea users: {response_message}') + else: + users = response.json() + + return users # Endpoint: GET /api/{GITEA_API_VERSION}/repos def get_gitea_projects() -> list: - pass + + projects = [] + + _debug(f'REQUEST: GET {GITEA_URL}/api/{GITEA_API_VERSION}/repos/search') + + response = requests.get(f'{GITEA_URL}/api/{GITEA_API_VERSION}/repos/search', + headers={ + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': f'token {GITEA_TOKEN}' + }) + + _trace(f'RESPONSE: {response.json()}') + + if response.status_code != 200: + response_message = response.json()['message'] if 'message' in response.json() else 'Unknown error' + raise Exception(f'Failed to get Gitea projects: {response_message}') + else: + projects = response.json() + + return projects # Endpoint: POST /api/{GITEA_API_VERSION}/orgs -def create_gitea_org(name: str, description: str = '', website: str = '', visibility: str = 'private') -> dict: +def create_gitea_org(name: str) -> dict: gitlab_group = get_gitlab_group(name) if not gitlab_group: raise Exception(f'GitLab group "{name}" does not exist!') - # Update detail fields - if description: - gitlab_group['description'] = description - - if website: - gitlab_group['web_url'] = website - # Create Gitea group _debug(f'REQUEST: POST {GITEA_URL}/api/{GITEA_API_VERSION}/orgs') response = requests.post(f'{GITEA_URL}/api/{GITEA_API_VERSION}/orgs', json={ 'username': name, + 'full_name': gitlab_group['full_name'], 'description': gitlab_group['description'], 'website': gitlab_group['web_url'], - 'visibility': visibility + 'visibility': gitlab2gitea_visibility(gitlab_group['visibility']) }, headers={ 'Content-Type': 'application/json', 'Accept': 'application/json', @@ -439,6 +523,29 @@ def create_gitea_org(name: str, description: str = '', website: str = '', visibi return group +# Endpoint: PATCH /api/{GITEA_API_VERSION}/orgs/{org} +def update_gitea_org(name: str, data: dict) -> dict: + + # Update Gitea group + + _debug(f'REQUEST: PATCH {GITEA_URL}/api/{GITEA_API_VERSION}/orgs/{name}') + + response = requests.patch(f'{GITEA_URL}/api/{GITEA_API_VERSION}/orgs/{name}', json=data, headers={ + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': f'token {GITEA_TOKEN}' + }) + + _trace(f'RESPONSE: {response.json()}') + + if response.status_code != 200: + response_message = response.json()['message'] if 'message' in response.json() else 'Unknown error' + raise Exception(f'Failed to update Gitea group: {response_message}') + else: + group = response.json() + + return group + def cmp_gitlab_gitea_groups(gitlab_groups: list, gitea_groups: list) -> dict: # 0 = exists on both @@ -570,6 +677,29 @@ def create_missing_groups(gitlab_groups: list, gitea_groups: list): except Exception as e: _error(f'Failed to create Gitea group "{name}": {e}') +def update_existing_groups(gitlab_groups: list, gitea_groups: list): + for gitlab_group in gitlab_groups: + name = gitlab_group['path'] + exists = False + + for gitea_group in gitea_groups: + if name == gitea_group['name']: + exists = True + break + + if exists: + _info(f'Updating existing group "{name}" on Gitea...') + + try: + update_gitea_org(name, { + 'description': gitlab_group['description'], + 'website': gitlab_group['web_url'], + 'visibility': gitlab2gitea_visibility(gitlab_group['visibility']), + 'full_name': gitlab_group['full_name'] + }) + except Exception as e: + _error(f'Failed to update Gitea group "{name}": {e}') + def run_migration(): _info('Migrating GitLab groups...') @@ -589,14 +719,25 @@ def run_migration(): if missing_matches > 0 and CREATE_MISSING_GROUPS: _info('Creating missing groups on Gitea...') - create_missing_groups(gitlab_groups, gitea_groups) + _info('Updating existing groups on Gitea...') + + try: + update_existing_groups(gitlab_groups, gitea_groups) + except Exception as e: + _error(f'Failed to update existing groups: {e}') + _info('Migrating GitLab users...') gitlab_users = get_gitlab_users() gitea_users = get_gitea_users() + _debug(f'Users on GitLab: {len(gitlab_users)}') + _trace(f'Users on GitLab: {gitlab_users}') + _debug(f'Users on Gitea: {len(gitea_users)}') + _trace(f'Users on Gitea: {gitea_users}') + cmp_gitlab_gitea_users(gitlab_users, gitea_users) _info('Migrating GitLab projects...') @@ -604,6 +745,11 @@ def run_migration(): gitlab_projects = get_gitlab_projects() gitea_projects = get_gitea_projects() + _debug(f'Projects on GitLab: {len(gitlab_projects)}') + _trace(f'Projects on GitLab: {gitlab_projects}') + _debug(f'Projects on Gitea: {len(gitea_projects)}') + _trace(f'Projects on Gitea: {gitea_projects}') + cmp_gitlab_gitea_projects(gitlab_projects, gitea_projects) def main():