ai-engineering-init 1.17.1 → 1.17.2
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.
- package/.claude/skills/jenkins-deploy/SKILL.md +53 -126
- package/.claude/skills/jenkins-deploy/assets/jk_build.py +58 -20
- package/.codex/skills/jenkins-deploy/SKILL.md +53 -126
- package/.cursor/skills/jenkins-deploy/SKILL.md +53 -126
- package/bin/index.js +16 -10
- package/package.json +1 -1
- package/.claude/skills/jenkins-deploy/assets/last_cd_env.template.json +0 -7
|
@@ -15,21 +15,20 @@ description: |
|
|
|
15
15
|
|
|
16
16
|
# Jenkins + Portainer 自动打包部署
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## 架构
|
|
19
19
|
|
|
20
|
-
项目使用 `jenkins/` 目录下的 Python 脚本实现自动化构建部署,流程:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
Jenkins 构建 core → Jenkins 构建 api → Portainer 更新容器
|
|
24
20
|
```
|
|
21
|
+
技能目录(随框架更新,不复制到项目):
|
|
22
|
+
~/.claude/skills/jenkins-deploy/assets/jk_build.py ← 构建脚本
|
|
23
|
+
|
|
24
|
+
全局配置(一次性配置,所有项目共享):
|
|
25
|
+
~/.claude/jenkins-config.json ← 凭证(Jenkins/Portainer)
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
项目本地(自动生成):
|
|
28
|
+
jenkins/last_cd_env.json ← 构建状态(环境、分支、模式)
|
|
29
|
+
```
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|------|------|
|
|
30
|
-
| `jenkins/jk_build.py` | 主构建脚本 |
|
|
31
|
-
| `jenkins/env_param.json` | 环境配置(Jenkins/Portainer 连接参数) |
|
|
32
|
-
| `jenkins/last_cd_env.json` | 上次构建参数(自动保存) |
|
|
31
|
+
脚本按 **本地 `.claude/` > 全局 `~/.claude/`** 优先级查找 `jenkins-config.json`。
|
|
33
32
|
|
|
34
33
|
## 构建模式
|
|
35
34
|
|
|
@@ -42,156 +41,84 @@ Jenkins 构建 core → Jenkins 构建 api → Portainer 更新容器
|
|
|
42
41
|
|
|
43
42
|
## 环境支持
|
|
44
43
|
|
|
45
|
-
| 环境 | 前缀 |
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
52
|
-
## 定制项目支持
|
|
53
|
-
|
|
54
|
-
当指定 `api_param_folder`(定制工程文件夹名)时,Jenkins Job 路径变为:
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
{folder_name}/dev-后端-core # 替代 dev-tengyun-core
|
|
58
|
-
{folder_name}/dev-后端-api # 替代 dev-tengyun-yunshitang-api
|
|
59
|
-
```
|
|
44
|
+
| 环境 | 前缀 | Portainer 更新方式 |
|
|
45
|
+
|------|------|-------------------|
|
|
46
|
+
| dev1~15 | `dev` | Webhook 触发 |
|
|
47
|
+
| dev16~43 | `dev` | Force Update(xnzn-dev.xnzn.net) |
|
|
48
|
+
| dev44+ | `dev` | 只支持模式 0(手动更新) |
|
|
49
|
+
| test | `test` | Webhook 触发 |
|
|
60
50
|
|
|
61
51
|
## 使用方式
|
|
62
52
|
|
|
63
|
-
###
|
|
53
|
+
### 运行构建脚本
|
|
64
54
|
|
|
65
55
|
```bash
|
|
66
|
-
|
|
56
|
+
python ~/.claude/skills/jenkins-deploy/assets/jk_build.py
|
|
67
57
|
```
|
|
68
58
|
|
|
69
|
-
|
|
70
|
-
1. **模式**(0/1/2/3)
|
|
71
|
-
2. **环境**(dev1, dev2, test1 等)
|
|
72
|
-
3. **core 分支**(如 release_5.56.0)
|
|
73
|
-
4. **api 分支**(如 master)
|
|
74
|
-
5. **定制工程文件夹**(可选,空格或 None 跳过)
|
|
59
|
+
脚本交互式询问:模式 → 环境 → core 分支 → api 分支 → 定制工程文件夹
|
|
75
60
|
|
|
76
|
-
### 通过
|
|
61
|
+
### 通过 AI 辅助部署
|
|
77
62
|
|
|
78
63
|
当用户说"打包到 devX"时:
|
|
79
64
|
|
|
80
|
-
1.
|
|
81
|
-
2.
|
|
82
|
-
3.
|
|
83
|
-
4.
|
|
65
|
+
1. 读取 `jenkins/last_cd_env.json` 获取上次参数
|
|
66
|
+
2. 确认参数:环境、分支、模式
|
|
67
|
+
3. 修改 `jenkins/last_cd_env.json` 写入新参数
|
|
68
|
+
4. 执行 `python ~/.claude/skills/jenkins-deploy/assets/jk_build.py`
|
|
84
69
|
|
|
85
|
-
##
|
|
70
|
+
## 配置文件
|
|
86
71
|
|
|
87
|
-
###
|
|
72
|
+
### jenkins-config.json(凭证,全局)
|
|
88
73
|
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
"build_mode": "0",
|
|
92
|
-
"cd_env": "dev63",
|
|
93
|
-
"core_param_branch": "release_5.56.0",
|
|
94
|
-
"api_param_branch": "master",
|
|
95
|
-
"api_param_folder": null
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
| 字段 | 说明 |
|
|
100
|
-
|------|------|
|
|
101
|
-
| `build_mode` | 构建模式(0/1/2/3) |
|
|
102
|
-
| `cd_env` | 目标环境(如 dev1, test2) |
|
|
103
|
-
| `core_param_branch` | core 仓库分支 |
|
|
104
|
-
| `api_param_branch` | api 仓库分支 |
|
|
105
|
-
| `api_param_folder` | 定制项目文件夹(null 表示标准项目) |
|
|
74
|
+
位置:`~/.claude/jenkins-config.json`(或本地 `.claude/jenkins-config.json`)
|
|
106
75
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
包含 Jenkins 和 Portainer 的连接参数(用户名、API Token、服务地址等),按 dev/test 环境分组。
|
|
76
|
+
模板:`.claude/skills/jenkins-deploy/assets/env_param.template.json`
|
|
110
77
|
|
|
111
78
|
> **注意**:此文件包含敏感凭证,不要将内容输出到对话中。
|
|
112
79
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
1. 连接 Jenkins(ci.xnzn.net)
|
|
117
|
-
2. 构建 core(参数:BRANCH + VERSION=环境名)
|
|
118
|
-
└─ 轮询构建进度,超时 10 分钟
|
|
119
|
-
3. 构建 api(参数同上)
|
|
120
|
-
└─ 轮询构建进度,超时 5 分钟
|
|
121
|
-
4. 更新 Portainer:
|
|
122
|
-
├─ dev1~15:Webhook 触发
|
|
123
|
-
│ └─ 获取 JWT → 查 Service ID → 获取/创建 Webhook → POST 触发
|
|
124
|
-
└─ dev16+:Force Update
|
|
125
|
-
└─ 获取 JWT → 查 Service ID → PUT forceupdateservice
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## 常见操作
|
|
80
|
+
### last_cd_env.json(构建状态,项目本地)
|
|
129
81
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
# 修改 last_cd_env.json 的 build_mode 为 "2",然后运行
|
|
134
|
-
cd jenkins && python jk_build.py
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### 只需要更新容器(已在 Jenkins 手动构建完)
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
# build_mode 设为 "3"
|
|
141
|
-
cd jenkins && python jk_build.py
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### 部署定制项目
|
|
82
|
+
位置:`jenkins/last_cd_env.json`(脚本自动创建,无需手动初始化)
|
|
145
83
|
|
|
146
84
|
```json
|
|
147
|
-
// last_cd_env.json
|
|
148
85
|
{
|
|
149
|
-
"
|
|
86
|
+
"build_mode": "1",
|
|
87
|
+
"cd_env": "dev1",
|
|
88
|
+
"core_param_branch": "master",
|
|
89
|
+
"api_param_branch": "master",
|
|
90
|
+
"api_param_folder": null
|
|
150
91
|
}
|
|
151
92
|
```
|
|
152
93
|
|
|
153
|
-
##
|
|
94
|
+
## 定制项目
|
|
154
95
|
|
|
155
|
-
|
|
96
|
+
指定 `api_param_folder` 后,Jenkins Job 路径变为:
|
|
156
97
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# 1. 创建 jenkins 目录
|
|
161
|
-
mkdir -p jenkins
|
|
162
|
-
|
|
163
|
-
# 2. 从技能模板复制文件(SKILL_DIR 为技能目录路径)
|
|
164
|
-
cp .claude/skills/jenkins-deploy/assets/jk_build.py jenkins/jk_build.py
|
|
165
|
-
cp .claude/skills/jenkins-deploy/assets/last_cd_env.template.json jenkins/last_cd_env.json
|
|
166
|
-
|
|
167
|
-
# 3. 环境配置需要用户提供(含敏感凭证)
|
|
168
|
-
cp .claude/skills/jenkins-deploy/assets/env_param.template.json jenkins/env_param.json
|
|
169
|
-
|
|
170
|
-
# 4. 安装依赖
|
|
171
|
-
pip install python-jenkins requests
|
|
98
|
+
```
|
|
99
|
+
{folder_name}/dev-后端-core
|
|
100
|
+
{folder_name}/dev-后端-api
|
|
172
101
|
```
|
|
173
102
|
|
|
174
|
-
|
|
103
|
+
## 首次初始化(团队成员)
|
|
175
104
|
|
|
176
|
-
|
|
105
|
+
只需一步:配置全局凭证文件。
|
|
177
106
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
| `__JENKINS_DEV_TOKEN__` | Jenkins dev API Token | Jenkins → 用户 → 设置 → API Token |
|
|
182
|
-
| `__JENKINS_TEST_USER__` | Jenkins test 账号 | 同上 |
|
|
183
|
-
| `__JENKINS_TEST_TOKEN__` | Jenkins test API Token | 同上 |
|
|
184
|
-
| `__PORTAINER_*_USER__` | Portainer 用户名 | 向团队负责人获取 |
|
|
185
|
-
| `__PORTAINER_*_PWD__` | Portainer 密码 | 向团队负责人获取 |
|
|
107
|
+
```bash
|
|
108
|
+
# 方式 1:从团队成员拷贝
|
|
109
|
+
cp /path/to/teammate/jenkins-config.json ~/.claude/jenkins-config.json
|
|
186
110
|
|
|
187
|
-
|
|
111
|
+
# 方式 2:从模板创建,手动填写凭证
|
|
112
|
+
cp ~/.claude/skills/jenkins-deploy/assets/env_param.template.json ~/.claude/jenkins-config.json
|
|
113
|
+
# 然后替换 __JENKINS_*__ 和 __PORTAINER_*__ 占位符
|
|
114
|
+
```
|
|
188
115
|
|
|
189
116
|
### AI 初始化行为
|
|
190
117
|
|
|
191
|
-
当技能被触发但 `jenkins
|
|
192
|
-
1.
|
|
193
|
-
2.
|
|
194
|
-
3.
|
|
118
|
+
当技能被触发但 `jenkins-config.json` 不存在时:
|
|
119
|
+
1. 提示"检测到尚未配置 Jenkins 凭证"
|
|
120
|
+
2. 询问是否从模板创建
|
|
121
|
+
3. 复制模板到 `~/.claude/jenkins-config.json`
|
|
195
122
|
4. 提示用户填写凭证(或拷贝已有配置)
|
|
196
123
|
|
|
197
124
|
## 依赖
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import html
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
+
import sys
|
|
5
6
|
import time
|
|
6
7
|
|
|
7
8
|
import jenkins
|
|
@@ -24,6 +25,32 @@ jenkins_api_token = ''
|
|
|
24
25
|
core_job = ''
|
|
25
26
|
api_job = ''
|
|
26
27
|
|
|
28
|
+
|
|
29
|
+
# ~~~~~~~~~~~~~~~~~ 配置文件查找 ~~~~~~~~~~~~~~~~~~~~~~~~
|
|
30
|
+
|
|
31
|
+
def find_config_file(filename, search_paths):
|
|
32
|
+
"""按优先级查找配置文件:本地 > 全局"""
|
|
33
|
+
for p in search_paths:
|
|
34
|
+
filepath = os.path.join(p, filename)
|
|
35
|
+
if os.path.exists(filepath):
|
|
36
|
+
return filepath
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# 配置文件搜索路径
|
|
41
|
+
project_dir = os.getcwd()
|
|
42
|
+
home_claude_dir = os.path.join(os.path.expanduser('~'), '.claude')
|
|
43
|
+
|
|
44
|
+
# jenkins-config.json 搜索路径:项目本地 .claude/ > 全局 ~/.claude/
|
|
45
|
+
config_search_paths = [
|
|
46
|
+
os.path.join(project_dir, '.claude'),
|
|
47
|
+
home_claude_dir,
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
# last_cd_env.json 搜索路径:项目本地 jenkins/
|
|
51
|
+
state_dir = os.path.join(project_dir, 'jenkins')
|
|
52
|
+
|
|
53
|
+
|
|
27
54
|
# 执行job方法,通过等待时间来判断是否构建成功
|
|
28
55
|
def do_job_by_time(server, job_name, param_branch, param_env, wait_time):
|
|
29
56
|
queue_num = server.build_job(name=job_name,
|
|
@@ -134,8 +161,6 @@ def get_server_id(token):
|
|
|
134
161
|
"Authorization": f"Bearer {token}",
|
|
135
162
|
"Content-Type": "application/json"
|
|
136
163
|
}
|
|
137
|
-
# Get list of services
|
|
138
|
-
# services_response = requests.get(portainer_api_url + "/endpoints/1/docker/services", headers=headers) // dev改成了2
|
|
139
164
|
url = portainer_api_url + f'/endpoints/{portainer_endpoints}/docker/services'
|
|
140
165
|
services_response = requests.get(url, headers=headers)
|
|
141
166
|
services = services_response.json()
|
|
@@ -162,8 +187,6 @@ def get_service_web_hook():
|
|
|
162
187
|
"Content-Type": "application/json"
|
|
163
188
|
}
|
|
164
189
|
|
|
165
|
-
# 查询service的webhook
|
|
166
|
-
# url = portainer_api_url + f'/webhooks?filters=%7B%22ResourceID%22:%22{service_id}%22,%22EndpointID%22:1%7D' // dev改成了2
|
|
167
190
|
url = portainer_api_url + f'/webhooks?filters=%7B%22ResourceID%22:%22{service_id}%22,%22EndpointID%22:{portainer_endpoints}%7D'
|
|
168
191
|
services_response = requests.get(url, headers=headers)
|
|
169
192
|
webhook_json = services_response.json()
|
|
@@ -226,11 +249,33 @@ print('\n~~~~~~~~~~~~~~')
|
|
|
226
249
|
print('正在使用jenkins+portainer构建工具,目前支持dev和test环境的自动化构建+更新')
|
|
227
250
|
print('~~~~~~~~~~~~~~\n')
|
|
228
251
|
|
|
229
|
-
#
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
252
|
+
# 查找环境配置文件(jenkins-config.json)
|
|
253
|
+
config_file = find_config_file('jenkins-config.json', config_search_paths)
|
|
254
|
+
if config_file is None:
|
|
255
|
+
print('❌ 未找到 jenkins-config.json')
|
|
256
|
+
print(f' 请将配置文件放到以下任一位置:')
|
|
257
|
+
for p in config_search_paths:
|
|
258
|
+
print(f' - {os.path.join(p, "jenkins-config.json")}')
|
|
259
|
+
print(f'\n 或运行: npx ai-engineering-init config --type jenkins')
|
|
260
|
+
exit(1)
|
|
261
|
+
print(f'配置文件: {config_file}')
|
|
262
|
+
|
|
263
|
+
# 确保构建状态目录存在
|
|
264
|
+
os.makedirs(state_dir, exist_ok=True)
|
|
265
|
+
state_file = os.path.join(state_dir, 'last_cd_env.json')
|
|
266
|
+
|
|
267
|
+
# 读取上一次构建的环境(如果不存在则使用默认值)
|
|
268
|
+
if os.path.exists(state_file):
|
|
269
|
+
with open(state_file, 'r', encoding='utf-8') as f:
|
|
270
|
+
cd_env_json = json.load(f)
|
|
271
|
+
else:
|
|
272
|
+
cd_env_json = {
|
|
273
|
+
"build_mode": "1",
|
|
274
|
+
"cd_env": "dev1",
|
|
275
|
+
"core_param_branch": "master",
|
|
276
|
+
"api_param_branch": "master",
|
|
277
|
+
"api_param_folder": None
|
|
278
|
+
}
|
|
234
279
|
|
|
235
280
|
# 从终端获取用户输入模式
|
|
236
281
|
build_mode = input(f"请输入模式 0-只构建 1-全构建+更新 2-构建api+更新 3-只更新(预设{cd_env_json['build_mode']}):", ) or cd_env_json['build_mode']
|
|
@@ -245,7 +290,6 @@ core_param_branch = input(f"请输入core分支(预设:{cd_env_json['core_pa
|
|
|
245
290
|
api_param_branch = input(f"请输入api分支(预设:{cd_env_json['api_param_branch']}):") or cd_env_json['api_param_branch']
|
|
246
291
|
|
|
247
292
|
# 从终端输入api文件夹名
|
|
248
|
-
# 读取上一次构建的分支
|
|
249
293
|
api_param_folder = input(f"请输入定制工程文件夹名(空格或None表示不需要,预设:{cd_env_json['api_param_folder']}):") or cd_env_json['api_param_folder']
|
|
250
294
|
|
|
251
295
|
# 校验模式:
|
|
@@ -270,21 +314,19 @@ if cd_env.startswith('dev') and int(cd_env[3:]) >= 44 and build_mode != '0':
|
|
|
270
314
|
print("dev43及以上环境只能使用模式0,结束")
|
|
271
315
|
exit(1)
|
|
272
316
|
|
|
273
|
-
#
|
|
317
|
+
# 保存到本地状态文件
|
|
274
318
|
cd_env_json['cd_env'] = cd_env
|
|
275
319
|
cd_env_json['core_param_branch'] = core_param_branch
|
|
276
320
|
cd_env_json['api_param_branch'] = api_param_branch
|
|
277
321
|
cd_env_json['api_param_folder'] = api_param_folder
|
|
278
322
|
cd_env_json['build_mode'] = build_mode
|
|
279
|
-
json.dump(cd_env_json, open(
|
|
280
|
-
|
|
281
|
-
# exit(0)
|
|
323
|
+
json.dump(cd_env_json, open(state_file, 'w', encoding='utf-8'), ensure_ascii=False)
|
|
282
324
|
|
|
283
325
|
# 根据环境输入,设置前缀
|
|
284
326
|
env_prefix = 'dev' if cd_env.startswith('dev') else 'test'
|
|
285
327
|
|
|
286
|
-
#
|
|
287
|
-
with open(
|
|
328
|
+
# 读取环境配置(从全局或本地 jenkins-config.json)
|
|
329
|
+
with open(config_file, 'r', encoding='utf-8') as f:
|
|
288
330
|
env_param = json.load(f)
|
|
289
331
|
|
|
290
332
|
jenkins_user_id = env_param['jenkins_user_id'][env_prefix]
|
|
@@ -331,10 +373,6 @@ if int(build_mode) < 2:
|
|
|
331
373
|
if int(build_mode) < 3:
|
|
332
374
|
print('开始构建api:' + api_job + ' ' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
|
|
333
375
|
rs = do_job(j_server, api_job, api_param_branch, cd_env, api_timeout)
|
|
334
|
-
# 如果构建api失败,再次构建
|
|
335
|
-
# if rs is False:
|
|
336
|
-
# print('第一次构建api失败,再次构建')
|
|
337
|
-
# rs = do_job_1(j_server, api_job, api_param_branch, cd_env, api_timeout)
|
|
338
376
|
if rs is False:
|
|
339
377
|
print('构建api失败,结束')
|
|
340
378
|
exit(1)
|
|
@@ -15,21 +15,20 @@ description: |
|
|
|
15
15
|
|
|
16
16
|
# Jenkins + Portainer 自动打包部署
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## 架构
|
|
19
19
|
|
|
20
|
-
项目使用 `jenkins/` 目录下的 Python 脚本实现自动化构建部署,流程:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
Jenkins 构建 core → Jenkins 构建 api → Portainer 更新容器
|
|
24
20
|
```
|
|
21
|
+
技能目录(随框架更新,不复制到项目):
|
|
22
|
+
~/.claude/skills/jenkins-deploy/assets/jk_build.py ← 构建脚本
|
|
23
|
+
|
|
24
|
+
全局配置(一次性配置,所有项目共享):
|
|
25
|
+
~/.claude/jenkins-config.json ← 凭证(Jenkins/Portainer)
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
项目本地(自动生成):
|
|
28
|
+
jenkins/last_cd_env.json ← 构建状态(环境、分支、模式)
|
|
29
|
+
```
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|------|------|
|
|
30
|
-
| `jenkins/jk_build.py` | 主构建脚本 |
|
|
31
|
-
| `jenkins/env_param.json` | 环境配置(Jenkins/Portainer 连接参数) |
|
|
32
|
-
| `jenkins/last_cd_env.json` | 上次构建参数(自动保存) |
|
|
31
|
+
脚本按 **本地 `.claude/` > 全局 `~/.claude/`** 优先级查找 `jenkins-config.json`。
|
|
33
32
|
|
|
34
33
|
## 构建模式
|
|
35
34
|
|
|
@@ -42,156 +41,84 @@ Jenkins 构建 core → Jenkins 构建 api → Portainer 更新容器
|
|
|
42
41
|
|
|
43
42
|
## 环境支持
|
|
44
43
|
|
|
45
|
-
| 环境 | 前缀 |
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
52
|
-
## 定制项目支持
|
|
53
|
-
|
|
54
|
-
当指定 `api_param_folder`(定制工程文件夹名)时,Jenkins Job 路径变为:
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
{folder_name}/dev-后端-core # 替代 dev-tengyun-core
|
|
58
|
-
{folder_name}/dev-后端-api # 替代 dev-tengyun-yunshitang-api
|
|
59
|
-
```
|
|
44
|
+
| 环境 | 前缀 | Portainer 更新方式 |
|
|
45
|
+
|------|------|-------------------|
|
|
46
|
+
| dev1~15 | `dev` | Webhook 触发 |
|
|
47
|
+
| dev16~43 | `dev` | Force Update(xnzn-dev.xnzn.net) |
|
|
48
|
+
| dev44+ | `dev` | 只支持模式 0(手动更新) |
|
|
49
|
+
| test | `test` | Webhook 触发 |
|
|
60
50
|
|
|
61
51
|
## 使用方式
|
|
62
52
|
|
|
63
|
-
###
|
|
53
|
+
### 运行构建脚本
|
|
64
54
|
|
|
65
55
|
```bash
|
|
66
|
-
|
|
56
|
+
python ~/.claude/skills/jenkins-deploy/assets/jk_build.py
|
|
67
57
|
```
|
|
68
58
|
|
|
69
|
-
|
|
70
|
-
1. **模式**(0/1/2/3)
|
|
71
|
-
2. **环境**(dev1, dev2, test1 等)
|
|
72
|
-
3. **core 分支**(如 release_5.56.0)
|
|
73
|
-
4. **api 分支**(如 master)
|
|
74
|
-
5. **定制工程文件夹**(可选,空格或 None 跳过)
|
|
59
|
+
脚本交互式询问:模式 → 环境 → core 分支 → api 分支 → 定制工程文件夹
|
|
75
60
|
|
|
76
|
-
### 通过
|
|
61
|
+
### 通过 AI 辅助部署
|
|
77
62
|
|
|
78
63
|
当用户说"打包到 devX"时:
|
|
79
64
|
|
|
80
|
-
1.
|
|
81
|
-
2.
|
|
82
|
-
3.
|
|
83
|
-
4.
|
|
65
|
+
1. 读取 `jenkins/last_cd_env.json` 获取上次参数
|
|
66
|
+
2. 确认参数:环境、分支、模式
|
|
67
|
+
3. 修改 `jenkins/last_cd_env.json` 写入新参数
|
|
68
|
+
4. 执行 `python ~/.claude/skills/jenkins-deploy/assets/jk_build.py`
|
|
84
69
|
|
|
85
|
-
##
|
|
70
|
+
## 配置文件
|
|
86
71
|
|
|
87
|
-
###
|
|
72
|
+
### jenkins-config.json(凭证,全局)
|
|
88
73
|
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
"build_mode": "0",
|
|
92
|
-
"cd_env": "dev63",
|
|
93
|
-
"core_param_branch": "release_5.56.0",
|
|
94
|
-
"api_param_branch": "master",
|
|
95
|
-
"api_param_folder": null
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
| 字段 | 说明 |
|
|
100
|
-
|------|------|
|
|
101
|
-
| `build_mode` | 构建模式(0/1/2/3) |
|
|
102
|
-
| `cd_env` | 目标环境(如 dev1, test2) |
|
|
103
|
-
| `core_param_branch` | core 仓库分支 |
|
|
104
|
-
| `api_param_branch` | api 仓库分支 |
|
|
105
|
-
| `api_param_folder` | 定制项目文件夹(null 表示标准项目) |
|
|
74
|
+
位置:`~/.claude/jenkins-config.json`(或本地 `.claude/jenkins-config.json`)
|
|
106
75
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
包含 Jenkins 和 Portainer 的连接参数(用户名、API Token、服务地址等),按 dev/test 环境分组。
|
|
76
|
+
模板:`.claude/skills/jenkins-deploy/assets/env_param.template.json`
|
|
110
77
|
|
|
111
78
|
> **注意**:此文件包含敏感凭证,不要将内容输出到对话中。
|
|
112
79
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
1. 连接 Jenkins(ci.xnzn.net)
|
|
117
|
-
2. 构建 core(参数:BRANCH + VERSION=环境名)
|
|
118
|
-
└─ 轮询构建进度,超时 10 分钟
|
|
119
|
-
3. 构建 api(参数同上)
|
|
120
|
-
└─ 轮询构建进度,超时 5 分钟
|
|
121
|
-
4. 更新 Portainer:
|
|
122
|
-
├─ dev1~15:Webhook 触发
|
|
123
|
-
│ └─ 获取 JWT → 查 Service ID → 获取/创建 Webhook → POST 触发
|
|
124
|
-
└─ dev16+:Force Update
|
|
125
|
-
└─ 获取 JWT → 查 Service ID → PUT forceupdateservice
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## 常见操作
|
|
80
|
+
### last_cd_env.json(构建状态,项目本地)
|
|
129
81
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
# 修改 last_cd_env.json 的 build_mode 为 "2",然后运行
|
|
134
|
-
cd jenkins && python jk_build.py
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### 只需要更新容器(已在 Jenkins 手动构建完)
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
# build_mode 设为 "3"
|
|
141
|
-
cd jenkins && python jk_build.py
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### 部署定制项目
|
|
82
|
+
位置:`jenkins/last_cd_env.json`(脚本自动创建,无需手动初始化)
|
|
145
83
|
|
|
146
84
|
```json
|
|
147
|
-
// last_cd_env.json
|
|
148
85
|
{
|
|
149
|
-
"
|
|
86
|
+
"build_mode": "1",
|
|
87
|
+
"cd_env": "dev1",
|
|
88
|
+
"core_param_branch": "master",
|
|
89
|
+
"api_param_branch": "master",
|
|
90
|
+
"api_param_folder": null
|
|
150
91
|
}
|
|
151
92
|
```
|
|
152
93
|
|
|
153
|
-
##
|
|
94
|
+
## 定制项目
|
|
154
95
|
|
|
155
|
-
|
|
96
|
+
指定 `api_param_folder` 后,Jenkins Job 路径变为:
|
|
156
97
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# 1. 创建 jenkins 目录
|
|
161
|
-
mkdir -p jenkins
|
|
162
|
-
|
|
163
|
-
# 2. 从技能模板复制文件(SKILL_DIR 为技能目录路径)
|
|
164
|
-
cp .claude/skills/jenkins-deploy/assets/jk_build.py jenkins/jk_build.py
|
|
165
|
-
cp .claude/skills/jenkins-deploy/assets/last_cd_env.template.json jenkins/last_cd_env.json
|
|
166
|
-
|
|
167
|
-
# 3. 环境配置需要用户提供(含敏感凭证)
|
|
168
|
-
cp .claude/skills/jenkins-deploy/assets/env_param.template.json jenkins/env_param.json
|
|
169
|
-
|
|
170
|
-
# 4. 安装依赖
|
|
171
|
-
pip install python-jenkins requests
|
|
98
|
+
```
|
|
99
|
+
{folder_name}/dev-后端-core
|
|
100
|
+
{folder_name}/dev-后端-api
|
|
172
101
|
```
|
|
173
102
|
|
|
174
|
-
|
|
103
|
+
## 首次初始化(团队成员)
|
|
175
104
|
|
|
176
|
-
|
|
105
|
+
只需一步:配置全局凭证文件。
|
|
177
106
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
| `__JENKINS_DEV_TOKEN__` | Jenkins dev API Token | Jenkins → 用户 → 设置 → API Token |
|
|
182
|
-
| `__JENKINS_TEST_USER__` | Jenkins test 账号 | 同上 |
|
|
183
|
-
| `__JENKINS_TEST_TOKEN__` | Jenkins test API Token | 同上 |
|
|
184
|
-
| `__PORTAINER_*_USER__` | Portainer 用户名 | 向团队负责人获取 |
|
|
185
|
-
| `__PORTAINER_*_PWD__` | Portainer 密码 | 向团队负责人获取 |
|
|
107
|
+
```bash
|
|
108
|
+
# 方式 1:从团队成员拷贝
|
|
109
|
+
cp /path/to/teammate/jenkins-config.json ~/.claude/jenkins-config.json
|
|
186
110
|
|
|
187
|
-
|
|
111
|
+
# 方式 2:从模板创建,手动填写凭证
|
|
112
|
+
cp ~/.claude/skills/jenkins-deploy/assets/env_param.template.json ~/.claude/jenkins-config.json
|
|
113
|
+
# 然后替换 __JENKINS_*__ 和 __PORTAINER_*__ 占位符
|
|
114
|
+
```
|
|
188
115
|
|
|
189
116
|
### AI 初始化行为
|
|
190
117
|
|
|
191
|
-
当技能被触发但 `jenkins
|
|
192
|
-
1.
|
|
193
|
-
2.
|
|
194
|
-
3.
|
|
118
|
+
当技能被触发但 `jenkins-config.json` 不存在时:
|
|
119
|
+
1. 提示"检测到尚未配置 Jenkins 凭证"
|
|
120
|
+
2. 询问是否从模板创建
|
|
121
|
+
3. 复制模板到 `~/.claude/jenkins-config.json`
|
|
195
122
|
4. 提示用户填写凭证(或拷贝已有配置)
|
|
196
123
|
|
|
197
124
|
## 依赖
|
|
@@ -15,21 +15,20 @@ description: |
|
|
|
15
15
|
|
|
16
16
|
# Jenkins + Portainer 自动打包部署
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## 架构
|
|
19
19
|
|
|
20
|
-
项目使用 `jenkins/` 目录下的 Python 脚本实现自动化构建部署,流程:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
Jenkins 构建 core → Jenkins 构建 api → Portainer 更新容器
|
|
24
20
|
```
|
|
21
|
+
技能目录(随框架更新,不复制到项目):
|
|
22
|
+
~/.claude/skills/jenkins-deploy/assets/jk_build.py ← 构建脚本
|
|
23
|
+
|
|
24
|
+
全局配置(一次性配置,所有项目共享):
|
|
25
|
+
~/.claude/jenkins-config.json ← 凭证(Jenkins/Portainer)
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
项目本地(自动生成):
|
|
28
|
+
jenkins/last_cd_env.json ← 构建状态(环境、分支、模式)
|
|
29
|
+
```
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|------|------|
|
|
30
|
-
| `jenkins/jk_build.py` | 主构建脚本 |
|
|
31
|
-
| `jenkins/env_param.json` | 环境配置(Jenkins/Portainer 连接参数) |
|
|
32
|
-
| `jenkins/last_cd_env.json` | 上次构建参数(自动保存) |
|
|
31
|
+
脚本按 **本地 `.claude/` > 全局 `~/.claude/`** 优先级查找 `jenkins-config.json`。
|
|
33
32
|
|
|
34
33
|
## 构建模式
|
|
35
34
|
|
|
@@ -42,156 +41,84 @@ Jenkins 构建 core → Jenkins 构建 api → Portainer 更新容器
|
|
|
42
41
|
|
|
43
42
|
## 环境支持
|
|
44
43
|
|
|
45
|
-
| 环境 | 前缀 |
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
52
|
-
## 定制项目支持
|
|
53
|
-
|
|
54
|
-
当指定 `api_param_folder`(定制工程文件夹名)时,Jenkins Job 路径变为:
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
{folder_name}/dev-后端-core # 替代 dev-tengyun-core
|
|
58
|
-
{folder_name}/dev-后端-api # 替代 dev-tengyun-yunshitang-api
|
|
59
|
-
```
|
|
44
|
+
| 环境 | 前缀 | Portainer 更新方式 |
|
|
45
|
+
|------|------|-------------------|
|
|
46
|
+
| dev1~15 | `dev` | Webhook 触发 |
|
|
47
|
+
| dev16~43 | `dev` | Force Update(xnzn-dev.xnzn.net) |
|
|
48
|
+
| dev44+ | `dev` | 只支持模式 0(手动更新) |
|
|
49
|
+
| test | `test` | Webhook 触发 |
|
|
60
50
|
|
|
61
51
|
## 使用方式
|
|
62
52
|
|
|
63
|
-
###
|
|
53
|
+
### 运行构建脚本
|
|
64
54
|
|
|
65
55
|
```bash
|
|
66
|
-
|
|
56
|
+
python ~/.claude/skills/jenkins-deploy/assets/jk_build.py
|
|
67
57
|
```
|
|
68
58
|
|
|
69
|
-
|
|
70
|
-
1. **模式**(0/1/2/3)
|
|
71
|
-
2. **环境**(dev1, dev2, test1 等)
|
|
72
|
-
3. **core 分支**(如 release_5.56.0)
|
|
73
|
-
4. **api 分支**(如 master)
|
|
74
|
-
5. **定制工程文件夹**(可选,空格或 None 跳过)
|
|
59
|
+
脚本交互式询问:模式 → 环境 → core 分支 → api 分支 → 定制工程文件夹
|
|
75
60
|
|
|
76
|
-
### 通过
|
|
61
|
+
### 通过 AI 辅助部署
|
|
77
62
|
|
|
78
63
|
当用户说"打包到 devX"时:
|
|
79
64
|
|
|
80
|
-
1.
|
|
81
|
-
2.
|
|
82
|
-
3.
|
|
83
|
-
4.
|
|
65
|
+
1. 读取 `jenkins/last_cd_env.json` 获取上次参数
|
|
66
|
+
2. 确认参数:环境、分支、模式
|
|
67
|
+
3. 修改 `jenkins/last_cd_env.json` 写入新参数
|
|
68
|
+
4. 执行 `python ~/.claude/skills/jenkins-deploy/assets/jk_build.py`
|
|
84
69
|
|
|
85
|
-
##
|
|
70
|
+
## 配置文件
|
|
86
71
|
|
|
87
|
-
###
|
|
72
|
+
### jenkins-config.json(凭证,全局)
|
|
88
73
|
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
"build_mode": "0",
|
|
92
|
-
"cd_env": "dev63",
|
|
93
|
-
"core_param_branch": "release_5.56.0",
|
|
94
|
-
"api_param_branch": "master",
|
|
95
|
-
"api_param_folder": null
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
| 字段 | 说明 |
|
|
100
|
-
|------|------|
|
|
101
|
-
| `build_mode` | 构建模式(0/1/2/3) |
|
|
102
|
-
| `cd_env` | 目标环境(如 dev1, test2) |
|
|
103
|
-
| `core_param_branch` | core 仓库分支 |
|
|
104
|
-
| `api_param_branch` | api 仓库分支 |
|
|
105
|
-
| `api_param_folder` | 定制项目文件夹(null 表示标准项目) |
|
|
74
|
+
位置:`~/.claude/jenkins-config.json`(或本地 `.claude/jenkins-config.json`)
|
|
106
75
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
包含 Jenkins 和 Portainer 的连接参数(用户名、API Token、服务地址等),按 dev/test 环境分组。
|
|
76
|
+
模板:`.claude/skills/jenkins-deploy/assets/env_param.template.json`
|
|
110
77
|
|
|
111
78
|
> **注意**:此文件包含敏感凭证,不要将内容输出到对话中。
|
|
112
79
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
1. 连接 Jenkins(ci.xnzn.net)
|
|
117
|
-
2. 构建 core(参数:BRANCH + VERSION=环境名)
|
|
118
|
-
└─ 轮询构建进度,超时 10 分钟
|
|
119
|
-
3. 构建 api(参数同上)
|
|
120
|
-
└─ 轮询构建进度,超时 5 分钟
|
|
121
|
-
4. 更新 Portainer:
|
|
122
|
-
├─ dev1~15:Webhook 触发
|
|
123
|
-
│ └─ 获取 JWT → 查 Service ID → 获取/创建 Webhook → POST 触发
|
|
124
|
-
└─ dev16+:Force Update
|
|
125
|
-
└─ 获取 JWT → 查 Service ID → PUT forceupdateservice
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## 常见操作
|
|
80
|
+
### last_cd_env.json(构建状态,项目本地)
|
|
129
81
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
# 修改 last_cd_env.json 的 build_mode 为 "2",然后运行
|
|
134
|
-
cd jenkins && python jk_build.py
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### 只需要更新容器(已在 Jenkins 手动构建完)
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
# build_mode 设为 "3"
|
|
141
|
-
cd jenkins && python jk_build.py
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### 部署定制项目
|
|
82
|
+
位置:`jenkins/last_cd_env.json`(脚本自动创建,无需手动初始化)
|
|
145
83
|
|
|
146
84
|
```json
|
|
147
|
-
// last_cd_env.json
|
|
148
85
|
{
|
|
149
|
-
"
|
|
86
|
+
"build_mode": "1",
|
|
87
|
+
"cd_env": "dev1",
|
|
88
|
+
"core_param_branch": "master",
|
|
89
|
+
"api_param_branch": "master",
|
|
90
|
+
"api_param_folder": null
|
|
150
91
|
}
|
|
151
92
|
```
|
|
152
93
|
|
|
153
|
-
##
|
|
94
|
+
## 定制项目
|
|
154
95
|
|
|
155
|
-
|
|
96
|
+
指定 `api_param_folder` 后,Jenkins Job 路径变为:
|
|
156
97
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# 1. 创建 jenkins 目录
|
|
161
|
-
mkdir -p jenkins
|
|
162
|
-
|
|
163
|
-
# 2. 从技能模板复制文件(SKILL_DIR 为技能目录路径)
|
|
164
|
-
cp .claude/skills/jenkins-deploy/assets/jk_build.py jenkins/jk_build.py
|
|
165
|
-
cp .claude/skills/jenkins-deploy/assets/last_cd_env.template.json jenkins/last_cd_env.json
|
|
166
|
-
|
|
167
|
-
# 3. 环境配置需要用户提供(含敏感凭证)
|
|
168
|
-
cp .claude/skills/jenkins-deploy/assets/env_param.template.json jenkins/env_param.json
|
|
169
|
-
|
|
170
|
-
# 4. 安装依赖
|
|
171
|
-
pip install python-jenkins requests
|
|
98
|
+
```
|
|
99
|
+
{folder_name}/dev-后端-core
|
|
100
|
+
{folder_name}/dev-后端-api
|
|
172
101
|
```
|
|
173
102
|
|
|
174
|
-
|
|
103
|
+
## 首次初始化(团队成员)
|
|
175
104
|
|
|
176
|
-
|
|
105
|
+
只需一步:配置全局凭证文件。
|
|
177
106
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
| `__JENKINS_DEV_TOKEN__` | Jenkins dev API Token | Jenkins → 用户 → 设置 → API Token |
|
|
182
|
-
| `__JENKINS_TEST_USER__` | Jenkins test 账号 | 同上 |
|
|
183
|
-
| `__JENKINS_TEST_TOKEN__` | Jenkins test API Token | 同上 |
|
|
184
|
-
| `__PORTAINER_*_USER__` | Portainer 用户名 | 向团队负责人获取 |
|
|
185
|
-
| `__PORTAINER_*_PWD__` | Portainer 密码 | 向团队负责人获取 |
|
|
107
|
+
```bash
|
|
108
|
+
# 方式 1:从团队成员拷贝
|
|
109
|
+
cp /path/to/teammate/jenkins-config.json ~/.claude/jenkins-config.json
|
|
186
110
|
|
|
187
|
-
|
|
111
|
+
# 方式 2:从模板创建,手动填写凭证
|
|
112
|
+
cp ~/.claude/skills/jenkins-deploy/assets/env_param.template.json ~/.claude/jenkins-config.json
|
|
113
|
+
# 然后替换 __JENKINS_*__ 和 __PORTAINER_*__ 占位符
|
|
114
|
+
```
|
|
188
115
|
|
|
189
116
|
### AI 初始化行为
|
|
190
117
|
|
|
191
|
-
当技能被触发但 `jenkins
|
|
192
|
-
1.
|
|
193
|
-
2.
|
|
194
|
-
3.
|
|
118
|
+
当技能被触发但 `jenkins-config.json` 不存在时:
|
|
119
|
+
1. 提示"检测到尚未配置 Jenkins 凭证"
|
|
120
|
+
2. 询问是否从模板创建
|
|
121
|
+
3. 复制模板到 `~/.claude/jenkins-config.json`
|
|
195
122
|
4. 提示用户填写凭证(或拷贝已有配置)
|
|
196
123
|
|
|
197
124
|
## 依赖
|
package/bin/index.js
CHANGED
|
@@ -591,17 +591,23 @@ function showDoneHint(toolKey) {
|
|
|
591
591
|
|
|
592
592
|
/** 检测 jenkins/ 是否已初始化,提示用户配置部署环境 */
|
|
593
593
|
function showJenkinsHint() {
|
|
594
|
-
const
|
|
595
|
-
const
|
|
594
|
+
const homeClaudeDir = path.join(os.homedir(), '.claude');
|
|
595
|
+
const globalConfig = path.join(homeClaudeDir, 'jenkins-config.json');
|
|
596
|
+
const localConfig = path.join(targetDir, '.claude', 'jenkins-config.json');
|
|
596
597
|
const skillAssetsDir = path.join(targetDir, '.claude', 'skills', 'jenkins-deploy', 'assets');
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
598
|
+
// 全局安装时也检查全局技能目录
|
|
599
|
+
const globalSkillDir = path.join(homeClaudeDir, 'skills', 'jenkins-deploy', 'assets');
|
|
600
|
+
|
|
601
|
+
const hasSkill = fs.existsSync(skillAssetsDir) || fs.existsSync(globalSkillDir);
|
|
602
|
+
const hasConfig = fs.existsSync(globalConfig) || fs.existsSync(localConfig);
|
|
603
|
+
|
|
604
|
+
// 技能存在但凭证未配置
|
|
605
|
+
if (hasSkill && !hasConfig) {
|
|
606
|
+
console.log(fmt('yellow', fmt('bold', '📦 Jenkins 部署凭证未配置')));
|
|
607
|
+
console.log(` 已安装 ${fmt('bold', 'jenkins-deploy')} 技能,但 ${fmt('bold', 'jenkins-config.json')} 尚未配置。`);
|
|
608
|
+
console.log(` 配置方式:`);
|
|
609
|
+
console.log(` 方式 1:从团队成员处拷贝 ${fmt('bold', '~/.claude/jenkins-config.json')}`);
|
|
610
|
+
console.log(` 方式 2:在 AI 对话中说 ${fmt('bold', '"初始化部署环境"')}`);
|
|
605
611
|
console.log('');
|
|
606
612
|
}
|
|
607
613
|
}
|
package/package.json
CHANGED