@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/LICENSE +57 -0
- package/README.md +332 -298
- package/dist/cli.js +1602 -547
- package/dist/index.cjs +1524 -539
- package/dist/index.d.cts +278 -55
- package/dist/index.d.ts +278 -55
- package/dist/index.js +1504 -529
- package/package.json +44 -12
- package/dist/cli.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# App Ship
|
|
2
2
|
|
|
3
|
-
多平台应用商店上传引擎 — CLI 命令行工具 & npm
|
|
3
|
+
多平台应用商店上传引擎 — CLI 命令行工具 & npm 库,使用官方API来完成 APK / IPA / AAB / HAP 一键分发。
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@huoye/app-ship)
|
|
6
6
|
[](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
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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` |
|
|
81
|
-
| `--build-number <n>` | `-b` | 构建号(默认:"1")
|
|
82
|
-
| `--changelog <text>` |
|
|
83
|
-
| `--
|
|
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
|
-
|
|
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
|
|
146
|
+
import { UploadManager, ConfigValidator } from "@huoye/app-ship";
|
|
91
147
|
|
|
92
148
|
// 加载并验证配置
|
|
93
|
-
const config = ConfigValidator.loadAndValidate(
|
|
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(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
|
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
|
-
|
|
131
|
-
{ enable: true, apiKey:
|
|
132
|
-
{ version:
|
|
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(
|
|
137
|
-
console.log(
|
|
193
|
+
console.log(`✅ 下载地址: ${result.url}`);
|
|
194
|
+
console.log(`✅ 二维码: ${result.qrCode}`);
|
|
195
|
+
} else {
|
|
196
|
+
console.log(`❌ 失败: ${result.message}`);
|
|
138
197
|
}
|
|
139
198
|
```
|
|
140
199
|
|
|
141
|
-
|
|
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/
|
|
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
|
-
|
|
|
159
|
-
|
|
|
160
|
-
|
|
|
161
|
-
|
|
|
162
|
-
|
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
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
|
-
|
|
239
|
+
### 完整的 app-ship.yaml 配置
|
|
240
|
+
|
|
241
|
+
所有 API 地址均来自官方平台,凭证需从各平台官方后台申请。
|
|
173
242
|
|
|
174
243
|
```yaml
|
|
175
|
-
version:
|
|
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:
|
|
189
|
-
description:
|
|
257
|
+
apiKey: "${PGYER_API_KEY}"
|
|
258
|
+
description: "测试版本"
|
|
190
259
|
|
|
191
|
-
# ── 华为
|
|
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:
|
|
196
|
-
clientSecret:
|
|
197
|
-
appId:
|
|
198
|
-
releaseType: draft
|
|
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:
|
|
206
|
-
privateKey:
|
|
207
|
-
|
|
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:
|
|
215
|
-
clientSecret:
|
|
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:
|
|
222
|
-
accessSecret:
|
|
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:
|
|
229
|
-
appId:
|
|
230
|
-
accessSecret:
|
|
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:
|
|
237
|
-
clientSecret:
|
|
238
|
-
appId:
|
|
303
|
+
clientId: "${HARMONY_CLIENT_ID}"
|
|
304
|
+
clientSecret: "${HARMONY_CLIENT_SECRET}"
|
|
305
|
+
appId: "YOUR_APP_ID"
|
|
239
306
|
|
|
240
|
-
# ── App Store / TestFlight
|
|
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
|
|
310
|
+
mode: app_store
|
|
244
311
|
auth:
|
|
245
|
-
appleId:
|
|
246
|
-
appPassword:
|
|
247
|
-
|
|
248
|
-
|
|
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:
|
|
257
|
-
packageName:
|
|
258
|
-
track:
|
|
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
|
-
|
|
275
|
-
|
|
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
|
-
|
|
355
|
+
**华为**: [AppGallery Connect](https://developer.huawei.com/consumer/cn/service/josp/agc/index.html) → 我的项目 → 项目设置 → 密钥管理
|
|
356
356
|
|
|
357
|
-
|
|
357
|
+
**小米**: [小米开放平台](https://dev.mi.com/console/) → 应用管理 → 应用详情 → 上传接口
|
|
358
358
|
|
|
359
|
-
|
|
359
|
+
**OPPO/vivo/腾讯**: 对应开发者平台 → 应用管理 → API 管理
|
|
360
360
|
|
|
361
|
-
|
|
362
|
-
import { IUploader, UploadResult, AppMetadata } from '../types.js'
|
|
361
|
+
**Apple**: [App Store Connect](https://appstoreconnect.apple.com) → 用户和访问权限 → API 密钥
|
|
363
362
|
|
|
364
|
-
|
|
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
|
-
|
|
379
|
-
|
|
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
|
-
|
|
373
|
+
2. 检查以下几点:
|
|
374
|
+
- 网络连接正常
|
|
375
|
+
- 各平台服务状态正常
|
|
376
|
+
- API Key 和权限配置正确
|
|
377
|
+
- 应用包格式是否正确
|
|
400
378
|
|
|
401
|
-
|
|
379
|
+
3. 查看 [Issues](https://gitee.com/flu-cli/flu-cli/issues) 是否有类似问题
|
|
402
380
|
|
|
403
|
-
|
|
404
|
-
export * from './my_platform_uploader.js'
|
|
405
|
-
```
|
|
381
|
+
---
|
|
406
382
|
|
|
407
|
-
|
|
383
|
+
### Q: 支持 Windows / Mac 吗?
|
|
408
384
|
|
|
409
|
-
|
|
410
|
-
this.registerUploader('my_platform', new MyPlatformUploader())
|
|
411
|
-
```
|
|
385
|
+
支持!本工具是跨平台的,可在以下环境运行:
|
|
412
386
|
|
|
413
|
-
|
|
387
|
+
- Windows 10+
|
|
388
|
+
- macOS 10.15+
|
|
389
|
+
- Linux (Ubuntu 18+, Fedora, etc.)
|
|
414
390
|
|
|
415
|
-
|
|
391
|
+
---
|
|
416
392
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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
|
|
478
|
+
npm run build
|
|
459
479
|
|
|
460
480
|
# 开发模式(监听文件变化)
|
|
461
481
|
npm run dev
|
|
462
482
|
```
|
|
463
483
|
|
|
464
|
-
|
|
484
|
+
### 新增平台支持(3 步)
|
|
465
485
|
|
|
466
|
-
|
|
486
|
+
1. **实现 `IUploader` 接口**(在 `src/adapters/` 下)
|
|
487
|
+
2. **在 `src/adapters/index.ts` 导出**
|
|
488
|
+
3. **在 `src/utils/upload-manager.ts` 注册**
|
|
467
489
|
|
|
468
|
-
|
|
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
|
-
|
|
494
|
+
## 目录架构
|
|
476
495
|
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
|
|
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/
|
|
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
|
|