zt-devops-cli 0.1.4__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zt_devops_cli-0.1.6/PKG-INFO +110 -0
- zt_devops_cli-0.1.6/README.md +99 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/pyproject.toml +1 -1
- zt_devops_cli-0.1.6/src/devops_cli/api.py +165 -0
- zt_devops_cli-0.1.6/src/devops_cli/cli.py +575 -0
- zt_devops_cli-0.1.6/src/zt_devops_cli.egg-info/PKG-INFO +110 -0
- zt_devops_cli-0.1.4/PKG-INFO +0 -80
- zt_devops_cli-0.1.4/README.md +0 -69
- zt_devops_cli-0.1.4/src/devops_cli/api.py +0 -103
- zt_devops_cli-0.1.4/src/devops_cli/cli.py +0 -317
- zt_devops_cli-0.1.4/src/zt_devops_cli.egg-info/PKG-INFO +0 -80
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/setup.cfg +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/devops_cli/__init__.py +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/devops_cli/auth.py +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/devops_cli/config.py +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/zt_devops_cli.egg-info/SOURCES.txt +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/zt_devops_cli.egg-info/dependency_links.txt +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/zt_devops_cli.egg-info/entry_points.txt +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/zt_devops_cli.egg-info/requires.txt +0 -0
- {zt_devops_cli-0.1.4 → zt_devops_cli-0.1.6}/src/zt_devops_cli.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: zt-devops-cli
|
|
3
|
+
Version: 0.1.6
|
|
4
|
+
Summary: DevOps 平台迭代管理 CLI
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: playwright>=1.40.0
|
|
8
|
+
Requires-Dist: requests>=2.31.0
|
|
9
|
+
Requires-Dist: click>=8.1.0
|
|
10
|
+
Requires-Dist: pyyaml>=6.0
|
|
11
|
+
|
|
12
|
+
# DevOps CLI
|
|
13
|
+
|
|
14
|
+
蓝鲸 DevOps 平台迭代管理命令行工具。
|
|
15
|
+
|
|
16
|
+
## 打包
|
|
17
|
+
```bash
|
|
18
|
+
python -m pip install --upgrade build twine
|
|
19
|
+
python -m build
|
|
20
|
+
twine upload dist/*
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
* 源码安装
|
|
25
|
+
```bash
|
|
26
|
+
pip install -e .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
* pip安装
|
|
30
|
+
```bash
|
|
31
|
+
pipx install zt-devops-cli
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 使用
|
|
35
|
+
|
|
36
|
+
### 登陆
|
|
37
|
+
|
|
38
|
+
首次运行时会自动打开浏览器,请登录蓝鲸 DevOps。登录成功后 cookie 会缓存到本地。
|
|
39
|
+
```bash
|
|
40
|
+
zt-devops-cli login
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 空间管理
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
zt-devops-cli project list
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### ZTeam 项目列表
|
|
50
|
+
```bash
|
|
51
|
+
zt-devops-cli zteam-project list --project f39507
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 迭代管理
|
|
55
|
+
|
|
56
|
+
#### 迭代列表
|
|
57
|
+
```bash
|
|
58
|
+
zt-devops-cli sprint list --project k64352
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### 创建迭代
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
zt-devops-cli sprint create --project k64352 \
|
|
65
|
+
--title "迭代名称" \
|
|
66
|
+
--start-date 2026-04-04 \
|
|
67
|
+
--end-date 2026-05-30 \
|
|
68
|
+
--purpose "迭代目标"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### 启用迭代
|
|
72
|
+
```bash
|
|
73
|
+
zt-devops-cli sprint start --project k64352 --sprint-id <id>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### 删除迭代
|
|
77
|
+
```bash
|
|
78
|
+
zt-devops-cli sprint delete --project k64352 --sprint-id <id>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### 完成迭代
|
|
82
|
+
```bash
|
|
83
|
+
zt-devops-cli sprint done --project k64352 --sprint-id <id>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 任务管理
|
|
87
|
+
|
|
88
|
+
#### 查询任务列表(TASK)
|
|
89
|
+
```bash
|
|
90
|
+
zt-devops-cli task list --project f39507 \
|
|
91
|
+
--start-date 2026-04-01 \
|
|
92
|
+
--end-date 2026-04-30 \
|
|
93
|
+
--creator zt07905
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### 新增任务(TASK)
|
|
97
|
+
```bash
|
|
98
|
+
zt-devops-cli task create --project <project-id> \ # 通过 project list 获取
|
|
99
|
+
--title "<任务标题>" \
|
|
100
|
+
--owner <工号> \
|
|
101
|
+
--estimate-start <预计开始时间: yyyy-MM-dd> \
|
|
102
|
+
--estimate-end <预计完成时间: yyyy-MM-dd> \
|
|
103
|
+
--origin-hours 8.00 \ # 预估工时
|
|
104
|
+
--remain-hours 8.00 \ # 实际工时
|
|
105
|
+
--zteam-project-id <zteam-project-id> # 通过 zteam-project list 获取
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 配置
|
|
109
|
+
- cookie 缓存:`~/.zt-devops-cli/cookies.json`
|
|
110
|
+
- 配置文件:`~/.zt-devops-cli/config.yaml`
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# DevOps CLI
|
|
2
|
+
|
|
3
|
+
蓝鲸 DevOps 平台迭代管理命令行工具。
|
|
4
|
+
|
|
5
|
+
## 打包
|
|
6
|
+
```bash
|
|
7
|
+
python -m pip install --upgrade build twine
|
|
8
|
+
python -m build
|
|
9
|
+
twine upload dist/*
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 安装
|
|
13
|
+
* 源码安装
|
|
14
|
+
```bash
|
|
15
|
+
pip install -e .
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
* pip安装
|
|
19
|
+
```bash
|
|
20
|
+
pipx install zt-devops-cli
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 使用
|
|
24
|
+
|
|
25
|
+
### 登陆
|
|
26
|
+
|
|
27
|
+
首次运行时会自动打开浏览器,请登录蓝鲸 DevOps。登录成功后 cookie 会缓存到本地。
|
|
28
|
+
```bash
|
|
29
|
+
zt-devops-cli login
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 空间管理
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
zt-devops-cli project list
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### ZTeam 项目列表
|
|
39
|
+
```bash
|
|
40
|
+
zt-devops-cli zteam-project list --project f39507
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 迭代管理
|
|
44
|
+
|
|
45
|
+
#### 迭代列表
|
|
46
|
+
```bash
|
|
47
|
+
zt-devops-cli sprint list --project k64352
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### 创建迭代
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
zt-devops-cli sprint create --project k64352 \
|
|
54
|
+
--title "迭代名称" \
|
|
55
|
+
--start-date 2026-04-04 \
|
|
56
|
+
--end-date 2026-05-30 \
|
|
57
|
+
--purpose "迭代目标"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### 启用迭代
|
|
61
|
+
```bash
|
|
62
|
+
zt-devops-cli sprint start --project k64352 --sprint-id <id>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### 删除迭代
|
|
66
|
+
```bash
|
|
67
|
+
zt-devops-cli sprint delete --project k64352 --sprint-id <id>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### 完成迭代
|
|
71
|
+
```bash
|
|
72
|
+
zt-devops-cli sprint done --project k64352 --sprint-id <id>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 任务管理
|
|
76
|
+
|
|
77
|
+
#### 查询任务列表(TASK)
|
|
78
|
+
```bash
|
|
79
|
+
zt-devops-cli task list --project f39507 \
|
|
80
|
+
--start-date 2026-04-01 \
|
|
81
|
+
--end-date 2026-04-30 \
|
|
82
|
+
--creator zt07905
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### 新增任务(TASK)
|
|
86
|
+
```bash
|
|
87
|
+
zt-devops-cli task create --project <project-id> \ # 通过 project list 获取
|
|
88
|
+
--title "<任务标题>" \
|
|
89
|
+
--owner <工号> \
|
|
90
|
+
--estimate-start <预计开始时间: yyyy-MM-dd> \
|
|
91
|
+
--estimate-end <预计完成时间: yyyy-MM-dd> \
|
|
92
|
+
--origin-hours 8.00 \ # 预估工时
|
|
93
|
+
--remain-hours 8.00 \ # 实际工时
|
|
94
|
+
--zteam-project-id <zteam-project-id> # 通过 zteam-project list 获取
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 配置
|
|
98
|
+
- cookie 缓存:`~/.zt-devops-cli/cookies.json`
|
|
99
|
+
- 配置文件:`~/.zt-devops-cli/config.yaml`
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""API 请求封装"""
|
|
2
|
+
import json as json_mod
|
|
3
|
+
import requests
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from .auth import get_auth_cookies, get_auth_headers
|
|
7
|
+
from .config import config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DevOpsAPI:
|
|
11
|
+
"""DevOps API 客户端"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, project_id: str):
|
|
14
|
+
self.project_id = project_id
|
|
15
|
+
self.base_url = config.BASE_URL
|
|
16
|
+
|
|
17
|
+
def _request(self, method: str, path: str, **kwargs) -> dict:
|
|
18
|
+
"""发送 API 请求"""
|
|
19
|
+
cookies = get_auth_cookies()
|
|
20
|
+
headers = get_auth_headers(cookies, self.project_id)
|
|
21
|
+
|
|
22
|
+
url = f"{self.base_url}/{path}"
|
|
23
|
+
|
|
24
|
+
# 处理 data 参数
|
|
25
|
+
if "data" in kwargs:
|
|
26
|
+
kwargs["json"] = kwargs.pop("data")
|
|
27
|
+
|
|
28
|
+
# #############################################
|
|
29
|
+
# # 打印 curl 命令
|
|
30
|
+
# curl_parts = [f"curl -X {method}"]
|
|
31
|
+
# for k, v in headers.items():
|
|
32
|
+
# curl_parts.append(f"-H '{k}: {v}'")
|
|
33
|
+
# if "json" in kwargs:
|
|
34
|
+
# curl_parts.append(f"-d '{json_mod.dumps(kwargs['json'], ensure_ascii=False)}'")
|
|
35
|
+
# curl_parts.append(f"'{url}'")
|
|
36
|
+
# print(" ".join(curl_parts))
|
|
37
|
+
# #############################################
|
|
38
|
+
|
|
39
|
+
response = requests.request(
|
|
40
|
+
method=method,
|
|
41
|
+
url=url,
|
|
42
|
+
headers=headers,
|
|
43
|
+
cookies=cookies,
|
|
44
|
+
**kwargs
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if response.status_code >= 400:
|
|
48
|
+
raise Exception(f"API 错误: {response.status_code} {response.text}")
|
|
49
|
+
|
|
50
|
+
return response.json()
|
|
51
|
+
|
|
52
|
+
# ========== 迭代操作 ==========
|
|
53
|
+
|
|
54
|
+
def create_sprint(
|
|
55
|
+
self,
|
|
56
|
+
title: str,
|
|
57
|
+
start_date: str,
|
|
58
|
+
end_date: str,
|
|
59
|
+
purpose: str = "",
|
|
60
|
+
test_start_date: Optional[str] = None,
|
|
61
|
+
test_end_date: Optional[str] = None,
|
|
62
|
+
development_pic: str = "",
|
|
63
|
+
test_pic: str = "",
|
|
64
|
+
acceptance_pic: str = "",
|
|
65
|
+
) -> dict:
|
|
66
|
+
"""创建迭代"""
|
|
67
|
+
data = {
|
|
68
|
+
"title": title,
|
|
69
|
+
"startDate": start_date,
|
|
70
|
+
"endDate": end_date,
|
|
71
|
+
"purpose": purpose,
|
|
72
|
+
"daterange": [f"{start_date}T16:00:00.000Z", f"{end_date}T16:00:00.000Z"],
|
|
73
|
+
"reviewTime": "",
|
|
74
|
+
"testStartDate": test_start_date or start_date,
|
|
75
|
+
"testEndDate": test_end_date or end_date,
|
|
76
|
+
"developmentPic": development_pic,
|
|
77
|
+
"testPic": test_pic,
|
|
78
|
+
"acceptancePic": acceptance_pic,
|
|
79
|
+
"excludeTime": "",
|
|
80
|
+
"state": "ACTIVE",
|
|
81
|
+
}
|
|
82
|
+
return self._request("POST", f"/ms/vteam/api/user/issue_sprint/{self.project_id}", data=data)
|
|
83
|
+
|
|
84
|
+
def start_sprint(self, sprint_data: dict) -> dict:
|
|
85
|
+
"""启用迭代"""
|
|
86
|
+
return self._request("PUT", f"/ms/vteam/api/user/issue_sprint/{self.project_id}/start", data=sprint_data)
|
|
87
|
+
|
|
88
|
+
def delete_sprint(self, sprint_id: str) -> dict:
|
|
89
|
+
"""删除迭代"""
|
|
90
|
+
return self._request("DELETE", f"/ms/vteam/api/user/issue_sprint/{self.project_id}/{sprint_id}")
|
|
91
|
+
|
|
92
|
+
def done_sprint(self, sprint_id: str) -> dict:
|
|
93
|
+
"""完成迭代"""
|
|
94
|
+
return self._request("PUT", f"/ms/vteam/api/user/issue_sprint/{self.project_id}/complete/{sprint_id}")
|
|
95
|
+
|
|
96
|
+
def list_sprints(self) -> dict:
|
|
97
|
+
"""查询迭代列表"""
|
|
98
|
+
return self._request("GET",
|
|
99
|
+
f"/ms/vteam/api/user/issue_sprint/{self.project_id}/flat?num=1&count=1&size=20&content=&start_time=&end_time=&state=ACTIVE%2CNOT_STARTED&sort_field=CREATED_TIME&sort_rule=DESC")
|
|
100
|
+
|
|
101
|
+
def list_projects(self) -> dict:
|
|
102
|
+
"""查询项目列表"""
|
|
103
|
+
return self._request("GET",
|
|
104
|
+
f"/ms/projectmanager/api/user/project/cw/selectByType?showTree=false&haveUser=false")
|
|
105
|
+
|
|
106
|
+
def list_zteam_projects(self) -> dict:
|
|
107
|
+
"""查询 ZTeam 项目列表(任务字段选项)"""
|
|
108
|
+
return self._request(
|
|
109
|
+
"GET",
|
|
110
|
+
f"/ms/vteam/api/user/issue_field_value/{self.project_id}/option/5abdcb4c783e11edbef4fa819a160800?all=false&classify=TASK",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# ========== 任务操作 ==========
|
|
114
|
+
|
|
115
|
+
def create_task(
|
|
116
|
+
self,
|
|
117
|
+
title: str,
|
|
118
|
+
model_type_id: str,
|
|
119
|
+
priority: str = "CENTRAL",
|
|
120
|
+
editor_type: str = "MARKDOWN",
|
|
121
|
+
desc: str = "",
|
|
122
|
+
parent_id: str = "",
|
|
123
|
+
demand_classify: str = "-1",
|
|
124
|
+
instance_values: Optional[list] = None,
|
|
125
|
+
) -> dict:
|
|
126
|
+
"""创建 TASK 任务"""
|
|
127
|
+
data = {
|
|
128
|
+
"title": title,
|
|
129
|
+
"modelTypeId": model_type_id,
|
|
130
|
+
"priority": priority,
|
|
131
|
+
"editorType": editor_type,
|
|
132
|
+
"desc": desc,
|
|
133
|
+
"parentId": parent_id,
|
|
134
|
+
"relationIssue": {},
|
|
135
|
+
"demandClassify": demand_classify,
|
|
136
|
+
"fileVO": [],
|
|
137
|
+
"labelId": [],
|
|
138
|
+
"instanceValue": instance_values or [],
|
|
139
|
+
}
|
|
140
|
+
return self._request("POST", f"/ms/vteam/api/user/issue/{self.project_id}", data=data)
|
|
141
|
+
|
|
142
|
+
def list_tasks(
|
|
143
|
+
self,
|
|
144
|
+
creator: Optional[str] = None,
|
|
145
|
+
start_date: Optional[str] = None,
|
|
146
|
+
end_date: Optional[str] = None,
|
|
147
|
+
num: int = 1,
|
|
148
|
+
size: int = 20,
|
|
149
|
+
remember: bool = False,
|
|
150
|
+
) -> dict:
|
|
151
|
+
"""按条件查询 TASK 列表"""
|
|
152
|
+
|
|
153
|
+
data = [ {"name": "exclude", "value": []}]
|
|
154
|
+
|
|
155
|
+
if creator:
|
|
156
|
+
data.insert(0, {"name": "createUser", "value": [creator]})
|
|
157
|
+
if start_date and end_date:
|
|
158
|
+
data.insert(0, {"name": "estimate_start_time", "value": [start_date, end_date]})
|
|
159
|
+
data.insert(0, {"name": "estimate_end_time", "value": [start_date, end_date]})
|
|
160
|
+
remember_value = str(remember).lower()
|
|
161
|
+
return self._request(
|
|
162
|
+
"POST",
|
|
163
|
+
f"/ms/vteam/api/user/issue/{self.project_id}/table/TASK?num={num}&size={size}&remember={remember_value}",
|
|
164
|
+
data=data,
|
|
165
|
+
)
|