hydro-ai-helper 1.8.5 → 1.10.0
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/.github/AUTOMATION.md +280 -0
- package/.github/workflows/npm-publish.yml +71 -0
- package/.github/workflows/sync-releases-to-gitee.yml +34 -14
- package/TROUBLESHOOTING.md +31 -0
- package/assets/trusted-keys/publisher.asc +63 -0
- package/dist/handlers/updateHandler.js +5 -0
- package/dist/handlers/updateHandler.js.map +1 -1
- package/dist/services/updateService.js +1089 -51
- package/dist/services/updateService.js.map +1 -1
- package/frontend/teacher/ConversationList.tsx +0 -26
- package/frontend/test.page.ts +12 -9
- package/package.json +1 -1
- package/src/handlers/updateHandler.ts +11 -0
- package/src/services/updateService.ts +1276 -57
- package/dist/__tests__/__mocks__/hydrooj.js +0 -29
- package/dist/__tests__/__mocks__/hydrooj.js.map +0 -1
- package/dist/index.d.ts +0 -22
- package/dist/index.d.ts.map +0 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# GitHub Actions 自动发布配置指南
|
|
2
|
+
|
|
3
|
+
## 📦 功能说明
|
|
4
|
+
|
|
5
|
+
当你推送新的 git tag(如 `v1.8.6`)到 GitHub 时,会自动:
|
|
6
|
+
1. ✅ 构建 TypeScript 代码
|
|
7
|
+
2. ✅ 验证版本号一致性
|
|
8
|
+
3. ✅ 发布到 npm
|
|
9
|
+
4. ✅ 创建 GitHub Release
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 🔧 配置步骤
|
|
14
|
+
|
|
15
|
+
### Step 1: 创建 npm Automation Token
|
|
16
|
+
|
|
17
|
+
1. **访问** npm Tokens 页面:
|
|
18
|
+
https://www.npmjs.com/settings/npmdwhguieg/tokens
|
|
19
|
+
|
|
20
|
+
2. **点击** "Generate New Token"
|
|
21
|
+
|
|
22
|
+
3. **选择配置**:
|
|
23
|
+
- **Token Type**: `Granular Access Token` 或 `Automation`
|
|
24
|
+
- **Expiration**: 建议 `No expiration` 或 `365 days`
|
|
25
|
+
- **Packages and scopes**:
|
|
26
|
+
- Permissions: `Read and write`
|
|
27
|
+
- Packages: `hydro-ai-helper` 或 `All packages`
|
|
28
|
+
|
|
29
|
+
4. **完成安全验证**(指纹/密钥)
|
|
30
|
+
|
|
31
|
+
5. **复制生成的 token**(格式:`npm_xxxxxxxxxxxxx`)
|
|
32
|
+
- ⚠️ **重要**:token 只会显示一次,请立即保存
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### Step 2: 添加 GitHub Secret
|
|
37
|
+
|
|
38
|
+
1. **访问** 你的 GitHub 仓库设置:
|
|
39
|
+
https://github.com/AltureT/hydro-ai-helper/settings/secrets/actions
|
|
40
|
+
|
|
41
|
+
2. **点击** "New repository secret"
|
|
42
|
+
|
|
43
|
+
3. **填写信息**:
|
|
44
|
+
- **Name**: `NPM_TOKEN`(必须完全一致)
|
|
45
|
+
- **Secret**: 粘贴你刚才复制的 npm token
|
|
46
|
+
|
|
47
|
+
4. **点击** "Add secret"
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### Step 3: 验证配置
|
|
52
|
+
|
|
53
|
+
运行以下命令测试自动发布:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# 1. 确保代码已提交
|
|
57
|
+
git status
|
|
58
|
+
|
|
59
|
+
# 2. 升级版本号(例如 1.8.5 → 1.8.6)
|
|
60
|
+
npm version patch # 或 minor/major
|
|
61
|
+
|
|
62
|
+
# 3. 推送代码和 tag
|
|
63
|
+
git push origin main --tags
|
|
64
|
+
|
|
65
|
+
# 4. 查看 GitHub Actions 执行情况
|
|
66
|
+
# 访问:https://github.com/AltureT/hydro-ai-helper/actions
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 🚀 使用流程
|
|
72
|
+
|
|
73
|
+
### 发布新版本的完整流程
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# 1. 修改代码并测试
|
|
77
|
+
npm run build:plugin
|
|
78
|
+
npm test # 如果有测试
|
|
79
|
+
|
|
80
|
+
# 2. 提交代码
|
|
81
|
+
git add .
|
|
82
|
+
git commit -m "feat: 新功能描述"
|
|
83
|
+
|
|
84
|
+
# 3. 升级版本(自动修改 package.json 并创建 git tag)
|
|
85
|
+
npm version patch # 小版本:1.8.5 → 1.8.6
|
|
86
|
+
# 或
|
|
87
|
+
npm version minor # 中版本:1.8.6 → 1.9.0
|
|
88
|
+
# 或
|
|
89
|
+
npm version major # 大版本:1.9.0 → 2.0.0
|
|
90
|
+
|
|
91
|
+
# 4. 推送(触发自动发布)
|
|
92
|
+
git push origin main --tags
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**自动执行**:
|
|
96
|
+
- ✅ GitHub Actions 检测到新 tag
|
|
97
|
+
- ✅ ���动构建、测试、发布
|
|
98
|
+
- ✅ 创建 GitHub Release
|
|
99
|
+
- ✅ 5-10 分钟后在 npm 上可见
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 📋 版本号规范
|
|
104
|
+
|
|
105
|
+
遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/):
|
|
106
|
+
|
|
107
|
+
- **Patch** (1.8.5 → 1.8.6):Bug 修复、小改进
|
|
108
|
+
- **Minor** (1.8.6 → 1.9.0):新功能(向后兼容)
|
|
109
|
+
- **Major** (1.9.0 → 2.0.0):破坏性变更(不向后兼容)
|
|
110
|
+
|
|
111
|
+
**Tag 格式**:
|
|
112
|
+
- ✅ 正确:`v1.8.6`, `v2.0.0`, `v1.9.0-beta.1`
|
|
113
|
+
- ❌ 错误:`1.8.6`, `version-1.8.6`, `release-v1.8.6`
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 🔍 故障排查
|
|
118
|
+
|
|
119
|
+
### 问题 1:发布失败 - "401 Unauthorized"
|
|
120
|
+
|
|
121
|
+
**原因**:NPM_TOKEN 未配置或已过期
|
|
122
|
+
|
|
123
|
+
**解决**:
|
|
124
|
+
1. 检查 GitHub Secret 是否存在
|
|
125
|
+
2. 重新生成 npm token
|
|
126
|
+
3. 更新 GitHub Secret
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### 问题 2:发布失败 - "版本已存在"
|
|
131
|
+
|
|
132
|
+
**原因**:npm 上已有相同版本号
|
|
133
|
+
|
|
134
|
+
**解决**:
|
|
135
|
+
```bash
|
|
136
|
+
# 删除本地 tag
|
|
137
|
+
git tag -d v1.8.6
|
|
138
|
+
|
|
139
|
+
# 删除远程 tag
|
|
140
|
+
git push origin :refs/tags/v1.8.6
|
|
141
|
+
|
|
142
|
+
# 升级版本号
|
|
143
|
+
npm version patch
|
|
144
|
+
|
|
145
|
+
# 重新推送
|
|
146
|
+
git push origin main --tags
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### 问题 3:版本号不一致错误
|
|
152
|
+
|
|
153
|
+
**原因**:Tag 版本与 package.json 版本不匹配
|
|
154
|
+
|
|
155
|
+
**解决**:
|
|
156
|
+
```bash
|
|
157
|
+
# 始终使用 npm version 命令(自动同步)
|
|
158
|
+
npm version patch
|
|
159
|
+
|
|
160
|
+
# 不要手动修改 package.json 后创建 tag
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### 问题 4:如何手动触发发布?
|
|
166
|
+
|
|
167
|
+
如果自动发布失败,可以手动触发:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# 方法 1:使用 GitHub CLI
|
|
171
|
+
gh workflow run npm-publish.yml
|
|
172
|
+
|
|
173
|
+
# 方法 2:在 GitHub 网页手动触发
|
|
174
|
+
# 访问:https://github.com/AltureT/hydro-ai-helper/actions
|
|
175
|
+
# 选择 "Publish to npm" → "Run workflow"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 📊 监控发布状态
|
|
181
|
+
|
|
182
|
+
### 查看 Actions 执行日志
|
|
183
|
+
|
|
184
|
+
访问:https://github.com/AltureT/hydro-ai-helper/actions
|
|
185
|
+
|
|
186
|
+
**成功标志**:
|
|
187
|
+
- ✅ 绿色勾号
|
|
188
|
+
- ✅ 日志中显示 "🎉 成功发布"
|
|
189
|
+
|
|
190
|
+
**失败标志**:
|
|
191
|
+
- ❌ 红色叉号
|
|
192
|
+
- ❌ 日志中显示错误信息
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### 验证发布成功
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# 检查 npm 版本
|
|
200
|
+
npm view hydro-ai-helper version
|
|
201
|
+
|
|
202
|
+
# 检查 GitHub Release
|
|
203
|
+
gh release list
|
|
204
|
+
|
|
205
|
+
# 检查徽章
|
|
206
|
+
curl https://img.shields.io/github/v/release/AltureT/hydro-ai-helper
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 🔒 安全注意事项
|
|
212
|
+
|
|
213
|
+
1. ✅ **NPM_TOKEN 是敏感信息**,仅保存在 GitHub Secrets 中
|
|
214
|
+
2. ✅ **不要提交 token** 到代码仓库或 .npmrc
|
|
215
|
+
3. ✅ **定期轮换 token**(建议 90-180 天)
|
|
216
|
+
4. ✅ **限制 token 权限**(仅授予必要的包)
|
|
217
|
+
5. ✅ **启用 2FA**(双因素认证)
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 📚 参考资源
|
|
222
|
+
|
|
223
|
+
- GitHub Actions 文档:https://docs.github.com/en/actions
|
|
224
|
+
- npm Publishing 指南:https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry
|
|
225
|
+
- Semantic Versioning:https://semver.org/lang/zh-CN/
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## ❓ 常见问题
|
|
230
|
+
|
|
231
|
+
### Q1: 能否同时发布到多个 npm registry?
|
|
232
|
+
|
|
233
|
+
可以,在 workflow 中添加多个发布步骤:
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
- name: 发布到 npm
|
|
237
|
+
run: npm publish --access public
|
|
238
|
+
env:
|
|
239
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
240
|
+
|
|
241
|
+
- name: 发布到 GitHub Packages
|
|
242
|
+
run: npm publish --registry=https://npm.pkg.github.com
|
|
243
|
+
env:
|
|
244
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
### Q2: 如何发布 beta 版本?
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# 创建 beta 版本
|
|
253
|
+
npm version prerelease --preid=beta
|
|
254
|
+
# 例如:1.8.5 → 1.8.6-beta.0
|
|
255
|
+
|
|
256
|
+
# 推送
|
|
257
|
+
git push origin main --tags
|
|
258
|
+
|
|
259
|
+
# npm 上会标记为 beta
|
|
260
|
+
npm install hydro-ai-helper@beta
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### Q3: 能否在发布前自动运行测试?
|
|
266
|
+
|
|
267
|
+
可以,在 workflow 中添加测试步骤:
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
- name: 运行测试
|
|
271
|
+
run: npm test
|
|
272
|
+
|
|
273
|
+
- name: 发布到 npm
|
|
274
|
+
if: success() # 仅测试通过时发布
|
|
275
|
+
run: npm publish
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
**配置完成后,你只需要运行 `npm version patch && git push --tags`,其余全部自动化!**
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*' # 匹配 v1.0.0, v1.8.5 等格式的 tag
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write # 需要写入权限以创建 Release
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout 代码
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: 设置 Node.js
|
|
20
|
+
uses: actions/setup-node@v4
|
|
21
|
+
with:
|
|
22
|
+
node-version: '22'
|
|
23
|
+
registry-url: 'https://registry.npmjs.org'
|
|
24
|
+
|
|
25
|
+
- name: 安装依赖
|
|
26
|
+
run: npm ci
|
|
27
|
+
|
|
28
|
+
- name: 构建插件
|
|
29
|
+
run: npm run build:plugin
|
|
30
|
+
|
|
31
|
+
- name: 验证版本一致性
|
|
32
|
+
run: |
|
|
33
|
+
TAG_VERSION=${GITHUB_REF#refs/tags/v}
|
|
34
|
+
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
35
|
+
|
|
36
|
+
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
|
|
37
|
+
echo "❌ 错误:Tag 版本 ($TAG_VERSION) 与 package.json 版本 ($PKG_VERSION) 不一致"
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
echo "✅ 版本验证通过:$TAG_VERSION"
|
|
42
|
+
|
|
43
|
+
- name: 发布到 npm
|
|
44
|
+
run: npm publish --access public
|
|
45
|
+
env:
|
|
46
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
47
|
+
|
|
48
|
+
- name: 创建 GitHub Release
|
|
49
|
+
uses: softprops/action-gh-release@v1
|
|
50
|
+
with:
|
|
51
|
+
generate_release_notes: true # 自动生成 Release Notes
|
|
52
|
+
draft: false
|
|
53
|
+
prerelease: false
|
|
54
|
+
env:
|
|
55
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
56
|
+
|
|
57
|
+
- name: 发布成功通知
|
|
58
|
+
if: success()
|
|
59
|
+
run: |
|
|
60
|
+
echo "🎉 成功发布 ${{ github.ref_name }} 到 npm"
|
|
61
|
+
echo "📦 npm: https://www.npmjs.com/package/hydro-ai-helper"
|
|
62
|
+
echo "🏷️ GitHub Release: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}"
|
|
63
|
+
|
|
64
|
+
- name: 发布失败通知
|
|
65
|
+
if: failure()
|
|
66
|
+
run: |
|
|
67
|
+
echo "❌ 发布失败,请检查日志"
|
|
68
|
+
echo "可能的原因:"
|
|
69
|
+
echo "1. NPM_TOKEN 未配置或已过期"
|
|
70
|
+
echo "2. 版本号与 package.json 不一致"
|
|
71
|
+
echo "3. npm 包名已被占用"
|
|
@@ -44,12 +44,17 @@ jobs:
|
|
|
44
44
|
- name: Check if release exists on Gitee
|
|
45
45
|
id: check
|
|
46
46
|
run: |
|
|
47
|
-
|
|
47
|
+
# 获取 release 信息,如果不存在会返回错误信息
|
|
48
|
+
RESPONSE=$(curl -s \
|
|
48
49
|
"https://gitee.com/api/v5/repos/alture/hydro-ai-helper/releases/tags/${{ steps.release.outputs.tag_name }}?access_token=${{ secrets.GITEE_ACCESS_TOKEN }}")
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
# 检查返回的 JSON 是否包含 id 字段(存在)或 message 字段(不存在)
|
|
52
|
+
RELEASE_ID=$(echo "$RESPONSE" | jq -r '.id // empty')
|
|
53
|
+
|
|
54
|
+
if [ -n "$RELEASE_ID" ]; then
|
|
51
55
|
echo "exists=true" >> $GITHUB_OUTPUT
|
|
52
|
-
echo "
|
|
56
|
+
echo "release_id=${RELEASE_ID}" >> $GITHUB_OUTPUT
|
|
57
|
+
echo "Release already exists on Gitee (ID: ${RELEASE_ID}), will update"
|
|
53
58
|
else
|
|
54
59
|
echo "exists=false" >> $GITHUB_OUTPUT
|
|
55
60
|
echo "Release does not exist on Gitee, will create"
|
|
@@ -70,13 +75,10 @@ jobs:
|
|
|
70
75
|
fi
|
|
71
76
|
|
|
72
77
|
if [ "${{ steps.check.outputs.exists }}" = "true" ]; then
|
|
73
|
-
#
|
|
74
|
-
RELEASE_ID
|
|
75
|
-
"https://gitee.com/api/v5/repos/alture/hydro-ai-helper/releases/tags/${TAG_NAME}?access_token=${{ secrets.GITEE_ACCESS_TOKEN }}" \
|
|
76
|
-
| jq -r '.id')
|
|
78
|
+
# Update existing release using the ID from check step
|
|
79
|
+
RELEASE_ID="${{ steps.check.outputs.release_id }}"
|
|
77
80
|
|
|
78
|
-
|
|
79
|
-
curl -X PATCH \
|
|
81
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" -X PATCH \
|
|
80
82
|
"https://gitee.com/api/v5/repos/alture/hydro-ai-helper/releases/${RELEASE_ID}" \
|
|
81
83
|
-H "Content-Type: application/json" \
|
|
82
84
|
-d "$(jq -n \
|
|
@@ -91,12 +93,21 @@ jobs:
|
|
|
91
93
|
name: $name,
|
|
92
94
|
body: $body,
|
|
93
95
|
prerelease: $prerelease
|
|
94
|
-
}')"
|
|
96
|
+
}')")
|
|
97
|
+
|
|
98
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
99
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
95
100
|
|
|
96
|
-
|
|
101
|
+
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
|
|
102
|
+
echo "✅ Release updated on Gitee successfully"
|
|
103
|
+
else
|
|
104
|
+
echo "❌ Failed to update release on Gitee (HTTP $HTTP_CODE)"
|
|
105
|
+
echo "Response: $BODY"
|
|
106
|
+
exit 1
|
|
107
|
+
fi
|
|
97
108
|
else
|
|
98
109
|
# Create new release
|
|
99
|
-
curl -X POST \
|
|
110
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
|
|
100
111
|
"https://gitee.com/api/v5/repos/alture/hydro-ai-helper/releases" \
|
|
101
112
|
-H "Content-Type: application/json" \
|
|
102
113
|
-d "$(jq -n \
|
|
@@ -113,7 +124,16 @@ jobs:
|
|
|
113
124
|
body: $body,
|
|
114
125
|
target_commitish: $branch,
|
|
115
126
|
prerelease: $prerelease
|
|
116
|
-
}')"
|
|
127
|
+
}')")
|
|
128
|
+
|
|
129
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
130
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "200" ]; then
|
|
133
|
+
echo "✅ Release created on Gitee successfully"
|
|
134
|
+
else
|
|
135
|
+
echo "❌ Failed to create release on Gitee (HTTP $HTTP_CODE)"
|
|
136
|
+
echo "Response: $BODY"
|
|
137
|
+
exit 1
|
|
138
|
+
fi
|
|
119
139
|
fi
|
package/TROUBLESHOOTING.md
CHANGED
|
@@ -317,6 +317,37 @@ pm2 logs hydrooj | grep TelemetryService
|
|
|
317
317
|
|
|
318
318
|
---
|
|
319
319
|
|
|
320
|
+
## 一键更新(后台)故障排查
|
|
321
|
+
|
|
322
|
+
### 1. 前置条件(必须)
|
|
323
|
+
|
|
324
|
+
- `git`、`npm`、`gpg`、`pm2` 在服务器上可用(可执行且在 PATH 中)。
|
|
325
|
+
- 插件目录包含 `assets/trusted-keys/publisher.asc`(用于校验发布者签名)。
|
|
326
|
+
|
|
327
|
+
### 2. 常见失败原因
|
|
328
|
+
|
|
329
|
+
1) **提示:未检测到可用的 gpg(GnuPG)**
|
|
330
|
+
- 解决:安装 `gpg` 后重试(例如:Debian/Ubuntu `sudo apt-get install gnupg`;macOS `brew install gnupg`)。
|
|
331
|
+
|
|
332
|
+
2) **提示:上游仓库未启用 GPG 签名 / 签名无效 / 指纹不在信任列表**
|
|
333
|
+
- 说明:为保证更新代码来源可信,“一键更新”会强制校验最新 commit 的 GPG 签名,并核对发布者主密钥指纹白名单。
|
|
334
|
+
- 解决:
|
|
335
|
+
- 确认上游 main 分支最新 commit 已签名;
|
|
336
|
+
- 确认签名主密钥指纹与插件内白名单一致;
|
|
337
|
+
- 若发布者更换密钥,需要更新 `assets/trusted-keys/publisher.asc` 与白名单指纹后再更新。
|
|
338
|
+
|
|
339
|
+
3) **提示:依赖安装失败(默认禁用 npm scripts)**
|
|
340
|
+
- 说明:为降低供应链风险,更新过程默认使用 `npm ci/install --ignore-scripts`,不会执行依赖包的 `install/postinstall` 脚本。
|
|
341
|
+
- 解决(谨慎):若确实需要执行 scripts 才能安装成功,可在运行 HydroOJ 的环境中设置:
|
|
342
|
+
- `AI_HELPER_UPDATE_ALLOW_NPM_SCRIPTS=1`
|
|
343
|
+
- 风险:启用后依赖包安装脚本可能在服务器上执行,请确认来源与变更可信。
|
|
344
|
+
|
|
345
|
+
4) **页面提示 502 / 连接中断**
|
|
346
|
+
- 说明:更新完成后会触发 `pm2 reload/restart hydrooj`,短时间内可能导致连接中断。
|
|
347
|
+
- 解决:等待 15–20 秒刷新页面;必要时查看 `pm2 logs hydrooj`。
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
320
351
|
## 常见问题汇总
|
|
321
352
|
|
|
322
353
|
| 问题 | 原因 | 解决方案 |
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
2
|
+
|
|
3
|
+
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
|
|
62
|
+
=ElGs
|
|
63
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
|
@@ -55,6 +55,11 @@ exports.UpdateInfoHandlerPriv = hydrooj_1.PRIV.PRIV_EDIT_SYSTEM;
|
|
|
55
55
|
class UpdateHandler extends hydrooj_1.Handler {
|
|
56
56
|
async post() {
|
|
57
57
|
try {
|
|
58
|
+
// 🔒 强制管理员权限检查(防御路由配置被绕过)
|
|
59
|
+
if (!this.user.hasPerm(hydrooj_1.PRIV.PRIV_EDIT_SYSTEM)) {
|
|
60
|
+
console.warn(`[UpdateHandler] 权限不足: 用户 ${this.user._id} 尝试执行更新操作`);
|
|
61
|
+
return (0, httpHelpers_1.setErrorResponse)(this, 'PERMISSION_DENIED', '执行插件更新需要管理员权限。更新操作会修改代码并重启服务,仅允许管理员执行。', 403);
|
|
62
|
+
}
|
|
58
63
|
const updateService = new updateService_1.UpdateService();
|
|
59
64
|
// 收集所有日志
|
|
60
65
|
const allLogs = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateHandler.js","sourceRoot":"","sources":["../../src/handlers/updateHandler.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,qCAAwC;AACxC,6DAA0D;AAC1D,oDAAuE;AAEvE;;;;;;;;;;GAUG;AACH,MAAa,iBAAkB,SAAQ,iBAAO;IAC5C,KAAK,CAAC,GAAG;QACP,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,aAAa,CAAC,aAAa,EAAE,CAAC;YAE3C,IAAA,6BAAe,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;YACjD,IAAA,8BAAgB,EAAC,IAAI,EAAE,oBAAoB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;CACF;AAZD,8CAYC;AAED,uBAAuB;AACV,QAAA,qBAAqB,GAAG,cAAI,CAAC,gBAAgB,CAAC;AAE3D;;;;;;;;;;;;;GAaG;AACH,MAAa,aAAc,SAAQ,iBAAO;IACxC,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;YAE1C,SAAS;YACT,MAAM,OAAO,GAAa,EAAE,CAAC;YAE7B,OAAO;YACP,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;gBAC7D,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,IAAA,6BAAe,EAAC,IAAI,EAAE;gBACpB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YAC7C,IAAA,8BAAgB,EAAC,IAAI,EAAE,eAAe,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"updateHandler.js","sourceRoot":"","sources":["../../src/handlers/updateHandler.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,qCAAwC;AACxC,6DAA0D;AAC1D,oDAAuE;AAEvE;;;;;;;;;;GAUG;AACH,MAAa,iBAAkB,SAAQ,iBAAO;IAC5C,KAAK,CAAC,GAAG;QACP,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,aAAa,CAAC,aAAa,EAAE,CAAC;YAE3C,IAAA,6BAAe,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;YACjD,IAAA,8BAAgB,EAAC,IAAI,EAAE,oBAAoB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;CACF;AAZD,8CAYC;AAED,uBAAuB;AACV,QAAA,qBAAqB,GAAG,cAAI,CAAC,gBAAgB,CAAC;AAE3D;;;;;;;;;;;;;GAaG;AACH,MAAa,aAAc,SAAQ,iBAAO;IACxC,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,0BAA0B;YAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC9C,OAAO,CAAC,IAAI,CAAC,4BAA4B,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;gBACnE,OAAO,IAAA,8BAAgB,EACrB,IAAI,EACJ,mBAAmB,EACnB,wCAAwC,EACxC,GAAG,CACJ,CAAC;YACJ,CAAC;YAED,MAAM,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;YAE1C,SAAS;YACT,MAAM,OAAO,GAAa,EAAE,CAAC;YAE7B,OAAO;YACP,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;gBAC7D,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,IAAA,6BAAe,EAAC,IAAI,EAAE;gBACpB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YAC7C,IAAA,8BAAgB,EAAC,IAAI,EAAE,eAAe,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;CACF;AAtCD,sCAsCC;AAED,uBAAuB;AACV,QAAA,iBAAiB,GAAG,cAAI,CAAC,gBAAgB,CAAC"}
|