@huoye/app-ship 0.1.1 → 0.2.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,6 +1,6 @@
1
1
  # App Ship
2
2
 
3
- 多平台应用商店上传引擎 — CLI 命令行工具 & npm 库,支持 APK / IPA / AAB / HAP 一键分发。
3
+ 多平台应用商店上传引擎 — CLI 命令行工具 & npm 库,使用官方API来完成 APK / IPA / AAB / HAP 一键分发。
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@huoye/app-ship.svg)](https://www.npmjs.com/package/@huoye/app-ship)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@huoye/app-ship.svg)](https://www.npmjs.com/package/@huoye/app-ship)
@@ -8,48 +8,87 @@
8
8
 
9
9
  **Languages**: [English](https://gitee.com/flu-cli/flu-cli/blob/main/packages/app-ship/README_EN.md) | 简体中文
10
10
 
11
- ## 特性
11
+ ## 目录
12
12
 
13
- - **8 大平台实测通过** ✅:蒲公英、华为、小米、OPPO、vivo、腾讯应用宝、App Store、鸿蒙
14
- - **并行上传**:多平台同时上传,可配置并发数
15
- - **智能分发**:自动路由 APK → Android 商店、IPA → Apple、HAP → 鸿蒙
16
- - **指数退避重试**:网络波动自动重试,可配置退避策略
17
- - **YAML 单配置**:一个配置文件管理所有平台凭据
18
- - **三种使用方式**:CLI 命令行、npm 库、VSCode 插件
19
- - **框架无关**:Flutter、React Native、原生 Android/iOS、鸿蒙均可使用
13
+ - [⚡ 3分钟快速开始](#-3分钟快速开始)
14
+ - [特性](#特性)
15
+ - [使用指南](#使用指南)
16
+ - [支持平台](#支持平台)
17
+ - [详细配置参考](#详细配置参考)
18
+ - [常见问题](#常见问题)
19
+ - [安全与隐私](#安全与隐私)
20
+ - [开发指南](#开发指南)
21
+ - [社区与支持](#社区与支持)
20
22
 
21
- ## 安装
23
+ ---
24
+
25
+ ## ⚡ 3分钟快速开始
26
+
27
+ ### 1️⃣ 安装
22
28
 
23
29
  ```bash
24
- # 全局安装 CLI
25
30
  npm install -g @huoye/app-ship
26
-
27
- # 作为项目依赖
28
- npm install @huoye/app-ship
29
31
  ```
30
32
 
31
- ## 快速开始
33
+ ### 2️⃣ 初始化配置
32
34
 
33
35
  ```bash
34
- # 1. 安装
35
- npm install -g @huoye/app-ship
36
-
37
- # 2. 初始化配置
38
36
  app-ship init
37
+ ```
39
38
 
40
- # 3. 上传
41
- app-ship upload -c app-ship.yaml -f app.apk
39
+ 这会生成 `app-ship.yaml` 配置文件。
40
+
41
+ ### 3️⃣ 编辑配置文件
42
+
43
+ 在 `app-ship.yaml` 中填入你的平台 API Key(从各平台官方后台申请):
44
+
45
+ ```yaml
46
+ publish:
47
+ pgyer:
48
+ enable: true
49
+ apiKey: "YOUR_PGYER_API_KEY" # 替换为你的 API Key
50
+ ```
51
+
52
+ ### 4️⃣ 上传应用
53
+
54
+ ```bash
55
+ app-ship upload -c app-ship.yaml -f app-release.apk
42
56
  ```
43
57
 
44
- ## 三种使用方式
58
+ ✅ 完成!应用已上传到所有启用的平台。
45
59
 
46
- ### 1. CLI 命令行
60
+ > 💡 需要上传到特定平台?使用 `--platform` 参数:
61
+ >
62
+ > ```bash
63
+ > app-ship upload -c app-ship.yaml -f app.apk --platform pgyer,huawei
64
+ > ```
65
+
66
+ ---
67
+
68
+ ## 特性
69
+
70
+ - **8 大平台实测通过** ✅:蒲公英、华为、小米、OPPO、vivo、腾讯应用宝、App Store、鸿蒙
71
+ - **并行上传**:多平台同时上传,可配置并发数
72
+ - **智能分发**:自动路由 APK → Android 商店、IPA → Apple、HAP → 鸿蒙
73
+ - **指数退避重试**:网络波动自动重试,可配置退避策略
74
+ - **YAML 单配置**:一个配置文件管理所有平台凭据
75
+ - **三种使用方式**:CLI 命令行、npm 库、VSCode 插件
76
+ - **框架无关**:Flutter、React Native、原生 Android/iOS、鸿蒙均可使用
77
+ - **官方 API**:直接调用各平台官方 API,无第三方转接,透明开源
78
+
79
+ ---
80
+
81
+ ## 使用指南
82
+
83
+ ### 1️⃣ CLI 命令行
47
84
 
48
85
  适合 DevOps、CI/CD 流水线和命令行用户。
49
86
 
87
+ **常用命令**:
88
+
50
89
  ```bash
51
- # 初始化配置文件
52
- app-ship init
90
+ # 查看支持的平台
91
+ app-ship platforms
53
92
 
54
93
  # 上传到所有启用的平台
55
94
  app-ship upload -c app-ship.yaml -f app-release.apk
@@ -57,208 +96,238 @@ app-ship upload -c app-ship.yaml -f app-release.apk
57
96
  # 仅上传到指定平台
58
97
  app-ship upload -c app-ship.yaml -f app-release.apk --platform pgyer,huawei
59
98
 
99
+ # Google Play 必须在核对预览后显式确认,首版只进入 internal 草稿
100
+ app-ship upload -c app-ship.yaml -f app-release.aab \
101
+ --platform google_play \
102
+ --confirm-google-play
103
+
60
104
  # 带元数据上传
61
105
  app-ship upload -c app-ship.yaml -f app-release.apk \
62
106
  --version 2.0.0 \
63
107
  --build-number 42 \
64
108
  --changelog "修复了已知问题"
65
109
 
66
- # 查看支持的平台
67
- app-ship platforms
110
+ # 显示详细日志
111
+ app-ship upload -c app-ship.yaml -f app-release.apk --verbose
112
+
113
+ # 查看当前项目最近的本地发布回执;JSON 可直接交给 AI 或脚本处理
114
+ app-ship history
115
+ app-ship history --project /path/to/project --json
68
116
 
69
117
  # 查看帮助
70
118
  app-ship --help
119
+ app-ship --version
71
120
  ```
72
121
 
73
122
  **CLI 参数说明**:
74
123
 
75
- | 参数 | 简写 | 说明 |
76
- | -------------------- | ---- | ---------------------------------------------------------- |
77
- | `--config <path>` | `-c` | 配置文件路径 (YAML) |
78
- | `--file <path>` | `-f` | 安装包路径 (APK/IPA/AAB/HAP) |
79
- | `--platform <list>` | `-p` | 逗号分隔的平台列表(可选,不填则使用配置文件中启用的平台) |
80
- | `--version <ver>` | `-v` | 版本号(默认:配置文件中的值或 "1.0.0") |
81
- | `--build-number <n>` | `-b` | 构建号(默认:"1") |
82
- | `--changelog <text>` | | 更新日志 |
83
- | `--verbose` | | 显示详细输出 |
124
+ | 参数 | 简写 | 说明 |
125
+ | -------------------- | ---- | ---------------------------- |
126
+ | `--config <path>` | `-c` | 配置文件路径 (YAML) |
127
+ | `--file <path>` | `-f` | 安装包路径 (APK/IPA/AAB/HAP) |
128
+ | `--platform <list>` | `-p` | 逗号分隔的平台列表(可选) |
129
+ | `--version <ver>` | `-v` | 版本号(默认:"1.0.0") |
130
+ | `--build-number <n>` | `-b` | 构建号(默认:"1") |
131
+ | `--changelog <text>` | - | 更新日志 |
132
+ | `--confirm-google-play` | - | 确认上传 Google Play internal 草稿 |
133
+ | `--verbose` | - | 显示详细输出 |
84
134
 
85
- ### 2. npm 库(编程集成)
135
+ 上传完成后会自动在 `~/.flu-cli/release-receipts/` 保存项目隔离的结构化回执。回执只记录产物路径、大小、SHA-256、渠道状态和白名单远端标识;不会保存 Token、密钥、服务账号内容或完整平台响应。每个项目最多保留 100 条。
136
+
137
+ ---
138
+
139
+ ### 2️⃣ npm 库(编程集成)
86
140
 
87
141
  适合自建发布系统或集成到现有工作流。
88
142
 
143
+ **多平台上传**:
144
+
89
145
  ```typescript
90
- import { UploadManager, ConfigValidator } from '@huoye/app-ship'
146
+ import { UploadManager, ConfigValidator } from "@huoye/app-ship";
91
147
 
92
148
  // 加载并验证配置
93
- const config = ConfigValidator.loadAndValidate('./app-ship.yaml')
149
+ const config = ConfigValidator.loadAndValidate("./app-ship.yaml");
94
150
 
95
151
  // 创建上传管理器
96
152
  const manager = new UploadManager({
97
153
  maxConcurrent: 3, // 最大并发数
98
154
  continueOnError: true, // 部分失败后继续
99
155
  verbose: true, // 显示详细日志
100
- })
156
+ });
101
157
 
102
158
  // 执行上传
103
- const report = await manager.uploadToMultiplePlatforms('./app-release.apk', config, {
104
- version: '2.0.0',
105
- buildNumber: '42',
106
- changelog: '修复了已知问题',
107
- })
159
+ const report = await manager.uploadToMultiplePlatforms(
160
+ "./app-release.apk",
161
+ config,
162
+ {
163
+ version: "2.0.0",
164
+ buildNumber: "42",
165
+ changelog: "修复了已知问题",
166
+ },
167
+ );
108
168
 
109
169
  // 查看结果
110
- console.log(`成功: ${report.successCount}, 失败: ${report.failureCount}`)
111
- console.log(`总耗时: ${report.totalDurationMs}ms`)
112
-
113
- // 遍历每个平台的结果
170
+ console.log(`成功: ${report.successCount}, 失败: ${report.failureCount}`);
114
171
  for (const result of report.results) {
115
172
  if (result.success) {
116
- console.log(`✅ ${result.platform}: ${result.url || result.consoleUrl}`)
173
+ console.log(`✅ ${result.platform}: ${result.url || result.consoleUrl}`);
117
174
  } else {
118
- console.log(`❌ ${result.platform}: ${result.message}`)
175
+ console.log(`❌ ${result.platform}: ${result.message}`);
119
176
  }
120
177
  }
121
178
  ```
122
179
 
123
- **单平台上传示例**:
180
+ **单平台上传**:
124
181
 
125
182
  ```typescript
126
- import { PgyerUploader } from '@huoye/app-ship'
183
+ import { PgyerUploader } from "@huoye/app-ship";
127
184
 
128
- const uploader = new PgyerUploader()
185
+ const uploader = new PgyerUploader();
129
186
  const result = await uploader.upload(
130
- './app-release.apk',
131
- { enable: true, apiKey: 'YOUR_API_KEY' },
132
- { version: '1.0.0', buildNumber: '1', changelog: '首次发布' },
133
- )
187
+ "./app-release.apk",
188
+ { enable: true, apiKey: "YOUR_API_KEY" },
189
+ { version: "1.0.0", buildNumber: "1", changelog: "首次发布" },
190
+ );
134
191
 
135
192
  if (result.success) {
136
- console.log(`下载地址: ${result.url}`)
137
- console.log(`二维码: ${result.qrCode}`)
193
+ console.log(`✅ 下载地址: ${result.url}`);
194
+ console.log(`✅ 二维码: ${result.qrCode}`);
195
+ } else {
196
+ console.log(`❌ 失败: ${result.message}`);
138
197
  }
139
198
  ```
140
199
 
141
- ### 3. VSCode 插件(可视化)
200
+ ---
201
+
202
+ ### 3️⃣ VSCode 插件(可视化)
142
203
 
143
204
  安装 **Flu CLI** VSCode 插件,在 IDE 内点击操作即可完成构建和上传。
144
205
 
145
- 功能:
206
+ **功能特点**:
146
207
 
147
208
  - 实时构建 & 上传进度展示
148
209
  - 可视化配置面板
149
210
  - 自动密钥管理
150
211
  - 下载链接 + 二维码展示
151
212
 
152
- 详见 [VSCode 插件文档](https://gitee.com/flu-cli/flu-cli/tree/main/packages/vscode-extension#readme)。
213
+ 详见 [VSCode 插件文档](https://gitee.com/flu-cli/flu-cli/tree/master/packages/vscode-extension#readme)。
214
+
215
+ ---
153
216
 
154
217
  ## 支持平台
155
218
 
156
- | 平台 | 文件类型 | 认证方式 | 状态 |
157
- | -------------------- | -------- | ------------------ | --------------------- |
158
- | 蒲公英 (Pgyer) | APK, IPA | API Key | ✅ 已实测 |
159
- | 华为 (Huawei) | APK, AAB | OAuth2 | ✅ 已实测 |
160
- | 小米 (Xiaomi) | APK | RSA 公钥签名 | ✅ 已实测 |
161
- | OPPO | APK | HMAC-SHA256 | ✅ 已实测 |
162
- | vivo | APK | HMAC-SHA256 + MD5 | ✅ 已实测 |
163
- | 腾讯应用宝 (Tencent) | APK | HMAC-SHA256 | ✅ 已实测 |
164
- | App Store | IPA | Apple ID / API Key | ✅ 已实测 |
165
- | 鸿蒙 (Harmony) | HAP | OAuth2 | ✅ 已实测 |
166
- | TestFlight | IPA | Apple API Key | ⚠️ 框架就绪(开发中) |
167
- | Ad Hoc | IPA | 签名证书 | ⚠️ 框架就绪(开发中) |
168
- | Google Play | APK, AAB | Service Account | 🔄 计划中(v0.2.0) |
219
+ 本工具直接调用各平台**官方 API**,所有 API 地址和文档均为平台官方提供。
220
+
221
+ | 平台 | 文件 | 认证 | 官方 API 文档 | 状态 |
222
+ | ---------------------- | -------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
223
+ | 🐧 **蒲公英** | APK, IPA | API Key | [pgyer.com/api](https://www.pgyer.com/doc/view/api_basic) | ✅ 已实测 |
224
+ | 🟥 **华为** | APK, AAB | OAuth2 | [AppGallery Connect](https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/publish-app-0000001100974822) | ✅ 已实测 |
225
+ | 🔴 **小米** | APK | RSA 签名 | [小米开放平台](https://dev.mi.com/console/doc/detail?pId=1695) | ✅ 已实测 |
226
+ | 🟠 **OPPO** | APK | HMAC-SHA256 | [OPPO 开发者平台](https://open.oppomobile.com/wiki/doc#id=10106) | ✅ 已实测 |
227
+ | 🔵 **vivo** | APK | HMAC + MD5 | [vivo 开放平台](https://dev.vivo.com.cn/openAbility/interface) | ✅ 已实测 |
228
+ | 🐧 **腾讯应用宝** | APK | HMAC-SHA256 | [应用宝平台](https://open.qq.com/doc/?id=11016) | ✅ 已实测 |
229
+ | 🍎 **Apple App Store** | IPA | Apple ID / API | [App Store Connect API](https://developer.apple.com/app-store-connect/api/) | ✅ 已实测 |
230
+ | 🟣 **鸿蒙** | HAP | OAuth2 | [AppGallery Connect](https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/agcapi-getstarted-0000001111209402) | ✅ 已实测 |
231
+ | 🍎 **TestFlight** | IPA | Apple API | [TestFlight API](https://developer.apple.com/testflight/testers/) | ⚠️ 开发中 |
232
+ | 🍎 **Ad Hoc** | IPA | 证书 | [Apple 文档](https://developer.apple.com/documentation/xcode/distributing-your-app-for-beta-testing) | ⚠️ 开发中 |
233
+ | 🎮 **Google Play** | AAB | Service Account | [Android Publisher API](https://developers.google.com/android-publisher/api-ref/rest) | ✅ internal 草稿已实测 |
234
+
235
+ ---
169
236
 
170
- ## 完整配置参考
237
+ ## 详细配置参考
171
238
 
172
- `app-ship.yaml` 完整结构:
239
+ ### 完整的 app-ship.yaml 配置
240
+
241
+ 所有 API 地址均来自官方平台,凭证需从各平台官方后台申请。
173
242
 
174
243
  ```yaml
175
- version: '1.0.0'
244
+ version: "1.0.0"
176
245
 
177
246
  # 重试策略(可选)
178
247
  retry:
179
- maxRetries: 3 # 最大重试次数
180
- initialDelayMs: 1000 # 初始延迟 (毫秒)
181
- backoffMultiplier: 2 # 指数退避乘数
182
- maxDelayMs: 30000 # 最大延迟 (毫秒)
248
+ maxRetries: 3
249
+ initialDelayMs: 1000
250
+ backoffMultiplier: 2
251
+ maxDelayMs: 30000
183
252
 
184
253
  publish:
185
- # ── 蒲公英 ──
254
+ # ── 蒲公英 (官方 API: https://www.pgyer.com/doc/view/api_basic) ──
186
255
  pgyer:
187
256
  enable: true
188
- apiKey: '${PGYER_API_KEY}' # 支持环境变量
189
- description: '测试版本'
257
+ apiKey: "${PGYER_API_KEY}"
258
+ description: "测试版本"
190
259
 
191
- # ── 华为 AppGallery ──
260
+ # ── 华为 (官方 API: https://developer.huawei.com/consumer/cn/service/josp/agc/index.html) ──
192
261
  huawei:
193
262
  enable: false
194
263
  auth:
195
- clientId: '${HUAWEI_CLIENT_ID}'
196
- clientSecret: '${HUAWEI_CLIENT_SECRET}'
197
- appId: 'YOUR_APP_ID'
198
- releaseType: draft # draft = 仅上传 | submit = 提交审核
199
- # apiBaseUrl: '' # 可选:指定区域 API
264
+ clientId: "${HUAWEI_CLIENT_ID}"
265
+ clientSecret: "${HUAWEI_CLIENT_SECRET}"
266
+ appId: "YOUR_APP_ID"
267
+ releaseType: draft
200
268
 
201
- # ── 小米 ──
269
+ # ── 小米 (官方 API: https://dev.mi.com/console/doc/detail?pId=1695) ──
202
270
  xiaomi:
203
271
  enable: false
204
272
  auth:
205
- userName: 'your@email.com' # 开发者账号邮箱
206
- privateKey: '${XIAOMI_KEY}' # API 访问密码(非登录密码)
207
- # publicKeyPath: './rsa.cer' # 可选:RSA 公钥文件
208
- packageName: 'com.example.app'
273
+ userName: "your@email.com"
274
+ privateKey: "${XIAOMI_KEY}"
275
+ packageName: "com.example.app"
209
276
 
210
- # ── OPPO ──
277
+ # ── OPPO (官方 API: https://open.oppomobile.com/wiki/doc#id=10106) ──
211
278
  oppo:
212
279
  enable: false
213
280
  auth:
214
- clientId: '${OPPO_CLIENT_ID}'
215
- clientSecret: '${OPPO_CLIENT_SECRET}'
281
+ clientId: "${OPPO_CLIENT_ID}"
282
+ clientSecret: "${OPPO_CLIENT_SECRET}"
216
283
 
217
- # ── vivo ──
284
+ # ── vivo (官方 API: https://dev.vivo.com.cn/openAbility/interface) ──
218
285
  vivo:
219
286
  enable: false
220
287
  auth:
221
- accessKey: '${VIVO_ACCESS_KEY}'
222
- accessSecret: '${VIVO_ACCESS_SECRET}'
288
+ accessKey: "${VIVO_ACCESS_KEY}"
289
+ accessSecret: "${VIVO_ACCESS_SECRET}"
223
290
 
224
- # ── 腾讯应用宝 ──
291
+ # ── 腾讯应用宝 (官方 API: https://open.qq.com/doc/?id=11016) ──
225
292
  tencent:
226
293
  enable: false
227
294
  auth:
228
- userId: '${TENCENT_USER_ID}' # 开发者用户 ID
229
- appId: '${TENCENT_APP_ID}' # 应用 ID
230
- accessSecret: '${TENCENT_SECRET}' # 接入密钥
295
+ userId: "${TENCENT_USER_ID}"
296
+ appId: "${TENCENT_APP_ID}"
297
+ accessSecret: "${TENCENT_SECRET}"
231
298
 
232
- # ── 鸿蒙 ──
299
+ # ── 鸿蒙 (官方 API: https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/agcapi-getstarted-0000001111209402) ──
233
300
  harmony:
234
301
  enable: false
235
302
  auth:
236
- clientId: '${HARMONY_CLIENT_ID}'
237
- clientSecret: '${HARMONY_CLIENT_SECRET}'
238
- appId: 'YOUR_APP_ID'
303
+ clientId: "${HARMONY_CLIENT_ID}"
304
+ clientSecret: "${HARMONY_CLIENT_SECRET}"
305
+ appId: "YOUR_APP_ID"
239
306
 
240
- # ── App Store / TestFlight / Ad Hoc ──
307
+ # ── App Store / TestFlight (官方 API: https://developer.apple.com/app-store-connect/api/) ──
241
308
  app_store:
242
309
  enable: false
243
- mode: app_store # app_store | testflight | adhoc
310
+ mode: app_store
244
311
  auth:
245
- appleId: '${APPLE_ID}' # Apple ID 邮箱
246
- appPassword: '${APP_PASSWORD}' # App 专用密码
247
- # API Key 认证(可选,用于自动更新发行说明):
248
- # apiKeyId: ''
249
- # apiIssuerId: ''
250
- # privateKeyPath: './AuthKey.p8'
251
-
252
- # ── Google Play(计划中)──
312
+ appleId: "${APPLE_ID}"
313
+ appPassword: "${APP_PASSWORD}"
314
+
315
+ # ── Google Play(首版仅上传内部测试草稿;API 轨道标识为 internal)──
253
316
  google_play:
254
317
  enable: false
255
318
  auth:
256
- serviceAccountJsonPath: './service-account.json'
257
- packageName: 'com.example.app'
258
- track: production # internal | alpha | beta | production
319
+ serviceAccountJsonPath: "./service-account.json"
320
+ packageName: "com.example.app"
321
+ track: internal
259
322
  ```
260
323
 
261
- ### 环境变量
324
+ Google Play 连接器只从用户本机读取服务账号文件,并直接请求 Android Publisher API。
325
+ 应用需已在 Play Console 创建且包名一致;首版只接受 AAB,并固定写入 `internal` 轨道的
326
+ `draft` 发布记录,不提交审核,也不发布到测试用户或生产用户。
327
+ 如果应用从未上传过 APK/AAB,需先在 Play Console 手工上传并保存首个版本,之后才能使用
328
+ Edits API;CLI 上传还必须显式提供 `--confirm-google-play`。
329
+
330
+ ### 环境变量支持
262
331
 
263
332
  配置值支持 `${VAR_NAME}` 语法引用环境变量,避免敏感信息硬编码:
264
333
 
@@ -268,185 +337,136 @@ pgyer:
268
337
  apiKey: ${PGYER_API_KEY} # 运行时自动替换
269
338
  ```
270
339
 
271
- ## 目录架构
340
+ 在 CI/CD 中设置环境变量即可:
272
341
 
273
- ```
274
- packages/app-ship/
275
- ├── src/
276
- │ ├── index.ts # 📦 库入口 — 导出所有公共 API
277
- │ ├── cli.ts # 🖥️ CLI 入口 — 命令行工具主程序
278
- │ ├── types.ts # 📐 类型定义 — 所有接口和类型
279
- │ ├── adapters/ # 🔌 上传适配器层
280
- │ │ ├── index.ts # 适配器统一导出
281
- │ │ ├── pgyer_uploader.ts # 蒲公英 — API Key 认证
282
- │ │ ├── huawei_uploader.ts # 华为 — OAuth2 三步上传
283
- │ │ ├── xiaomi_uploader.ts # 小米 — RSA 1024 分段加密
284
- │ │ ├── oppo_uploader.ts # OPPO — HMAC-SHA256 签名
285
- │ │ ├── vivo_uploader.ts # vivo — HMAC-SHA256 + MD5
286
- │ │ ├── tencent_uploader.ts # 腾讯应用宝 — COS 直传
287
- │ │ ├── apple_store_uploader.ts # App Store — Transporter/altool
288
- │ │ ├── harmony_uploader.ts # 鸿蒙 — 复用华为 AGC API
289
- │ │ ├── testflight_uploader.ts # TestFlight — 半成品
290
- │ │ └── adhoc_uploader.ts # Ad Hoc — 半成品
291
- │ ├── utils/ # 🔧 工具层
292
- │ │ ├── index.ts # 工具统一导出
293
- │ │ ├── upload-manager.ts # 上传管理器 — 并发调度 + 智能分发
294
- │ │ ├── retry-strategy.ts # 重试策略 — 指数退避 + 错误分类
295
- │ │ ├── apple-jwt-generator.ts # Apple JWT — ES256 签名生成
296
- │ │ ├── package-parser.ts # 包解析器 — APK/AAB 信息提取
297
- │ │ └── logger.ts # 日志工具 — 仅内部使用,不对外导出
298
- │ └── validators/ # ✅ 验证层
299
- │ ├── index.ts # 验证器统一导出
300
- │ ├── config_validator.ts # 配置验证 — YAML 加载 + Schema 校验
301
- │ └── env_validator.ts # 环境变量验证
302
- ├── dist/ # 构建产物
303
- ├── package.json
304
- ├── tsconfig.json
305
- └── tsup.config.ts
342
+ ```bash
343
+ export PGYER_API_KEY="your-actual-key"
344
+ app-ship upload -c app-ship.yaml -f app.apk
306
345
  ```
307
346
 
308
- ### 分层架构图
347
+ ---
309
348
 
310
- ```
311
- ┌─────────────────────────────────────────────────────┐
312
- │ 用户界面层 │
313
- ├───────────┬──────────────────┬───────────────────────┤
314
- │ CLI │ VSCode 插件 │ npm 库集成 │
315
- │ (cli.ts) │ (另一个包) │ (index.ts) │
316
- └─────┬─────┴────────┬─────────┴──────────┬────────────┘
317
- │ │ │
318
- ▼ ▼ ▼
319
- ┌─────────────────────────────────────────────────────┐
320
- │ 配置管理层 │
321
- │ ConfigValidator — YAML 解析 + 环境变量替换 + 校验 │
322
- │ EnvValidator — 环境变量存在性检查 │
323
- └─────────────────────┬───────────────────────────────┘
324
- │
325
- ▼
326
- ┌─────────────────────────────────────────────────────┐
327
- │ 上传管理层 │
328
- │ UploadManager │
329
- │ ├── 适配器注册与查找 │
330
- │ ├── 并发控制 (maxConcurrent) │
331
- │ ├── 智能分发 (APK→Android, IPA→Apple, HAP→鸿蒙) │
332
- │ └── 结果聚合 → UploadReport │
333
- └─────────────────────┬───────────────────────────────┘
334
- │
335
- ▼
336
- ┌─────────────────────────────────────────────────────┐
337
- │ 平台适配器层 (IUploader) │
338
- ├────────┬────────┬────────┬────────┬────────┬────────┤
339
- │ Pgyer │ Huawei │ Xiaomi │ Apple │ Harmony│ ... │
340
- └────────┴────────┴────────┴────────┴────────┴────────┘
341
- │
342
- ▼
343
- ┌─────────────────────────────────────────────────────┐
344
- │ 基础设施层 │
345
- │ RetryStrategy — 指数退避 + 错误分类 │
346
- │ AppleJWTGenerator — ES256 JWT 签名 │
347
- │ Logger — 彩色日志输出 │
348
- └─────────────────────────────────────────────────────┘
349
- ```
349
+ ## 常见问题
350
350
 
351
- ## 自定义开发指南
351
+ ### Q: 如何获取各平台的 API Key?
352
352
 
353
- ### 新增一个平台适配器
353
+ **蒲公英**: 登录 [pgyer.com](https://www.pgyer.com) → 账号设置 → API 信息
354
354
 
355
- 只需 3 步即可添加新的上传平台:
355
+ **华为**: [AppGallery Connect](https://developer.huawei.com/consumer/cn/service/josp/agc/index.html) → 我的项目 → 项目设置 → 密钥管理
356
356
 
357
- **第 1 步:实现 `IUploader` 接口**
357
+ **小米**: [小米开放平台](https://dev.mi.com/console/) → 应用管理 → 应用详情 → 上传接口
358
358
 
359
- 在 `src/adapters/` 下创建新文件,例如 `my_platform_uploader.ts`:
359
+ **OPPO/vivo/腾讯**: 对应开发者平台 → 应用管理 → API 管理
360
360
 
361
- ```typescript
362
- import { IUploader, UploadResult, AppMetadata } from '../types.js'
361
+ **Apple**: [App Store Connect](https://appstoreconnect.apple.com) → 用户和访问权限 → API 密钥
363
362
 
364
- export class MyPlatformUploader implements IUploader {
365
- name = 'my_platform'
363
+ ---
366
364
 
367
- // 验证配置是否完整
368
- validateConfig(config: any): boolean {
369
- return config?.enable && config?.auth?.apiKey
370
- }
365
+ ### Q: 上传失败如何排查?
371
366
 
372
- // 判断是否支持该文件类型
373
- canHandle(filePath: string): boolean {
374
- return filePath.endsWith('.apk')
375
- }
367
+ 1. 使用 `--verbose` 参数查看详细日志:
376
368
 
377
- // 执行上传
378
- async upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult> {
379
- try {
380
- // ... 你的上传逻辑
381
- return {
382
- platform: this.name,
383
- success: true,
384
- message: '上传成功',
385
- url: 'https://...',
386
- }
387
- } catch (error: any) {
388
- return {
389
- platform: this.name,
390
- success: false,
391
- message: error.message || '上传失败',
392
- error,
393
- }
394
- }
395
- }
396
- }
397
- ```
369
+ ```bash
370
+ app-ship upload -c app-ship.yaml -f app.apk --verbose
371
+ ```
398
372
 
399
- **第 2 步:注册适配器**
373
+ 2. 检查以下几点:
374
+ - 网络连接正常
375
+ - 各平台服务状态正常
376
+ - API Key 和权限配置正确
377
+ - 应用包格式是否正确
400
378
 
401
- 在 `src/adapters/index.ts` 中添加导出:
379
+ 3. 查看 [Issues](https://gitee.com/flu-cli/flu-cli/issues) 是否有类似问题
402
380
 
403
- ```typescript
404
- export * from './my_platform_uploader.js'
405
- ```
381
+ ---
406
382
 
407
- 然后在 `src/utils/upload-manager.ts` 的 `registerBuiltinUploaders()` 中注册:
383
+ ### Q: 支持 Windows / Mac 吗?
408
384
 
409
- ```typescript
410
- this.registerUploader('my_platform', new MyPlatformUploader())
411
- ```
385
+ 支持!本工具是跨平台的,可在以下环境运行:
412
386
 
413
- **第 3 步:添加配置类型**
387
+ - Windows 10+
388
+ - macOS 10.15+
389
+ - Linux (Ubuntu 18+, Fedora, etc.)
414
390
 
415
- 在 `src/types.ts` 的 `UploadConfig.publish` 中添加平台配置:
391
+ ---
416
392
 
417
- ```typescript
418
- my_platform?: {
419
- enable: boolean
420
- auth: {
421
- apiKey: string
422
- }
423
- }
393
+ ### Q: 可以在 CI/CD 中使用吗?
394
+
395
+ 当然可以!使用环境变量存储凭证:
396
+
397
+ **GitHub Actions 示例**:
398
+
399
+ ```yaml
400
+ - name: Upload App
401
+ run: app-ship upload -c app-ship.yaml -f app.apk
402
+ env:
403
+ PGYER_API_KEY: ${{ secrets.PGYER_API_KEY }}
404
+ HUAWEI_CLIENT_ID: ${{ secrets.HUAWEI_CLIENT_ID }}
405
+ # ... 其他平台凭证
424
406
  ```
425
407
 
426
- 完成!新平台将自动被 `UploadManager` 管理,支持并行上传和重试。
408
+ ---
409
+
410
+ ## 安全与隐私
411
+
412
+ ### 🔐 密钥管理
413
+
414
+ - **用户掌控**:所有凭证仅保存在本地 `app-ship.yaml`,不上传到任何服务器
415
+ - **本地处理**:所有认证和签名操作都在你的机器本地执行
416
+ - **官方渠道**:直接调用各平台官方 API,无第三方转接
417
+
418
+ ### 🛡️ 最佳实践
427
419
 
428
- ### 关键接口说明
420
+ 1. **保护配置文件** - 将 `app-ship.yaml` 加入 `.gitignore`:
429
421
 
430
- | 接口 | 文件 | 用途 |
431
- | -------------- | -------- | ---------------------------------- |
432
- | `IUploader` | types.ts | 所有上传适配器必须实现的接口 |
433
- | `UploadConfig` | types.ts | YAML 配置文件的完整类型定义 |
434
- | `AppMetadata` | types.ts | 上传时附带的应用元数据 |
435
- | `UploadResult` | types.ts | 每个平台上传后的统一返回格式 |
436
- | `BuildResult` | types.ts | 构建结果(Android/iOS 构建器使用) |
422
+ ```bash
423
+ echo "app-ship.yaml" >> .gitignore
424
+ ```
437
425
 
438
- ### 文件功能速查
426
+ 2. **在 CI/CD 中使用环境变量** - 不要提交凭证到版本控制
427
+
428
+ 3. **定期轮换凭证** - 按各平台建议定期更新 API Key
429
+
430
+ 4. **权限最小化** - 为 API Key 设置尽可能细粒度的权限
431
+
432
+ ### 📜 法律声明
433
+
434
+ 使用本工具时,你同意:
435
+
436
+ - 遵守各平台的服务协议和 API 使用政策
437
+ - 合法获取并妥善保管凭证和密钥
438
+ - 自行承担因不当使用造成的一切后果
439
+
440
+ 本工具作者不对违规使用或产生的损失承担任何责任。
441
+
442
+ ---
439
443
 
440
- | 文件 | 功能 | 修改场景 |
441
- | ------------------------ | -------------- | ---------------------------- |
442
- | `types.ts` | 所有接口定义 | 新增平台配置字段、扩展返回值 |
443
- | `cli.ts` | CLI 入口 | 新增命令、修改参数 |
444
- | `upload-manager.ts` | 并行调度 | 调整并发策略、修改分发逻辑 |
445
- | `retry-strategy.ts` | 重试机制 | 调整退避参数、新增错误分类 |
446
- | `config_validator.ts` | 配置校验 | 新增平台必填项验证规则 |
447
- | `apple-jwt-generator.ts` | JWT 签名 | 仅 Apple 平台相关 |
448
- | `package-parser.ts` | APK/AAB 解析 | 扩展包信息提取 |
449
- | `adapters/*.ts` | 各平台上传逻辑 | 修复 API 变更、调整上传流程 |
444
+ ## 开发指南
445
+
446
+ ### 项目结构
447
+
448
+ ```
449
+ packages/app-ship/
450
+ ├── src/
451
+ │ ├── index.ts # 📦 库入口 — 导出所有公共 API
452
+ │ ├── cli.ts # 🖥️ CLI 入口 — 命令行工具主程序
453
+ │ ├── types.ts # 📐 类型定义 — 所有接口和类型
454
+ │ ├── adapters/ # 🔌 上传适配器层
455
+ │ │ ├── pgyer_uploader.ts
456
+ │ │ ├── huawei_uploader.ts
457
+ │ │ ├── xiaomi_uploader.ts
458
+ │ │ └── ...
459
+ │ ├── utils/ # 🔧 工具层
460
+ │ │ ├── upload-manager.ts # 并发调度 + 智能分发
461
+ │ │ ├── retry-strategy.ts # 指数退避 + 错误分类
462
+ │ │ └── ...
463
+ │ └── validators/ # ✅ 验证层
464
+ │ ├── config_validator.ts
465
+ │ └── env_validator.ts
466
+ ├── dist/
467
+ ├── package.json
468
+ └── tsconfig.json
469
+ ```
450
470
 
451
471
  ### 本地开发
452
472
 
@@ -455,44 +475,58 @@ my_platform?: {
455
475
  npm install
456
476
 
457
477
  # 构建
458
- npm run build # 等效于 tsup
478
+ npm run build
459
479
 
460
480
  # 开发模式(监听文件变化)
461
481
  npm run dev
462
482
  ```
463
483
 
464
- ## 常见问题
484
+ ### 新增平台支持(3 步)
465
485
 
466
- ### 如何获取各平台的 API Key?
486
+ 1. **实现 `IUploader` 接口**(在 `src/adapters/` 下)
487
+ 2. **在 `src/adapters/index.ts` 导出**
488
+ 3. **在 `src/utils/upload-manager.ts` 注册**
467
489
 
468
- - **蒲公英**: 登录 [pgyer.com](https://www.pgyer.com) → 账号设置 → API 信息
469
- - **华为**: [AppGallery Connect](https://developer.huawei.com/consumer/cn/service/josp/agc/index.html) → 我的项目 → 项目设置 → 密钥管理
470
- - **小米**: [小米开放平台](https://dev.mi.com/console/) → 应用管理 → 应用详情 → 上传接口
471
- - **OPPO/vivo/腾讯**: 对应开发者平台 → 应用管理 → API 管理
490
+ 详见源码注释。
472
491
 
473
- ### 配置文件支持环境变量吗?
492
+ ---
474
493
 
475
- 支持!使用 `${VAR_NAME}` 语法:
494
+ ## 目录架构
476
495
 
477
- ```yaml
478
- pgyer:
479
- apiKey: '${PGYER_API_KEY}'
496
+ ```
497
+ ┌─────────────────────────────────┐
498
+ │ 用户界面层 │
499
+ ├──────┬─────────────┬─────────────┤
500
+ │ CLI │ VSCode 插件 │ npm 库 │
501
+ └──┬───┴──────┬──────┴──────┬──────┘
502
+ │ │ │
503
+ ▼ ▼ ▼
504
+ ┌─────────────────────────────────┐
505
+ │ 配置管理 & 验证 │
506
+ └──────────────┬──────────────────┘
507
+ ▼
508
+ ┌─────────────────────────────────┐
509
+ │ 上传管理(并发、智能分发) │
510
+ └──────────────┬──────────────────┘
511
+ ▼
512
+ ┌─────────────────────────────────┐
513
+ │ 平台适配器(8+ 个平台) │
514
+ └──────────────┬──────────────────┘
515
+ ▼
516
+ ┌─────────────────────────────────┐
517
+ │ 基础设施(重试、JWT、日志) │
518
+ └─────────────────────────────────┘
480
519
  ```
481
520
 
482
- ### 上传失败如何排查?
483
-
484
- 1. 使用 `--verbose` 参数查看详细日志
485
- 2. 检查网络连接和各平台服务状态
486
- 3. 确认 API Key 和权限配置正确
487
- 4. 查看 [Issues](https://gitee.com/flu-cli/flu-cli/issues) 是否有类似问题
521
+ ---
488
522
 
489
- ## 🤝 社区
523
+ ## 社区与支持
490
524
 
491
525
  扫描下方二维码或搜索公众号**火叶**关注我们
492
526
 
493
- | 关注公众号 | 加作者微信入群 | 赞赏支持 |
494
- | :------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------: |
495
- | <img src="https://gitee.com/flu-cli/flu-cli/raw/main/packages/vscode-extension/images/qcode-wx.png" alt="微信号" width="160"/> <br> **火叶** | <img src="https://gitee.com/flu-cli/flu-cli/raw/main/packages/vscode-extension/images/wechat-group.png" alt="微信号" width="160"/> <br> **微信**: `Huoye-TT`<br>(备注: `flu-cli`) | [给作者加鸡腿 ☕️](http://huozhiye.cn/flu-cli/advanced/rewards/rewards) |
527
+ | 关注公众号 | 加作者微信入群 | 赞赏支持 |
528
+ | :--------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------: |
529
+ | <img src="https://gitee.com/flu-cli/flu-cli/raw/master/packages/vscode-extension/images/qcode-wx.jpg" alt="微信号" width="160"/> <br> **火叶** | <img src="https://gitee.com/flu-cli/flu-cli/raw/master/packages/vscode-extension/images/wechat-group.png" alt="微信号" width="160"/> <br> **微信**: `Huoye-TT`<br>(备注: `flu-cli`) | [给作者加鸡腿 ☕️](http://huozhiye.cn/flu-cli/advanced/rewards/rewards) |
496
530
 
497
531
  > 💡 你也可以点击插件详情页顶部的 **Sponsor** 按钮来支持本项目。
498
532