因为目前需要开发一个和gitlab相关的需求,需要使用到GitLab的API,而我采用的思路是使用python的第三方库(python-gitlab)。
GitLab官方文档:GitLab
Python-gitlab官方文档:python-gitlab
GitLab 11.0后不支持 API v3,需要先查看 GitLab版本:
GitLab版本 ≥ 11.0 安装
pip install python-gitlab
否则安装
pip install python-gitlab==1.4.0
可以不安装这个可以,可以直接调用GitLab提供的API,具体参考:GitLab API Documentation 或者GitLab中Help中的API
使用API之前需要获取Token,用于免密登录。
及时保存Token,后续Token不能复制,只能重新生成。
直接调用GitLab API
import requests
import urllib.parse
url = 'https://gitlab.example.com/' # 你的GitLab地址
url = urllib.parse.urljoin(url, '/api/v3/projects')
params = {
'private_token': 'xxx', # 你的Private token
}
data = requests.get(url, params)
print(data.json())
# [{'id': 93, 'description': 'xxx', 'default_branch': 'develop', 'public': False, 'archived': False, 'visibility_level': 10, 'ssh_url_to_repo': '[email protected]:xxx/xxx.git', 'http_url_to_repo': 'https://gitlab.example.com/xxx/xxx.git', 'web_url': 'https://gitlab.example.com/xxx/xxx', 'name': 'xxx', 'name_with_namespace': 'xxx / xxx', 'path': 'xxx', 'path_with_namespace': 'xxx/xxx', 'issues_enabled': True, 'merge_requests_enabled': True, 'wiki_enabled': True, 'snippets_enabled': False, 'created_at': '2015-04-28T10:30:22.126Z', 'last_activity_at': '2020-12-28T02:35:55.104Z', 'namespace': {'id': 29, 'name': 'xxx', 'path': 'xxx', 'owner_id': None, 'created_at': '2015-04-27T10:18:20.834Z', 'updated_at': '2015-04-27T10:18:20.834Z', 'description': '', 'avatar': {'url': None}}}]
调用python-gitlab
import gitlab
url = 'https://gitlab.example.com/'
private_token = 'xxx'
gl = gitlab.Gitlab(url, private_token, api_version='3')
print(gl.projects.list())
如果页面有这样的登录框需要鉴权,否则报错 401 Authorization Required
使用这个来登录
import gitlab
url = 'https://gitlab.example.com/'
private_token = 'xxx'
http_username = 'xxx'
http_password = 'xxx'
gl = gitlab.Gitlab(url, private_token, http_username=http_username, http_password=http_password)
print(gl.projects.list())
import os
import time
import gitlab
import zipfile
def loginGitlab(gitlabUrl, token, userID=None, userPwd=None):
"""
使用Token登录GitLab
登陆账号可以默认不填,如果出现需要使用对话框登录的话需要填写,用于鉴权
:param gitlabUrl: GitLab地址
:param token: GitLab登陆账号Token
:param userID: GitLab账号
:param userPwd: GitLab密码
:return: GitLab登录连接
"""
gl = gitlab.Gitlab(gitlabUrl, private_token=token, http_username=userID, http_password=userPwd)
return gl
def getItem(gl, ItemName):
"""
通过项目名称,获取对应项目信息
:param gl: GitLab登录连接
:param ItemName: 项目名称
:return: 项目信息
"""
projectNameDir = {item.name: item.id for item in gl.projects.list(all=True, recursive=True)}
project = gl.projects.get(projectNameDir[ItemName])
return project
def createDir(dirName):
"""
创建项目对应文件夹
:param dirName: 项目的文件夹
:return:
"""
if not os.path.isdir(dirName):
# print("\033[0;32;40m开始创建目录: \033[0m{0}".format(dirName))
os.makedirs(dirName)
time.sleep(0.1)
def downloadFiles(project, rootPath, companyBranchName):
"""
下载项目文件
:param project:需要下载的项目信息
:param rootPath: 下载文件存放地址
:param companyBranchName:客户公司对应的开发分支
:return:
"""
info = project.repository_tree(all=True, recursive=True, ref=companyBranchName)
if not os.path.isdir(rootPath):
os.makedirs(rootPath)
fileList = []
os.chdir(rootPath)
# 调用创建目录的函数并生成文件名列表
for info_dir in range(len(info)):
if info[info_dir]['type'] == 'tree':
dirName = info[info_dir]['path']
createDir(dirName)
else:
fileName = info[info_dir]['path']
fileList.append(fileName)
for fileInfo in fileList:
getFile = project.files.get(file_path=fileInfo, ref=companyBranchName)
content = getFile.decode()
with open(fileInfo, 'wb') as code:
# print("\033[0;32;40m开始下载文件: \033[0m{0}".format(fileInfo))
code.write(content)
def packFiles(dirpath):
"""
项目文件打包
:param dirpath: 本地项目文件地址
:return:包文件地址
"""
output_name = f"{dirpath}.zip"
parent_name = os.path.dirname(dirpath)
zip = zipfile.ZipFile(output_name, "w", zipfile.ZIP_DEFLATED)
# 多层级压缩
for root, dirs, files in os.walk(dirpath):
for file in files:
if str(file).startswith("~$"):
continue
filepath = os.path.join(root, file)
writepath = os.path.relpath(filepath, parent_name)
zip.write(filepath, writepath)
zip.close()
return output_name
def uploadPackFile(packagePath, companyName, companyItem):
def delFile(path):
for i in os.listdir(path):
file_data = path + "\\" + i
if os.path.isfile(file_data):
os.remove(file_data)
else:
delFile(file_data)
filesPath, _ = os.path.split(packagePath)
fileDirPath = r"{}\{}_{}".format(filesPath, companyName, companyItem)
delFile(fileDirPath)
# os.rmdir(fileDirPath)
if __name__ == '__main__':
##########配置项############
gitlabUrl = 'http://xxxxxxxx'
token = '' # 账号 Token
targetPath = r'E:\GitlabDownloadTest'
##########################
rootPath = r'{}/{}_{}'.format(targetPath, companyName, companyItem)
gl = loginGitlab(gitlabUrl, token)
project = getItem(gl, companyItem)
downloadFiles(project, rootPath, companyBranch)
packPath = packFiles(rootPath)
uploadPackFile(packPath, companyName, companyItem)