获取gitlab上项目分支版本(二)

获取gitlab上项目分支版本_gitlab代码分支版本在哪-CSDN博客

原先写过一版,但是这次想更新一下项目的分支信息时,提示我

git服务器上的Python版本是2.7.3,这个错误表明当前Python环境中没有安装requests库,服务器也没有连接外网,所以排除了上面的方法。换了一种方式是获取列表后 测试发现是输出到屏幕,想直接生成一个表格,这样便于后面分析。计划是使用xlwt库来创建Excel文件的,但是机器里也没有安装xlwt,所以采用CSV代替Excel, Python内置的csv模块,无需额外安装,输出为CSV格式,可直接用Excel打开。

  1. 文件管理

    • 自动创建输出目录GitLab_Branch_Reports

    • 文件名包含时间戳,便于区分不同时间的报告

  2. 输出格式优化

    • 表头:项目ID, 项目名称, 分支数量, 分支列表

    • 分支列表以逗号分隔,方便查看。

使用说明

  1. 将脚本保存为gitlab_branches_csv.py

  2. 在命令行中运行:python gitlab_branches_csv.py

  3. 脚本运行完成后,在GitLab_Branch_Reports目录下找到CSV文件

  4. 用Excel打开CSV文件查看结果

    python 复制代码
    # -*- coding: utf-8 -*-
    import urllib2
    import json
    import time
    import sys
    import socket
    import csv
    import os
    from datetime import datetime
    
    # 配置信息
    GITLAB_URL = 'http://172.16.67.163:8083'
    ACCESS_TOKEN = 'glpat-xcyhWihzE7Z3SxQVicuY'
    HEADERS = {'PRIVATE-TOKEN': ACCESS_TOKEN}
    TIMEOUT = 30  # 请求超时时间(秒)
    MAX_RETRIES = 3  # 最大重试次数
    DELAY_BETWEEN_REQUESTS = 0.5  # 请求间隔(秒)
    
    def test_connection():
        """测试网络连接并验证API访问权限"""
        print("测试连接至 GitLab 服务器...")
        try:
            # 测试网络连接
            host, port = '172.16.67.163', 8083
            sock = socket.create_connection((host, port), timeout=5)
            sock.close()
            print("网络连接成功!")
            
            # 测试API访问权限
            print("验证API访问权限...")
            test_url = GITLAB_URL + "/api/v4/projects?per_page=1"
            req = urllib2.Request(test_url)
            for key, value in HEADERS.items():
                req.add_header(key, value)
                
            response = urllib2.urlopen(req, timeout=TIMEOUT)
            if response.getcode() == 200:
                print("API访问验证成功!")
                return True
            else:
                print("API访问失败,状态码: %d" % response.getcode())
                return False
                
        except (socket.timeout, socket.error) as e:
            print("网络连接失败: %s" % str(e))
            print("请检查: ")
            print("1. 服务器 %s 是否在线" % host)
            print("2. 端口 %s 是否开放" % port)
            print("3. 本地防火墙设置")
        except urllib2.HTTPError as e:
            print("API访问错误: %d %s" % (e.code, e.reason))
            if e.code == 401:
                print("认证失败,请检查访问令牌是否有效")
            elif e.code == 403:
                print("权限不足,请检查令牌权限")
        except Exception as e:
            print("未知错误: %s" % str(e))
        return False
    
    def make_request(url, params=None):
        """发起带重试机制和分页处理的请求"""
        all_items = []
        page = 1
        retry_count = 0
        
        while True:
            try:
                # 构建请求参数
                params = params or {}
                params['page'] = page
                params['per_page'] = 100
                
                query = '&'.join(["%s=%s" % (k, v) for k, v in params.items()])
                full_url = "%s?%s" % (url, query)
                
                # 创建请求对象
                req = urllib2.Request(full_url)
                for key, value in HEADERS.items():
                    req.add_header(key, value)
                    
                # 发送请求(带超时设置)
                response = urllib2.urlopen(req, timeout=TIMEOUT)
                data = response.read()
                items = json.loads(data)
                
                if not items:
                    break
                    
                all_items.extend(items)
                
                # 检查是否有更多页面
                link_header = response.info().getheader('Link')
                if not link_header or 'rel="next"' not in link_header:
                    break
                    
                page += 1
                retry_count = 0  # 成功则重置重试计数
                
            except urllib2.URLError as e:
                if isinstance(e.reason, socket.timeout):
                    print("请求超时: %s" % full_url)
                else:
                    print("URL错误: %s" % str(e))
                    
                retry_count += 1
                if retry_count > MAX_RETRIES:
                    print("达到最大重试次数,放弃请求")
                    break
                    
                print("等待 %d 秒后重试..." % retry_count)
                time.sleep(retry_count * 2)  # 指数退避
                
            except Exception as e:
                print("请求出错: %s" % str(e))
                retry_count += 1
                if retry_count > MAX_RETRIES:
                    print("达到最大重试次数,放弃请求")
                    break
                time.sleep(retry_count * 2)
                
        return all_items
    
    # 创建输出目录
    OUTPUT_DIR = "GitLab_Branch_Reports"
    if not os.path.exists(OUTPUT_DIR):
        os.makedirs(OUTPUT_DIR)
    
    # 先测试网络连接
    if not test_connection():
        print("无法连接到 GitLab 服务器,请检查网络连接和API权限")
        sys.exit(1)
    
    # 创建CSV文件
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    csv_filename = os.path.join(OUTPUT_DIR, 'gitlab_branches_%s.csv' % timestamp)
    
    # 修复Unicode问题:使用UnicodeWriter类
    class UnicodeWriter:
        """
        CSV writer that supports Unicode in Python 2.7
        """
        def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
            self.queue = []
            self.writer = csv.writer(f, dialect=dialect, **kwds)
            self.encoding = encoding
            
        def writerow(self, row):
            # 确保所有元素都是Unicode
            unicode_row = []
            for item in row:
                if isinstance(item, (str, unicode)):
                    if not isinstance(item, unicode):
                        item = unicode(item, self.encoding)
                else:
                    item = unicode(item)
                unicode_row.append(item)
            self.queue.append(unicode_row)
            
        def writerows(self, rows):
            for row in rows:
                self.writerow(row)
                
        def write_to_file(self):
            # 写入BOM头,使Excel正确识别UTF-8编码
            self.writer.writerow([])  # 先写一个空行确保位置正确
            for row in self.queue:
                # 将Unicode编码为UTF-8字节串
                encoded_row = [col.encode(self.encoding) for col in row]
                self.writer.writerow(encoded_row)
    
    # 打开CSV文件准备写入
    with open(csv_filename, 'wb') as csvfile:
        # 创建UnicodeWriter实例
        writer = UnicodeWriter(csvfile)
        
        # 写入CSV表头(使用Unicode字符串)
        headers = [u'项目ID', u'项目名称', u'分支数量', u'分支列表']
        writer.writerow(headers)
        
        # 获取所有项目
        print("\n正在获取所有项目列表...")
        projects_url = GITLAB_URL + '/api/v4/projects'
        all_projects = make_request(projects_url, {'simple': True})
    
        if not all_projects:
            print("无法获取项目列表,请检查错误信息")
            sys.exit(1)
    
        print("\n共获取 %d 个项目\n%s" % (len(all_projects), '='*50))
    
        # 遍历所有项目获取分支
        for idx, project in enumerate(all_projects, 1):
            project_id = project['id']
            
            # 安全处理项目名称
            try:
                # 优先使用带命名空间的项目名
                project_name = project.get('name_with_namespace', project.get('name', u'未知项目'))
            except Exception as e:
                project_name = u"项目名获取失败: %s" % unicode(e)
            
            # 打印项目信息
            try:
                print("\n[%d/%d] 处理项目: %s" % (idx, len(all_projects), project_name.encode('utf-8')))
            except:
                print("\n[%d/%d] 处理项目: [Unicode项目名]" % (idx, len(all_projects)))
            
            # 获取项目所有分支
            branches_url = GITLAB_URL + '/api/v4/projects/%d/repository/branches' % project_id
            all_branches = make_request(branches_url)
            
            branch_count = len(all_branches) if all_branches else 0
            
            # 处理分支信息
            branch_names = []
            if all_branches:
                print("  找到 %d 个分支:" % branch_count)
                
                # 收集分支名称
                for branch in all_branches:
                    try:
                        branch_name = branch.get('name', u'未知分支')
                        branch_names.append(branch_name)
                        
                        # 只打印前5个分支
                        if len(branch_names) <= 5:
                            try:
                                print("    - %s" % branch_name.encode('utf-8'))
                            except:
                                print("    - [Unicode分支名]")
                    except Exception as e:
                        error_msg = u"分支名获取失败: %s" % unicode(e)
                        branch_names.append(error_msg)
                        print("    - [分支名错误]")
                
                if branch_count > 5:
                    print("    ...及其他 %d 个分支" % (branch_count-5))
            else:
                print("  该项目没有分支或获取失败")
            
            # 准备CSV行数据
            branch_list_str = u", ".join(branch_names)
            csv_row = [
                unicode(project_id),
                project_name,
                unicode(branch_count),
                branch_list_str
            ]
            writer.writerow(csv_row)
            
            # 避免请求过快
            time.sleep(DELAY_BETWEEN_REQUESTS)
        
        # 将所有数据写入文件
        writer.write_to_file()
    
    print("\n所有项目处理完成!结果已保存到: %s" % csv_filename)
    
    # 添加完成提示
    print("\n操作说明:")
    print("1. CSV文件路径: %s" % os.path.abspath(csv_filename))

然后再通过Excel的操作,获取到分支信息

需要注意的是:ACCESS_TOKEN = 'glpat-xcyhWihzE7Z3SxQVicuY'的有效期会变,需要重新去gitlab上生成。

Excel单元和合并,2列内容合并到一起,2列内容都保留
公式:=A2 & " " & B2

相关推荐
小道仙974 小时前
gitlab对接,gitlabRestApi,gitlab4j-api
java·git·gitlab
tswddd21 小时前
项目:Gitlab HSD CI/CD总结
ci/cd·kubernetes·gitlab
Haoea!1 天前
持续集成 CI/CD-Jenkins持续集成GitLab项目打包docker镜像推送k8s集群并部署至rancher
ci/cd·gitlab·jenkins·rancher
极小狐1 天前
GitLab CVE-2025-4278 安全漏洞解决方案
ci/cd·gitlab·devsecops·devops·gitlab升级·极狐gitlab·安全升级
weixin_491865161 天前
git新建一个分支到gitlab项目目录中
git·gitlab
极小狐1 天前
GitLab CVE-2025-0673 安全漏洞解决方案
ci/cd·gitlab·devsecops·devops·gitlab升级
MC皮蛋侠客7 天前
使用Gitlab CI/CD结合docker容器实现自动化部署
ci/cd·docker·gitlab
遇见火星7 天前
Jenkins 配置gitlab的 pipeline流水线任务
servlet·gitlab·jenkins
爱写代码的派大星7 天前
gitlab相关操作
gitlab