Última actividad 2 months ago

gistfile1.py Sin formato
1#!/usr/bin/env python3
2"""
3为个人所有 GitLab 仓库批量添加 CI/CD 变量:
4 DOCKER_USERNAME
5 DOCKER_PASSWORD
6 LOCAL_DOCKER_USERNAME
7 LOCAL_DOCKER_PASSWORD
8"""
9
10import os
11import sys
12import requests
13
14def get_user_id(base_url, headers, username):
15 resp = requests.get(
16 f"{base_url}/api/v4/users",
17 params={"username": username},
18 headers=headers
19 )
20 resp.raise_for_status()
21 users = resp.json()
22 if not users:
23 print(f"用户 '{username}' 未找到", file=sys.stderr)
24 sys.exit(1)
25 return users[0]["id"]
26
27def get_projects(base_url, headers, user_id):
28 projects = []
29 page = 1
30 while True:
31 resp = requests.get(
32 f"{base_url}/api/v4/users/{user_id}/projects",
33 params={"per_page": 100, "page": page},
34 headers=headers
35 )
36 resp.raise_for_status()
37 data = resp.json()
38 if not data:
39 break
40 projects.extend(data)
41 page += 1
42 return projects
43
44def delete_variable(base_url, headers, project_id, key):
45 """无脑删除项目下的指定变量,忽略不存在的错误"""
46 url = f"{base_url}/api/v4/projects/{project_id}/variables/{key}"
47 r = requests.delete(url, headers=headers)
48 # 204:删除成功;404:变量本就不存在,都视作 OK
49 return r.status_code in (204, 404)
50
51def add_variable(base_url, headers, project_id, key, value):
52 payload = {
53 "key": key,
54 "value": value,
55 "variable_type": "env_var",
56 "protected": "true", # 仅在受保护的分支/标签上可用
57 "masked": "true", # 在 Job 日志中掩码
58 "masked_and_hidden": "true", # 掩码并在 UI 中隐藏(不能再查看)
59 "raw": "true", # 原样,不展开变量引用
60 "environment_scope": "*" # 生效所有环境
61 }
62 resp = requests.post(
63 f"{base_url}/api/v4/projects/{project_id}/variables",
64 headers=headers,
65 data=payload
66 )
67 if resp.status_code == 201:
68 return True, None
69 elif resp.status_code == 400:
70 return False, resp.text
71 else:
72 resp.raise_for_status()
73
74def main():
75 base_url = os.getenv("GITLAB_BASE_URL", "https://gitlab.aiursoft.cn")
76 token = "glpat-9ztZJRPATvsuaQ59yBxZ"
77 headers = {"Private-Token": token}
78
79 username = os.getenv("GITLAB_USERNAME", "anduin")
80
81 user_id = get_user_id(base_url, headers, username)
82 projects = get_projects(base_url, headers, user_id)
83
84 variables = [
85 ("DOCKER_USERNAME", "aaaaa"),
86 ("DOCKER_PASSWORD", "bbbbb"),
87 ("LOCAL_DOCKER_USERNAME", "ccccc"),
88 ("LOCAL_DOCKER_PASSWORD", "ddddd"),
89 ("LOCAL_NUGET_API_KEY", "eeeeeeee"),
90 ("NUGET_API_KEY", "fffff"),
91 ]
92
93 for proj in projects:
94 pid = proj["id"]
95 name = proj.get("path_with_namespace", proj["name"])
96 print(f"▶ 处理项目:{name}")
97
98 # —— 新增:先无脑删除所有旧变量 ——
99 for key, _ in variables:
100 deleted = delete_variable(base_url, headers, pid, key)
101 status = "已删除" if deleted else "删除失败"
102 print(f" ↳ 删除 {key}: {status}")
103
104 # —— 再批量添加 ——
105 for key, val in variables:
106 ok, msg = add_variable(base_url, headers, pid, key, val)
107 if ok:
108 print(f" ✔ 添加 {key}")
109 else:
110 print(f" ✖ 添加 {key} 失败:{msg}")
111
112if __name__ == "__main__":
113 main()
114