release-it-gitea 1.3.2 → 1.4.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/README.md CHANGED
@@ -1,16 +1,15 @@
1
- # release-it-gitea
1
+ # Release It! Gitea Plugin
2
2
 
3
- 一个用于 [release-it](https://github.com/release-it/release-it) 的 Gitea 插件,可以在生成版本和 changelog 后自动将它们推送到指定的 Gitea 服务器的仓库发布中。
3
+ 一个用于 [release-it](https://github.com/release-it/release-it) 的 Gitea 插件,支持自动创建 Gitea 发布并上传附件。
4
4
 
5
5
  ## 功能特性
6
6
 
7
- - ✅ 自动创建 Gitea 发布
8
- - ✅ 支持自定义发布标题和说明
9
- - ✅ 支持预发布和草稿发布
10
- - ✅ 支持模板变量替换
11
- - ✅ 自动检测并更新已存在的发布
12
- - ✅ 完整的错误处理和日志记录
13
- - ✅ TypeScript 支持
7
+ - ✅ 自动创建和更新 Gitea 发布
8
+ - ✅ 支持模板变量替换(版本号、变更日志等)
9
+ - ✅ 支持草稿和预发布版本
10
+ - ✅ **新功能:支持文件和文件夹附件上传**
11
+ - ✅ **新功能:支持自动打包文件夹为 ZIP**
12
+ - ✅ **新功能:支持通配符文件匹配**
14
13
 
15
14
  ## 安装
16
15
 
@@ -47,7 +46,8 @@ export GITEA_TOKEN="your-gitea-api-token"
47
46
  "releaseTitle": "v${version}",
48
47
  "releaseNotes": "${changelog}",
49
48
  "prerelease": false,
50
- "draft": false
49
+ "draft": false,
50
+ "tokenRef": "GITEA_TOKEN"
51
51
  }
52
52
  }
53
53
  }
@@ -72,95 +72,226 @@ export GITEA_TOKEN="your-gitea-api-token"
72
72
 
73
73
  ## 配置选项
74
74
 
75
- | 选项 | 类型 | 默认值 | 描述 |
76
- | -------------- | --------- | ---------------------- | -------------------- |
77
- | `host` | `string` | **必需** | Gitea 服务器 URL |
78
- | `owner` | `string` | 从 git remote 自动检测 | 仓库所有者 |
79
- | `repository` | `string` | 从 git remote 自动检测 | 仓库名称 |
80
- | `release` | `boolean` | `true` | 是否创建发布 |
81
- | `releaseTitle` | `string` | `"v${version}"` | 发布标题模板 |
82
- | `releaseNotes` | `string` | `"${changelog}"` | 发布说明模板 |
83
- | `prerelease` | `boolean` | `false` | 是否为预发布 |
84
- | `draft` | `boolean` | `false` | 是否为草稿 |
85
- | `tokenRef` | `string` | `"GITEA_TOKEN"` | API token 环境变量名 |
86
- | `timeout` | `number` | `30000` | 请求超时时间(毫秒) |
87
-
88
- ## 模板变量
89
-
90
- 在 `releaseTitle` 和 `releaseNotes` 中可以使用以下模板变量:
91
-
92
- - `${version}` - 当前版本号
93
- - `${latestVersion}` - 上一个版本号
94
- - `${changelog}` - 生成的 changelog
95
- - `${name}` - 项目名称
96
- - `${repo.owner}` - 仓库所有者
97
- - `${repo.repository}` - 仓库名称
98
- - `${branchName}` - 当前分支名
75
+ | 选项 | 类型 | 默认值 | 描述 |
76
+ | -------------- | ---------------------- | ---------------------- | -------------------- |
77
+ | `host` | `string` | 当前仓库的 host | Gitea 服务器 URL |
78
+ | `owner` | `string` | 从 git remote 自动检测 | 仓库所有者 |
79
+ | `repository` | `string` | 从 git remote 自动检测 | 仓库名称 |
80
+ | `release` | `boolean` | `true` | 是否创建发布 |
81
+ | `releaseTitle` | `string` | `"v${version}"` | 发布标题模板 |
82
+ | `releaseNotes` | `string` | `"${changelog}"` | 发布说明模板 |
83
+ | `prerelease` | `boolean` | `false` | 是否为预发布 |
84
+ | `draft` | `boolean` | `false` | 是否为草稿 |
85
+ | `tokenRef` | `string` | `"GITEA_TOKEN"` | API token 环境变量名 |
86
+ | `timeout` | `number` | `30000` | 请求超时时间(毫秒) |
87
+ | `assets` | `(string \| object)[]` | `` | 附加的资源文件 |
99
88
 
100
- ## 使用示例
89
+ ## 附件上传配置
101
90
 
102
- ### 基础配置
91
+ ### 基本附件配置
103
92
 
104
93
  ```json
105
94
  {
106
95
  "plugins": {
107
96
  "release-it-gitea": {
108
- "host": "https://gitea.example.com"
97
+ "host": "https://gitea.example.com",
98
+ "owner": "your-username",
99
+ "repository": "your-repo",
100
+ "assets": ["dist/app.js", "README.md", "dist/**/*.min.js"]
109
101
  }
110
102
  }
111
103
  }
112
104
  ```
113
105
 
114
- ### 完整配置
106
+ ### 高级附件配置
115
107
 
116
108
  ```json
117
109
  {
118
110
  "plugins": {
119
111
  "release-it-gitea": {
120
112
  "host": "https://gitea.example.com",
121
- "owner": "myorg",
122
- "repository": "myproject",
123
- "release": true,
124
- "releaseTitle": "Release ${version}",
125
- "releaseNotes": "## 更新内容\n\n${changelog}\n\n---\n\n完整更新日志请查看 [CHANGELOG.md](./CHANGELOG.md)",
126
- "prerelease": false,
127
- "draft": false,
128
- "tokenRef": "GITEA_TOKEN",
129
- "timeout": 30000
113
+ "owner": "your-username",
114
+ "repository": "your-repo",
115
+ "assets": [
116
+ {
117
+ "path": "dist/**/*",
118
+ "name": "distribution-files.zip",
119
+ "type": "zip",
120
+ "label": "Distribution Files"
121
+ },
122
+ {
123
+ "path": "docs/*.md",
124
+ "type": "file",
125
+ "label": "Documentation"
126
+ },
127
+ {
128
+ "path": "src",
129
+ "name": "source-code.zip",
130
+ "type": "zip",
131
+ "label": "Source Code"
132
+ }
133
+ ]
130
134
  }
131
135
  }
132
136
  }
133
137
  ```
134
138
 
135
- ### 预发布配置
139
+ ## 附件配置选项
140
+
141
+ ### 字符串格式
142
+
143
+ 直接指定文件路径,支持通配符:
144
+
145
+ ```json
146
+ "assets": [
147
+ "dist/app.js",
148
+ "build/**/*.min.js",
149
+ "*.md"
150
+ ]
151
+ ```
152
+
153
+ ### 对象格式
154
+
155
+ 更详细的配置选项:
156
+
157
+ | 属性 | 类型 | 必需 | 描述 |
158
+ | ------- | --------------- | ---- | ------------------------------------ |
159
+ | `path` | string | ✅ | 文件或文件夹路径,支持通配符 |
160
+ | `name` | string | ❌ | 上传后的文件名,不指定则使用原文件名 |
161
+ | `type` | 'file' \| 'zip' | ❌ | 文件类型,默认为 'file' |
162
+ | `label` | string | ❌ | 文件标签,用于标识文件用途 |
163
+
164
+ ### 文件类型说明
165
+
166
+ - **`file`**: 直接上传匹配到的文件
167
+ - **`zip`**: 将匹配到的文件打包成 ZIP 文件后上传
168
+
169
+ ## 使用示例
170
+
171
+ ### 示例 1:上传构建产物
136
172
 
137
173
  ```json
138
174
  {
139
- "plugins": {
140
- "release-it-gitea": {
141
- "host": "https://gitea.example.com",
142
- "releaseTitle": "v${version} (预发布)",
143
- "prerelease": true
175
+ "assets": ["dist/bundle.js", "dist/bundle.css", "dist/assets/**/*"]
176
+ }
177
+ ```
178
+
179
+ ### 示例 2:打包源代码
180
+
181
+ ```json
182
+ {
183
+ "assets": [
184
+ {
185
+ "path": "src/**/*",
186
+ "name": "source-v${version}.zip",
187
+ "type": "zip",
188
+ "label": "Source Code"
144
189
  }
145
- }
190
+ ]
146
191
  }
147
192
  ```
148
193
 
149
- ## 工作流程
194
+ ### 示例 3:多种文件类型
150
195
 
151
- 1. **初始化阶段** - 验证配置和 API 连接
152
- 2. **发布阶段** - 创建或更新 Gitea 发布
153
- 3. **发布后阶段** - 显示发布链接
196
+ ```json
197
+ {
198
+ "assets": [
199
+ "README.md",
200
+ "CHANGELOG.md",
201
+ {
202
+ "path": "dist",
203
+ "name": "build-output.zip",
204
+ "type": "zip"
205
+ },
206
+ {
207
+ "path": "docs/**/*.pdf",
208
+ "type": "file",
209
+ "label": "Documentation"
210
+ }
211
+ ]
212
+ }
213
+ ```
214
+
215
+ ## 完整配置选项
216
+
217
+ | 选项 | 类型 | 默认值 | 描述 |
218
+ | -------------- | ------- | ---------------- | -------------------- |
219
+ | `host` | string | - | Gitea 服务器地址 |
220
+ | `owner` | string | - | 仓库所有者 |
221
+ | `repository` | string | - | 仓库名称 |
222
+ | `release` | boolean | `true` | 是否启用发布功能 |
223
+ | `releaseTitle` | string | `"v${version}"` | 发布标题模板 |
224
+ | `releaseNotes` | string | `"${changelog}"` | 发布说明模板 |
225
+ | `prerelease` | boolean | `false` | 是否为预发布版本 |
226
+ | `draft` | boolean | `false` | 是否创建为草稿 |
227
+ | `tokenRef` | string | `"GITEA_TOKEN"` | API Token 环境变量名 |
228
+ | `timeout` | number | `30000` | 请求超时时间(毫秒) |
229
+ | `assets` | array | `[]` | 附件配置列表 |
230
+
231
+ ## 环境变量
232
+
233
+ 设置 Gitea API Token:
234
+
235
+ ```bash
236
+ export GITEA_TOKEN=your_gitea_api_token
237
+ ```
238
+
239
+ 或者使用自定义环境变量名:
240
+
241
+ ```json
242
+ {
243
+ "tokenRef": "MY_GITEA_TOKEN"
244
+ }
245
+ ```
154
246
 
155
- ## 错误处理
247
+ ```bash
248
+ export MY_GITEA_TOKEN=your_gitea_api_token
249
+ ```
250
+
251
+ ## 模板变量
252
+
253
+ 在 `releaseTitle` 和 `releaseNotes` 中可以使用以下变量:
254
+
255
+ - `${version}`: 当前版本号
256
+ - `${latestVersion}`: 上一个版本号
257
+ - `${changelog}`: 变更日志
258
+ - `${name}`: 项目名称
259
+ - `${repo.owner}`: 仓库所有者
260
+ - `${repo.repository}`: 仓库名称
261
+ - `${branchName}`: 分支名称
262
+
263
+ ## 故障排除
264
+
265
+ ### 常见问题
266
+
267
+ 1. **附件上传失败**
156
268
 
157
- 插件包含完整的错误处理:
269
+ - 检查文件路径是否正确
270
+ - 确保文件存在且可读
271
+ - 检查 Gitea API Token 权限
158
272
 
159
- - 配置验证
160
- - API token 验证
161
- - 网络连接检查
162
- - API 请求错误处理
163
- - 详细的错误日志
273
+ 2. **ZIP 文件创建失败**
274
+
275
+ - 确保有足够的磁盘空间
276
+ - 检查临时目录权限
277
+
278
+ 3. **通配符匹配无文件**
279
+
280
+ - 验证通配符模式是否正确
281
+ - 检查当前工作目录
282
+
283
+ 4. **API 请求失败**
284
+ - 检查 Gitea 服务器地址是否正确
285
+ - 验证 API Token 是否有效
286
+ - 确认仓库所有者和名称正确
287
+
288
+ ### 调试模式
289
+
290
+ 使用 `--verbose` 参数查看详细日志:
291
+
292
+ ```bash
293
+ npx release-it --verbose
294
+ ```
164
295
 
165
296
  ## 开发
166
297
 
package/lib/global.d.d.ts CHANGED
@@ -54,6 +54,21 @@ declare module "release-it" {
54
54
  }
55
55
  }
56
56
 
57
+ /** 附件配置接口 */
58
+ interface GiteaAssetConfig {
59
+ /** 文件或文件夹路径,支持通配符 */
60
+ path: string;
61
+
62
+ /** 上传后的文件名,如果不指定则使用原文件名 */
63
+ name?: string;
64
+
65
+ /** 文件类型:'file' 表示单个文件,'zip' 表示打包成 zip 文件 */
66
+ type?: "file" | "zip";
67
+
68
+ /** 文件标签,用于标识文件用途 */
69
+ label?: string;
70
+ }
71
+
57
72
  interface GiteaConfig {
58
73
  /** Gitea 服务器的完整 URL 地址 */
59
74
  host: string;
@@ -84,4 +99,7 @@ interface GiteaConfig {
84
99
 
85
100
  /** API 请求的超时时间,单位为毫秒 */
86
101
  timeout?: number;
102
+
103
+ /** 要上传的附件列表 */
104
+ assets?: (GiteaAssetConfig | string)[];
87
105
  }
package/lib/index.d.ts CHANGED
@@ -58,6 +58,46 @@ declare class GiteaPlugin extends Plugin {
58
58
  * @returns 替换变量后的字符串
59
59
  */
60
60
  private interpolate;
61
+ /**
62
+ * 解析附件配置,将字符串格式转换为标准配置对象
63
+ * @param asset 附件配置
64
+ * @returns 标准化的附件配置对象
65
+ */
66
+ private normalizeAssetConfig;
67
+ /**
68
+ * 根据路径模式匹配文件
69
+ * @param pattern 文件路径模式,支持通配符
70
+ * @returns 匹配到的文件路径数组
71
+ */
72
+ private resolveFiles;
73
+ /**
74
+ * 创建 ZIP 压缩包
75
+ * @param files 要压缩的文件列表
76
+ * @param outputPath 输出的 ZIP 文件路径
77
+ * @param basePath 基础路径,用于确定文件在压缩包中的相对路径
78
+ * @returns Promise<void>
79
+ */
80
+ private createZipArchive;
81
+ /**
82
+ * 上传单个附件到 Gitea 发布
83
+ * @param releaseId 发布 ID
84
+ * @param filePath 文件路径
85
+ * @param fileName 上传后的文件名
86
+ * @param label 文件标签
87
+ * @returns 上传结果
88
+ */
89
+ private uploadAsset;
90
+ /**
91
+ * 处理并上传所有配置的附件
92
+ * @param releaseId 发布 ID
93
+ */
94
+ private uploadAssets;
95
+ /**
96
+ * 处理单个附件配置
97
+ * @param releaseId 发布 ID
98
+ * @param config 附件配置
99
+ */
100
+ private processAsset;
61
101
  /**
62
102
  * 执行发布操作,创建或更新 Gitea 发布.
63
103
  * @throws 当发布创建失败时抛出错误
package/lib/index.js CHANGED
@@ -1,4 +1,9 @@
1
+ import archiver from "archiver";
2
+ import FormData from "form-data";
3
+ import { createReadStream, createWriteStream, statSync } from "fs";
4
+ import { glob } from "glob";
1
5
  import fetch from "node-fetch";
6
+ import { basename, dirname, join } from "path";
2
7
  import { Plugin } from "release-it";
3
8
  class GiteaPlugin extends Plugin {
4
9
  static isEnabled(config) {
@@ -17,13 +22,13 @@ class GiteaPlugin extends Plugin {
17
22
  const repo = this.config.getContext("repo");
18
23
  const config = {
19
24
  draft: gitea.draft ?? false,
20
- host: gitea.host,
25
+ host: gitea.host ?? repo.host,
21
26
  owner: gitea.owner ?? repo.owner,
22
27
  prerelease: gitea.prerelease ?? false,
23
28
  release: gitea.release !== false,
24
29
  releaseNotes: gitea.releaseNotes ?? "${changelog}",
25
30
  releaseTitle: gitea.releaseTitle ?? "v${version}",
26
- repository: gitea.repository ?? repo.repository,
31
+ repository: gitea.repository ?? repo.project,
27
32
  timeout: gitea.timeout ?? 3e4,
28
33
  tokenRef: gitea.tokenRef ?? "GITEA_TOKEN"
29
34
  };
@@ -60,7 +65,10 @@ class GiteaPlugin extends Plugin {
60
65
  * @returns 完整的 API URL
61
66
  */
62
67
  buildApiUrl(endpoint) {
63
- const host = this.giteaConfig.host.replace(/\/$/, "");
68
+ let host = this.giteaConfig.host.replace(/\/$/, "");
69
+ if (!host.startsWith("http")) {
70
+ host = `https://${host}`;
71
+ }
64
72
  return `${host}/api/v1${endpoint}`;
65
73
  }
66
74
  /**
@@ -159,6 +167,177 @@ class GiteaPlugin extends Plugin {
159
167
  const context = this.config.getContext();
160
168
  return template.replace(/\$\{version\}/g, context.version).replace(/\$\{latestVersion\}/g, context.latestVersion).replace(/\$\{changelog\}/g, context.changelog).replace(/\$\{name\}/g, context.name).replace(/\$\{repo\.owner\}/g, context.repo.owner).replace(/\$\{repo\.repository\}/g, context.repo.repository).replace(/\$\{branchName\}/g, context.branchName);
161
169
  }
170
+ /**
171
+ * 解析附件配置,将字符串格式转换为标准配置对象
172
+ * @param asset 附件配置
173
+ * @returns 标准化的附件配置对象
174
+ */
175
+ normalizeAssetConfig(asset) {
176
+ if (typeof asset === "string") {
177
+ return {
178
+ path: asset,
179
+ type: "file"
180
+ };
181
+ }
182
+ return {
183
+ type: "file",
184
+ ...asset
185
+ };
186
+ }
187
+ /**
188
+ * 根据路径模式匹配文件
189
+ * @param pattern 文件路径模式,支持通配符
190
+ * @returns 匹配到的文件路径数组
191
+ */
192
+ async resolveFiles(pattern) {
193
+ try {
194
+ const files = await glob(pattern, {
195
+ absolute: true,
196
+ nodir: true
197
+ });
198
+ return files;
199
+ } catch (error) {
200
+ this.log.warn(`\u6587\u4EF6\u5339\u914D\u5931\u8D25: ${pattern}, \u9519\u8BEF: ${error}`);
201
+ return [];
202
+ }
203
+ }
204
+ /**
205
+ * 创建 ZIP 压缩包
206
+ * @param files 要压缩的文件列表
207
+ * @param outputPath 输出的 ZIP 文件路径
208
+ * @param basePath 基础路径,用于确定文件在压缩包中的相对路径
209
+ * @returns Promise<void>
210
+ */
211
+ async createZipArchive(files, outputPath, basePath) {
212
+ return new Promise((resolve, reject) => {
213
+ const output = createWriteStream(outputPath);
214
+ const archive = archiver("zip", {
215
+ zlib: { level: 9 }
216
+ });
217
+ output.on("close", () => {
218
+ this.log.verbose(
219
+ `ZIP \u6587\u4EF6\u521B\u5EFA\u5B8C\u6210: ${outputPath} (${archive.pointer()} bytes)`
220
+ );
221
+ resolve();
222
+ });
223
+ archive.on("error", (err) => {
224
+ reject(err);
225
+ });
226
+ archive.pipe(output);
227
+ for (const file of files) {
228
+ const stats = statSync(file);
229
+ if (stats.isFile()) {
230
+ const relativePath = basePath ? file.replace(basePath, "").replace(/^\//, "") : basename(file);
231
+ archive.file(file, { name: relativePath });
232
+ }
233
+ }
234
+ archive.finalize();
235
+ });
236
+ }
237
+ /**
238
+ * 上传单个附件到 Gitea 发布
239
+ * @param releaseId 发布 ID
240
+ * @param filePath 文件路径
241
+ * @param fileName 上传后的文件名
242
+ * @param label 文件标签
243
+ * @returns 上传结果
244
+ */
245
+ async uploadAsset(releaseId, filePath, fileName, label) {
246
+ const url = this.buildApiUrl(
247
+ `/repos/${this.giteaConfig.owner}/${this.giteaConfig.repository}/releases/${releaseId}/assets`
248
+ );
249
+ const token = this.getToken();
250
+ const form = new FormData();
251
+ form.append("attachment", createReadStream(filePath), {
252
+ contentType: "application/octet-stream",
253
+ filename: fileName
254
+ });
255
+ if (label) {
256
+ form.append("name", label);
257
+ }
258
+ const requestOptions = {
259
+ body: form,
260
+ headers: {
261
+ ...form.getHeaders(),
262
+ Authorization: `token ${token}`
263
+ },
264
+ method: "POST",
265
+ timeout: this.giteaConfig.timeout
266
+ };
267
+ this.log.verbose(`\u4E0A\u4F20\u9644\u4EF6: ${fileName} \u5230\u53D1\u5E03 ${releaseId}`);
268
+ try {
269
+ const response = await fetch(url, requestOptions);
270
+ if (!response.ok) {
271
+ const errorText = await response.text();
272
+ throw new Error(`\u9644\u4EF6\u4E0A\u4F20\u5931\u8D25 (${response.status}): ${errorText}`);
273
+ }
274
+ const result = await response.json();
275
+ this.log.info(`\u2705 \u9644\u4EF6\u4E0A\u4F20\u6210\u529F: ${fileName}`);
276
+ return result;
277
+ } catch (error) {
278
+ if (error instanceof Error) {
279
+ throw new Error(`\u9644\u4EF6\u4E0A\u4F20\u5931\u8D25: ${error.message}`);
280
+ }
281
+ throw error;
282
+ }
283
+ }
284
+ /**
285
+ * 处理并上传所有配置的附件
286
+ * @param releaseId 发布 ID
287
+ */
288
+ async uploadAssets(releaseId) {
289
+ const assets = this.giteaConfig.assets;
290
+ if (!assets || assets.length === 0) {
291
+ this.log.verbose("\u6CA1\u6709\u914D\u7F6E\u9644\u4EF6\uFF0C\u8DF3\u8FC7\u4E0A\u4F20");
292
+ return;
293
+ }
294
+ this.log.info(`\u5F00\u59CB\u4E0A\u4F20 ${assets.length} \u4E2A\u9644\u4EF6...`);
295
+ for (const asset of assets) {
296
+ try {
297
+ const config = this.normalizeAssetConfig(asset);
298
+ await this.processAsset(releaseId, config);
299
+ } catch (error) {
300
+ this.log.error(
301
+ `\u9644\u4EF6\u5904\u7406\u5931\u8D25: ${JSON.stringify(asset)}, \u9519\u8BEF: ${error}`
302
+ );
303
+ }
304
+ }
305
+ this.log.info("\u2705 \u6240\u6709\u9644\u4EF6\u5904\u7406\u5B8C\u6210");
306
+ }
307
+ /**
308
+ * 处理单个附件配置
309
+ * @param releaseId 发布 ID
310
+ * @param config 附件配置
311
+ */
312
+ async processAsset(releaseId, config) {
313
+ const files = await this.resolveFiles(config.path);
314
+ if (files.length === 0) {
315
+ this.log.warn(`\u6CA1\u6709\u627E\u5230\u5339\u914D\u7684\u6587\u4EF6: ${config.path}`);
316
+ return;
317
+ }
318
+ if (config.type === "zip") {
319
+ const zipName = config.name || `${basename(config.path)}.zip`;
320
+ const tempZipPath = join(process.cwd(), ".temp", zipName);
321
+ const { mkdirSync } = await import("fs");
322
+ try {
323
+ mkdirSync(dirname(tempZipPath), { recursive: true });
324
+ } catch (error) {
325
+ }
326
+ await this.createZipArchive(files, tempZipPath, dirname(config.path));
327
+ await this.uploadAsset(releaseId, tempZipPath, zipName, config.label);
328
+ const { unlinkSync } = await import("fs");
329
+ try {
330
+ unlinkSync(tempZipPath);
331
+ } catch (error) {
332
+ this.log.warn(`\u6E05\u7406\u4E34\u65F6\u6587\u4EF6\u5931\u8D25: ${tempZipPath}`);
333
+ }
334
+ } else {
335
+ for (const file of files) {
336
+ const fileName = config.name || basename(file);
337
+ await this.uploadAsset(releaseId, file, fileName, config.label);
338
+ }
339
+ }
340
+ }
162
341
  /**
163
342
  * 执行发布操作,创建或更新 Gitea 发布.
164
343
  * @throws 当发布创建失败时抛出错误
@@ -194,6 +373,9 @@ class GiteaPlugin extends Plugin {
194
373
  release = await this.createRelease(releaseData);
195
374
  }
196
375
  this.log.info(`\u2705 Gitea \u53D1\u5E03\u521B\u5EFA\u6210\u529F: ${release.html_url}`);
376
+ if (this.giteaConfig.assets && this.giteaConfig.assets.length > 0) {
377
+ await this.uploadAssets(release.id);
378
+ }
197
379
  this.config.setContext("releaseUrl", release.html_url);
198
380
  } catch (error) {
199
381
  if (error instanceof Error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-it-gitea",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "description": "release-it gitea plugin",
5
5
  "keywords": [
6
6
  "gitea",
@@ -44,12 +44,16 @@
44
44
  "*": "prettier --ignore-unknown --write"
45
45
  },
46
46
  "dependencies": {
47
+ "archiver": "^7.0.1",
48
+ "form-data": "^4.0.3",
49
+ "glob": "^11.0.3",
47
50
  "node-fetch": "^3.3.2"
48
51
  },
49
52
  "devDependencies": {
50
53
  "@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
51
54
  "@eslint/js": "9.22.0",
52
55
  "@release-it/conventional-changelog": "10.0.0",
56
+ "@types/archiver": "^6.0.3",
53
57
  "@types/eslint-plugin-markdown": "2.0.2",
54
58
  "@types/node": "22.13.10",
55
59
  "@types/node-fetch": "^2.6.11",