Initial Commit

This commit is contained in:
Исправников Сергей Александрович 2020-06-04 21:35:23 +03:00
parent 3f0ad1c876
commit c8e7a2f7f5
3 changed files with 146 additions and 0 deletions

21
README.md Normal file
View file

@ -0,0 +1,21 @@
# BitBucket to Gitea migration tool.
## Description
Using BitBucket API we're getting repos, project of this repo, description and clone link.
Then, using Gitea API, creating organizations(gitea has no projects, but organizations replacing it fully), then starting migration for each repo from BitBucket.
## Using
* Create authentification token in bitbucket
* Create authentification token in gitea
* Create file props.py with parameters:
```
BitBucketURL='bitbucket url'
authTokenBB='bitbucket auth token'
GiteaURL='gitea url'
authTokenGitea='gitea auth token'
migrationUsername='user in bb, that have access to all repos'
migrationPassword='password'
```
run with
```python3 main.py```

119
main.py Normal file
View file

@ -0,0 +1,119 @@
import props
import requests
import json
import sys
import logging
#test commit
logging.basicConfig(level=logging.INFO, filename='migration.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
headersBB = {
'Authorization': 'Bearer ' + props.authTokenBB
}
headersGitea = {
'Authorization': 'token ' + props.authTokenGitea,
'Content-Type': 'application/json'
}
def getGiteaOrganizationID(orgName):
""" Gitea not accepting organization name as parameter, only it's uid, so we're gonna need to get it from API"""
GiteaOrgsOrgAPIurl = props.GiteaURL + '/api/v1/orgs/' + orgName
try:
GiteaGetOrgResponse = requests.get(GiteaOrgsOrgAPIurl, headers=headersGitea)
GiteaGetOrgResponse.raise_for_status()
except Exception as e:
print("%s, %s" % (e, GiteaGetOrgResponse.text))
logging.error("%s, %s" % (e, GiteaGetOrgResponse.text))
else:
GiteaOrgIdResponse = json.loads(GiteaGetOrgResponse.text)['id']
return GiteaOrgIdResponse
def startRepoMigration(cloneUrl, repoName, projectName):
""" we're now have all, that we need, let's start migration """
print("\nstarting migration of %s......\n" % (repoName))
logging.info("starting migration of %s......" % (repoName))
GiteaRepoAPIurl = props.GiteaURL + '/api/v1/repos/migrate'
uid = getGiteaOrganizationID(projectName)
repoPostData = {
"auth_password": props.migrationPassword,
"auth_username": props.migrationUsername,
"clone_addr": cloneUrl,
# "description": "string",
"issues": True,
"labels": True,
"milestones": True,
"mirror": True,
"private": True,
"pull_requests": True,
"releases": True,
"repo_name": repoName,
"uid": uid,
"wiki": True
}
try:
startRepoMigrationresponse = requests.post(GiteaRepoAPIurl, json = repoPostData, headers = headersGitea)
startRepoMigrationresponse.raise_for_status()
except Exception as e:
print("%s, : Exception: %s, Response: %s" % (repoName, e, startRepoMigrationresponse.text))
logging.error("%s, : Exception: %s, Response: %s" % (repoName, e, startRepoMigrationresponse.text))
else:
print("%s %s" % (repoName, startRepoMigrationresponse.text))
logging.info("%s %s" % (repoName, startRepoMigrationresponse.text))
def createGiteaOrganization(projectName, fullName, description):
""" before migration, we're gonna need to create organization, in which project will be stored """
print("\ncreating organization %s......\n" % (projectName))
logging.info("creating organization %s......" % (projectName))
GiteaOrgsAPIurl = props.GiteaURL + '/api/v1/orgs'
orgPostData = {
"username": projectName,
"full_name": fullName,
"description": description,
"repo_admin_change_team_access": True,
"visibility": "private"
}
try:
createGiteaOrganizationresponse = requests.post(GiteaOrgsAPIurl, json = orgPostData, headers = headersGitea)
createGiteaOrganizationresponse.raise_for_status()
except Exception as e:
print("Exception: %s \n Response: %s" % (e, createGiteaOrganizationresponse.text))
logging.error("Exception: %s \n Response: %s" % (e, createGiteaOrganizationresponse.text))
else:
print("Response: %s" % (createGiteaOrganizationresponse.text))
logging.info("Response: %s" % (createGiteaOrganizationresponse.text))
def getReposBB():
"""Get all bitbucket repos and it's parameters: clone url, repo name, project name, description."""
BitBucketAPIurl = props.BitBucketURL + "/rest/api/1.0/repos?limit=1000"
try:
response = requests.get(BitBucketAPIurl, headers=headersBB)
response.raise_for_status()
except Exception as e:
print("Exception: %s \n Response: %s" % (e, response.text))
logging.error("Exception: %s \n Response: %s" % (e, response.text))
else:
reposJson = json.loads(response.text)['values']
for repo in reposJson:
repoName = repo['name']
projectName = repo['project']['name']
try:
description = repo['project']['description']
except KeyError:
description = 'None'
cloneLink = props.BitBucketURL + "/scm/" + projectName + "/" + repoName + ".git"
print("Migrating: repo: %s with description: %s from project: %s via clonelink: %s" % (repoName, description, projectName, cloneLink))
logging.info("Migrating: repo: %s with description: %s from project: %s via clonelink: %s" % (repoName, description, projectName, cloneLink))
createGiteaOrganization(projectName, projectName, description)
startRepoMigration(cloneLink, repoName, projectName)
logging.info("_____________________________________________________________________________")
# sys.exit(1)
def main():
getReposBB()
main()

6
props.py Normal file
View file

@ -0,0 +1,6 @@
BitBucketURL='https://bitbucket.example.com'
authTokenBB='bitbucket auth token'
GiteaURL='https://gitea.example.com'
authTokenGitea='gitea auth token'
migrationUsername='user@example.com'
migrationPassword='password'