Initial Commit
This commit is contained in:
parent
3f0ad1c876
commit
c8e7a2f7f5
3 changed files with 146 additions and 0 deletions
21
README.md
Normal file
21
README.md
Normal 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
119
main.py
Normal 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
6
props.py
Normal 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'
|
||||||
Loading…
Add table
Add a link
Reference in a new issue