gitlab初始化+API批量操作

几年没接触gitlab了,新版本装完以后代码提交到默认的main分支,master不再是主分支
项目有几十个仓库,研发提交代码后仓库地址和之前的发生了变化
有几个点 需要注意
1、修改全局默认分支
2、关闭分支保护
在这里插入图片描述

上面修改了全局配置不会影响已经创建好的项目,所以还需要批量修改已创建的项目
先修改Group的默认分支,不会影响已存在的项目在这里插入图片描述
修改gitlab全局的默认分支
在这里插入图片描述

这就引出了需求,要获取当前仓库下所有仓库地址,还要修改所有仓库的默认分支,从main修改为master

生成AccessToken在这里插入图片描述

创建个人访问令牌

填写信息时,确保勾选以下权限(Scopes):
api
read_api
read_repository
write_repository
admin_mode(如果是要批量修改默认分支,可能需要这个权限)
# 权限解析
api 和 read_api: 基本的 API 访问权限
read_repository: 读取仓库信息
write_repository: 修改仓库设置(包括默认分支)
admin_mode: 管理员级别的操作权限

需求1-获取仓库下所有项目地址

import requests
import sys
import time
from typing import List, Dict

class GitLabProjectFetcher:
    def __init__(self, base_url: str, private_token: str):
        """
        初始化 GitLab API 客户端
        
        Args:
            base_url: GitLab 实例的基础 URL
            private_token: GitLab 个人访问令牌
        """
        self.base_url = base_url.rstrip('/')
        self.headers = {'PRIVATE-TOKEN': private_token}
        self.session = requests.Session()
        self.session.headers.update(self.headers)

    def get_all_projects(self) -> List[Dict]:
        """获取所有项目"""
        projects = []
        page = 1
        while True:
            url = f"{self.base_url}/api/v4/projects"
            params = {
                'page': page,
                'per_page': 100,
                'order_by': 'path',
                'sort': 'asc'
            }
            
            try:
                response = self.session.get(url, params=params)
                response.raise_for_status()
                
                batch = response.json()
                if not batch:
                    break
                    
                projects.extend(batch)
                page += 1
                print(f"已获取 {len(projects)} 个项目...")
                
                time.sleep(0.5)  # 避免请求过快
                
            except requests.exceptions.RequestException as e:
                print(f"获取项目列表时发生错误: {str(e)}")
                sys.exit(1)
            
        return projects

def main():
    # 配置信息 - 根据实际环境修改
    GITLAB_URL = "http://gitlab地址"
    PRIVATE_TOKEN = "accesstoken"
    
    fetcher = GitLabProjectFetcher(GITLAB_URL, PRIVATE_TOKEN)
    
    try:
        print("正在获取项目列表...")
        projects = fetcher.get_all_projects()
        
        print("\n所有项目的 Git SSH Clone URL:")
        print("-" * 80)
        
        # 按照路径排序
        sorted_projects = sorted(projects, key=lambda x: x['path_with_namespace'])
        
        for project in sorted_projects:
            if 'ssh_url_to_repo' in project:
                print(project['ssh_url_to_repo'])
        
        print(f"\n总共找到 {len(projects)} 个项目")
        
    except Exception as e:
        print(f"发生错误: {str(e)}")
        sys.exit(1)

if __name__ == "__main__":
    main()

需求2-修改所有仓库默认的分支为master

root@prd-ops-cicd-jenkins33:/data/ops# cat chage-branch.py 
import requests
import sys
import time
from typing import List, Dict

class GitLabProjectManager:
    def __init__(self, base_url: str, private_token: str):
        """
        初始化 GitLab API 客户端
        """
        self.base_url = base_url.rstrip('/')
        self.headers = {'PRIVATE-TOKEN': private_token}
        self.session = requests.Session()
        self.session.headers.update(self.headers)

    def get_all_projects(self) -> List[Dict]:
        """获取所有项目"""
        projects = []
        page = 1
        while True:
            url = f"{self.base_url}/api/v4/projects"
            params = {
                'page': page,
                'per_page': 100,
                'order_by': 'path',
                'sort': 'asc',
                'simple': False
            }
            
            try:
                print(f"正在获取第 {page} 页...")
                response = self.session.get(url, params=params)
                response.raise_for_status()
                
                batch = response.json()
                if not batch:
                    break
                    
                projects.extend(batch)
                page += 1
                time.sleep(0.5)
                
            except requests.exceptions.RequestException as e:
                print(f"获取项目列表时发生错误: {str(e)}")
                sys.exit(1)
            
        return projects

    def check_branch_exists(self, project_id: int, branch: str) -> bool:
        """检查分支是否存在"""
        url = f"{self.base_url}/api/v4/projects/{project_id}/repository/branches/{branch}"
        response = self.session.get(url)
        return response.status_code == 200

    def update_default_branch(self, project_id: int, project_name: str, new_branch: str) -> bool:
        """更新项目的默认分支"""
        # 检查目标分支是否存在
        if not self.check_branch_exists(project_id, new_branch):
            print(f"项目 {project_name} 中不存在 {new_branch} 分支,跳过")
            return False

        url = f"{self.base_url}/api/v4/projects/{project_id}"
        data = {'default_branch': new_branch}
        
        try:
            response = self.session.put(url, json=data)
            response.raise_for_status()
            return True
        except requests.exceptions.RequestException as e:
            print(f"更新失败: {str(e)}")
            return False

def main():
    # 配置信息
    GITLAB_URL = "http://gitlab地址"
    PRIVATE_TOKEN = "accesstoken"
    NEW_DEFAULT_BRANCH = "master"
    
    manager = GitLabProjectManager(GITLAB_URL, PRIVATE_TOKEN)
    
    try:
        # 获取所有项目
        print("正在获取项目列表...")
        projects = manager.get_all_projects()
        print(f"\n找到 {len(projects)} 个项目")
        
        # 更新默认分支
        success_count = 0
        fail_count = 0
        skipped_count = 0
        
        print("\n开始更新默认分支...")
        for project in projects:
            project_id = project['id']
            project_name = project['path_with_namespace']
            current_default = project.get('default_branch', '')
            
            print(f"\n处理项目: {project_name}")
            print(f"当前默认分支: {current_default}")
            
            if current_default == NEW_DEFAULT_BRANCH:
                print("默认分支已经是 master,跳过")
                skipped_count += 1
                continue
                
            if manager.update_default_branch(project_id, project_name, NEW_DEFAULT_BRANCH):
                success_count += 1
                print(f"✓ 成功将默认分支更新为 {NEW_DEFAULT_BRANCH}")
            else:
                fail_count += 1
                print(f"✗ 更新失败")
        
        # 打印总结
        print("\n更新完成!")
        print(f"成功更新: {success_count} 个项目")
        print(f"更新失败: {fail_count} 个项目")
        print(f"跳过项目: {skipped_count} 个项目")
        print(f"总项目数: {len(projects)} 个项目")
        
    except Exception as e:
        print(f"发生错误: {str(e)}")
        sys.exit(1)

if __name__ == "__main__":
    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/939410.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【记录50】uniapp安装uview插件,样式引入失败分析及解决

SassError: Undefined variable: "$u-border-color". 表示样式变量$u-border-color没定义&#xff0c;实际是定义的 首先确保安装了scss/sass 其次&#xff0c;根目录下 app.vue中是否全局引入 <style lang"scss">import /uni_modules/uview-ui/in…

STM32CUBEMX+STM32H743ZIT6+MPU+DMA+UART下发指令对MPU配置管理

实现stm32H7的IAP过程&#xff0c;没有想象中的顺利。 需要解决串口DMA和MPU配置管理。 查看正点原子的MPU管理例程&#xff0c;想自己用串口下发指令&#xff0c;实现MPU打开&#xff0c;读取和写入指令。 中间遇到很多坑&#xff0c;比如串口DMA方式下发指令&#xff0c;没反…

8. 数组拼接

题目描述 现在有多组整数数组&#xff0c;需要将它们合并成一个新的数组。合并规则&#xff0c;从每个数组里按顺序取出固定长度的内容合并到新的数组中&#xff0c;取完的内容会删除掉&#xff0c;如果该行不足固定长度或者已经为空&#xff0c;则直接取出剩余部分的内容放到新…

Chrome 浏览器原生功能截长屏

我偶尔需要截取一些网页内容作为素材&#xff0c;但偶尔内容很长无法截全&#xff0c;需要多次截屏再拼接&#xff0c;过于麻烦。所以记录下这个通过浏览器原生功能截长屏的方案。 注意 这种方案并不是百分百完美&#xff0c;如果涉及到一些需要滚动加载的数据或者悬浮区块&am…

学技术学英文:代码中的锁:悲观锁和乐观锁

本文导读&#xff1a; 1. 举例说明加锁的场景&#xff1a; 多线程并发情况下有资源竞争的时候&#xff0c;如果不加锁&#xff0c;会出现数据错误&#xff0c;举例说明&#xff1a; 业务需求&#xff1a;账户余额>取款金额&#xff0c;才能取钱。 时间线 两人共有账户 …

深度学习之目标检测——RCNN

Selective Search 背景:事先不知道需要检测哪个类别,且候选目标存在层级关系与尺度关系 常规解决方法&#xff1a;穷举法&#xff0c;在原始图片上进行不同尺度不同大小的滑窗&#xff0c;获取每个可能的位置 弊端&#xff1a;计算量大&#xff0c;且尺度不能兼顾 Selective …

数字人在虚拟展厅中的应用方向有哪些?

数字人在虚拟展厅中的应用日益丰富&#xff0c;为参观者带来了前所未有的互动体验。以下是数字人在虚拟展厅中的几大主要应用方向&#xff1a; 1. 智能导览与讲解 在虚拟展厅中&#xff0c;数字人以其独特的魅力担任着导览员的角色。它们不仅为参观者提供精准的信息和指引&am…

WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现

一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现&#xff1a; Python。 我们将用Python来实现一个学生管理应用&#xff0…

【我的 PWN 学习手札】IO_FILE 之 stdin任意地址写

我们知道&#xff0c;stdin会往“缓冲区”先读入数据&#xff0c;如果我们劫持这个所谓“缓冲区”到其他地址呢&#xff1f;是否可以读入数据到任意地址&#xff1f;答案是肯定的。 注意&#xff01;代码中的“-------”分隔&#xff0c;是为了区分一条调用链上不同代码片段&am…

从 Dify 到 Rill-Flow:大模型应用平台的进化之路

1. 基于 dify 的大模型应用平台构建 近些年&#xff0c;大语言模型领域的高速发展&#xff0c;涌现出了众多优秀的产品&#xff0c;能够解决很多实际的业务场景&#xff0c;大幅提升工作效率。各公司都纷纷搭建起了自己的大模型应用平台&#xff0c;来统一管理各种大语言模型&…

37. Three.js案例-绘制部分球体

37. Three.js案例-绘制部分球体 实现效果 知识点 WebGLRenderer WebGLRenderer 是Three.js中的一个渲染器类&#xff0c;用于将3D场景渲染到网页上。 构造器 WebGLRenderer( parameters : Object ) 参数类型描述parametersObject渲染器的配置参数&#xff0c;可选。 常用…

基于 SSM 框架 Vue 电脑测评系统:赋能电脑品质鉴定

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;作为一个一般的用户都开始注重与自己的信息展示平台&#xff0c;实现基于SSM框架的电脑测评系统在技术上已成熟。本文介绍了基于SSM框架的电脑测评系统的开发全过程。通过分析用户对于基于SSM框架的电脑测评系统的…

二七(vue2-03)、生命周期四个阶段及八个钩子、工程化开发和脚手架、组件注册、拆分组件

1. 生命周期 1.1 生命周期四个阶段 <!-- Vue生命周期&#xff1a;一个Vue实例从 创建 到 销毁 的整个过程。生命周期四个阶段&#xff1a;① 创建 ② 挂载 ③ 更新 ④ 销毁1.创建阶段&#xff1a;创建响应式数据2.挂载阶段&#xff1a;渲染模板3.更新阶段&#xff1a;修改…

Group FLUX - Beta Sprint Essay4

文章目录 I. SCRUMAchievements from yesterday’s stand-up meeting to the presentKey Features Demonstrated in Beta PM ReportBurnup mapRunning image of our current program I. SCRUM Achievements from yesterday’s stand-up meeting to the present Zhong Haoyan: …

c++-----------------类和对象(中)

1.类的默认成员函数 默认的成员函数就是用户没有显示实现&#xff0c;编译器会自动生成的成员函数称为默认的成员函数。一个类我们在不写的情况下编译器会自动生成以下6个默认的成员函数&#xff0c;这6个最重要的是前面4个&#xff0c;后面的了解一下就可以了。默认成员函数很…

Qt中的异步相关类

Qt中的异步相关类 今天在学习别人的项目时&#xff0c;看到别人包含了QFuture类&#xff0c;我没有见过&#xff0c;于是记录一下。 直接在AI助手中搜索QFuture,得到的时Qt中异步相关的类。于是直接查询一下Qt异步中相关的类。 在Qt中&#xff0c;异步编程是一个重要的概念&…

WPF DataTemplate 数据模板

DataTemplate 顾名思义&#xff0c;数据模板&#xff0c;在 wpf 中使用非常频繁。 它一般用在带有 DataTemplate 依赖属性的控件中&#xff0c;如 ContentControl、集合控件 ListBox、ItemsControl 、TabControls 等。 1. 非集合控件中使用 <UserControl.Resources>&l…

爬虫案例学习6

获取淘宝商品数据2024-12-18 参考学习&#xff1a; 大佬博客 视频教程 通过搜索发现&#xff0c;数据是通过发送请求过来的&#xff0c;不是静态存在源代码的 所以我们需要请求这个接口获取数据&#xff1a;比如标题&#xff0c;价格&#xff0c;图片等信息 https://h5api.m…

Linux学习——9_Ubuntu Linux操作系统

Ubuntu Linux操作系统 Ubuntu简介 Ubuntu Linux是由南非人马克沙特尔沃思(Mark Shuttleworth)创办的基于Debian Linux的操作系统&#xff0c;于2004年10月公布 Ubuntu是一个以桌面应用为主的Linux发行版操作系统 Ubuntu拥有庞大的社区力量&#xff0c;用户可以方便地从社区…

springboot449教学资源共享平台(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统教学资源共享平台信息管理难度大&#xff0c;容错率低&am…