Created
January 20, 2025 02:36
-
-
Save tklee1975/aa2c29587a05cafc5bff8463113ca046 to your computer and use it in GitHub Desktop.
Script for GitLab to Github Repository Migration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gitlab_username: <your-gitlab-username> | |
gitlab_access_token: <your-gitlab-access-token> | |
github_username: <your-github-username> | |
github_access_token: <your-github-access-token> | |
github_repo_owner: <your-github-repo-owner username or organization name> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Pre-requisites: | |
# 1. Install GitHub CLI: https://cli.github.com/ | |
# 2. Install Git: https://git-scm.com/ | |
# 3. Install PyYAML: pip3 install pyyaml | |
# 4. Run 'gh auth login' to login to GitHub CLI | |
# 5. Prepare the configuration file with the following fields: | |
# gitlab_username: <GitLab username> | |
# gitlab_access_token: <GitLab access token> | |
# github_username: <GitHub username> | |
# github_access_token: <GitHub access token> | |
# github_repo_owner: <GitHub repository owner> | |
# 6. Get ready the GitLab project ID and GitHub repository name | |
# 7. Get ready the GitLab and Github access tokens | |
# 8. Run the script with the following command: | |
# python gitlab2github_migrate.py <config_file> <gitlab_project_id> <github_repo_name> | |
import subprocess | |
import yaml | |
import sys | |
import os | |
root_dir = os.path.dirname(os.path.realpath(__file__)) | |
def is_github_cli_logged_in(): | |
try: | |
result = subprocess.run( | |
["gh", "auth", "status"], capture_output=True, text=True | |
) | |
if "Logged in to github.com" in result.stdout: | |
return True | |
else: | |
return False | |
except FileNotFoundError: | |
print("GitHub CLI is not installed.") | |
return False | |
def load_config(config_file): | |
with open(config_file, "r") as file: | |
config = yaml.safe_load(file) | |
return config | |
def check_config(config): | |
required_fields = [ | |
"gitlab_username", | |
"gitlab_access_token", | |
"github_username", | |
"github_access_token", | |
"github_repo_owner", | |
] | |
result = True | |
for field in required_fields: | |
if field not in config: | |
print(f"Configuration file is missing {field}") | |
result = False | |
return result | |
def try_command(command): | |
try: | |
result = subprocess.run( | |
command, | |
capture_output=False, | |
text=True, | |
) | |
# if "Error" in result.stdout: | |
# return False | |
# else: | |
return True | |
except FileNotFoundError: | |
print("Command not found.") | |
return False | |
def get_github_repo_url(config, github_repo_name): | |
github_repo_owner = config.get("github_repo_owner") | |
github_access_token = config.get("github_access_token") | |
return f"https://{github_access_token}@github.com/{github_repo_owner}/{github_repo_name}.git" | |
def clone_repo_to_github(config, gitlab_project_id, github_repo_name): | |
folder_name = gitlab_project_id.split("/")[-1] + ".git" | |
full_folder_name = os.path.join(root_dir, folder_name) | |
github_repo_url = get_github_repo_url(config, github_repo_name) | |
print(f"folder_name: {folder_name}") | |
print(f"github_repo_url: {github_repo_url}") | |
try: | |
os.chdir(full_folder_name) | |
except FileNotFoundError: | |
print(f"Directory {folder_name} not found.") | |
return False | |
# try_command(["pwd"]) | |
if not try_command(["git", "remote", "remove", "origin"]): | |
print(f"Error removing remote origin") | |
return False | |
if not try_command(["git", "remote", "add", "origin", github_repo_url]): | |
print(f"Error adding remote origin") | |
return False | |
if not try_command(["git", "push", "--mirror", "origin"]): | |
print(f"Error pushing to remote origin") | |
return False | |
try: | |
os.chdir(root_dir) | |
except FileNotFoundError: | |
print(f"Directory {root_dir} not found.") | |
# return Falseif | |
# try_command(["pwd"]) | |
try: | |
os.system(f"rm -rf {folder_name}") | |
except FileNotFoundError: | |
print(f"Error removing directory {folder_name}") | |
# return False | |
print(f"Repository {folder_name} migrated to GitHub repository {github_repo_name}") | |
def get_gitlab_repo_url(config, gitlab_project_id): | |
gitlab_username = config.get("gitlab_username") | |
gitlab_access_token = config.get("gitlab_access_token") | |
return f"https://{gitlab_username}:{gitlab_access_token}@gitlab.com/{gitlab_project_id}.git" | |
def download_gitlab_repo(config, gitlab_project_id): | |
repo_url = get_gitlab_repo_url(config, gitlab_project_id) | |
print(f"repo_url: {repo_url}") | |
try: | |
result = subprocess.run( | |
[ | |
"git", | |
"clone", | |
"--bare", | |
repo_url, | |
], | |
capture_output=True, | |
text=True, | |
) | |
if "Error" in result.stdout: | |
print(f"Error cloning GitLab repository {repo_url}") | |
return False | |
else: | |
print(f"GitLab repository {repo_url} cloned successfully") | |
return True | |
except FileNotFoundError: | |
print("Git is not installed.") | |
return False | |
def create_github_repo(config, repo_name): | |
owner = config.get("github_repo_owner") | |
if owner == None: | |
repo_location = repo_name | |
else: | |
repo_location = owner + "/" + repo_name | |
try: | |
result = subprocess.run( | |
["gh", "repo", "create", repo_location, "--private", "--confirm"], | |
capture_output=True, | |
text=True, | |
) | |
if "Error" in result.stdout: | |
print(f"Error creating GitHub repository {repo_location}") | |
return False | |
else: | |
print(f"GitHub repository {repo_location} created successfully") | |
return True | |
except FileNotFoundError: | |
print("GitHub CLI is not installed.") | |
return False | |
# Example usage | |
if __name__ == "__main__": | |
if len(sys.argv) != 4: | |
print( | |
"Usage: python gitlab2github_migrate.py <config_file> <gitlab_project_id> <github_repo_name>" | |
) | |
exit(1) | |
config_file = sys.argv[1] | |
gitlab_project_id = sys.argv[2] | |
github_repo_name = sys.argv[3] | |
config = load_config(config_file) | |
if not check_config(config): | |
exit(1) | |
if not is_github_cli_logged_in(): | |
print("GitHub CLI is not logged in. Please run 'gh auth login'") | |
exit(1) | |
print("Migration Config") | |
print(yaml.dump(config, default_flow_style=False)) | |
# Example usage | |
if __name__ == "__main__": | |
# Output | |
print("Begin migration...") | |
print("Create GitHub repository") | |
create_github_repo(config, github_repo_name) | |
print(get_gitlab_repo_url(config, gitlab_project_id)) | |
result = download_gitlab_repo(config, gitlab_project_id) | |
if not result: | |
print("Error downloading GitLab repository") | |
exit(1) | |
clone_repo_to_github(config, gitlab_project_id, github_repo_name) | |
print("Migration complete.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment