-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmigrate.py
More file actions
115 lines (101 loc) · 4.29 KB
/
Copy pathmigrate.py
File metadata and controls
115 lines (101 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import subprocess
import json
import os
import sys
import requests
from requests.auth import HTTPBasicAuth
from dotenv import load_dotenv
load_dotenv()
# Bitbucket: load from .env
bitbucket_username = os.getenv("BITBUCKET_USERNAME")
bitbucket_app_password = os.getenv("BITBUCKET_APP_PASSWORD")
bitbucket_workspace = os.getenv("BITBUCKET_WORKSPACE")
# GitHub: load from .env (gh CLI uses its own auth; token optional for API use)
github_token = os.getenv("GITHUB_TOKEN")
github_workspace = os.getenv("GITHUB_WORKSPACE")
def _check_credentials():
missing = []
if not bitbucket_username:
missing.append("BITBUCKET_USERNAME")
if not bitbucket_app_password:
missing.append("BITBUCKET_APP_PASSWORD")
if not bitbucket_workspace:
missing.append("BITBUCKET_WORKSPACE")
if not github_workspace:
missing.append("GITHUB_WORKSPACE")
if missing:
print("Missing required env vars. Copy .env.example to .env and set:", ", ".join(missing))
sys.exit(1)
# List Bitbucket repositories using basic authentication
def list_bitbucket_repos(url):
# Use HTTPBasicAuth for basic authentication
response = requests.get(url, auth=HTTPBasicAuth(bitbucket_username, bitbucket_app_password))
if response.status_code == 200:
# print(response.json())
return response.json()
else:
print(f"Failed to fetch Bitbucket repositories. Status code: {response.status_code}, Response: {response.text}")
return []
# Create GitHub repository
# def create_github_repo(repo_name):
# url = "https://api.github.com/user/repos"
# headers = {
# "Authorization": f"token {github_token}",
# "Accept": "application/vnd.github.v3+json"
# }
# data = {"name": repo_name}
# response = requests.post(url, json=data, headers=headers)
# if response.status_code == 201:
# return response.json()['clone_url']
# else:
# print(f"Failed to create GitHub repository {repo_name}")
# return None
# Main function to clone and push repos
def clone_and_push():
_check_credentials()
url = f"https://api.bitbucket.org/2.0/repositories/{bitbucket_workspace}?page=8"
repos = []
while url:
response = list_bitbucket_repos(url)
for repo in response['values']:
repo_name = repo['name']
repo_slug = repo['slug']
repo_description = repo['description']
bitbucket_url = repo['links']['clone'][1]['href']
repos.append({
"name": repo_name,
"slug": repo_slug,
"description": repo_description,
"http_url": repo['links']['clone'][0]['href'],
"ssh_url": repo['links']['clone'][1]['href'],
"project_key": repo['project']['key'],
"project_name": repo['project']['name'],
"created_on":repo['created_on'],
"updated_on":repo['updated_on'],
"size":repo['size'],
})
github_repo_name = f"{github_workspace}/{repo_slug}"
github_url = f"https://github.com/{github_repo_name}.git"
result = subprocess.run(["gh", "repo", "create", github_repo_name, "--private", "--description", repo_description], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode == 0:
print(f"\n\nStarted cloning and pushing {repo_name}({repo_slug}) to GitHub")
# Clone the Bitbucket repo
subprocess.run(["git", "clone", "--bare", bitbucket_url])
# Change directory to the cloned repo
os.chdir(repo_slug+".git")
# Push to GitHub
subprocess.run(["git", "push", "--mirror", github_url])
# Change back to the original directory
os.chdir("..")
# Delete the cloned repo
subprocess.run(["rm", "-rf", repo_slug+".git"])
print(f"Successfully cloned and pushed {repo_name}({repo_slug}) to GitHub")
else:
print(f"\n\nFailed to create {repo_slug} on GitHub. {result.stderr.decode()}")
# break
# Get the next page URL
url = response.get('next', None)
# url = None
# print(json.dumps(repos, indent=4))
if __name__ == "__main__":
clone_and_push()