shipup 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.
Files changed (83) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/LICENSE +14 -0
  3. package/README.md +112 -0
  4. package/README.zh-CN.md +105 -0
  5. package/SECURITY.md +32 -0
  6. package/creds.example.yaml +62 -0
  7. package/dist/adapters/android/honor/api.js +360 -0
  8. package/dist/adapters/android/honor/api.js.map +1 -0
  9. package/dist/adapters/android/honor/index.js +122 -0
  10. package/dist/adapters/android/honor/index.js.map +1 -0
  11. package/dist/adapters/android/huawei/api.js +389 -0
  12. package/dist/adapters/android/huawei/api.js.map +1 -0
  13. package/dist/adapters/android/huawei/index.js +128 -0
  14. package/dist/adapters/android/huawei/index.js.map +1 -0
  15. package/dist/adapters/android/meizu/api.js +367 -0
  16. package/dist/adapters/android/meizu/api.js.map +1 -0
  17. package/dist/adapters/android/meizu/index.js +129 -0
  18. package/dist/adapters/android/meizu/index.js.map +1 -0
  19. package/dist/adapters/android/oppo/api.js +397 -0
  20. package/dist/adapters/android/oppo/api.js.map +1 -0
  21. package/dist/adapters/android/oppo/index.js +135 -0
  22. package/dist/adapters/android/oppo/index.js.map +1 -0
  23. package/dist/adapters/android/qq/api.js +184 -0
  24. package/dist/adapters/android/qq/api.js.map +1 -0
  25. package/dist/adapters/android/qq/index.js +80 -0
  26. package/dist/adapters/android/qq/index.js.map +1 -0
  27. package/dist/adapters/android/samsung/api.js +355 -0
  28. package/dist/adapters/android/samsung/api.js.map +1 -0
  29. package/dist/adapters/android/samsung/index.js +111 -0
  30. package/dist/adapters/android/samsung/index.js.map +1 -0
  31. package/dist/adapters/android/specs.js +106 -0
  32. package/dist/adapters/android/specs.js.map +1 -0
  33. package/dist/adapters/android/stub.js +27 -0
  34. package/dist/adapters/android/stub.js.map +1 -0
  35. package/dist/adapters/android/vivo/api.js +236 -0
  36. package/dist/adapters/android/vivo/api.js.map +1 -0
  37. package/dist/adapters/android/vivo/index.js +121 -0
  38. package/dist/adapters/android/vivo/index.js.map +1 -0
  39. package/dist/adapters/android/xiaomi/api.js +163 -0
  40. package/dist/adapters/android/xiaomi/api.js.map +1 -0
  41. package/dist/adapters/android/xiaomi/index.js +108 -0
  42. package/dist/adapters/android/xiaomi/index.js.map +1 -0
  43. package/dist/adapters/ios/appstore/asc.js +280 -0
  44. package/dist/adapters/ios/appstore/asc.js.map +1 -0
  45. package/dist/adapters/ios/appstore/index.js +323 -0
  46. package/dist/adapters/ios/appstore/index.js.map +1 -0
  47. package/dist/adapters/registry.js +34 -0
  48. package/dist/adapters/registry.js.map +1 -0
  49. package/dist/adapters/util.js +26 -0
  50. package/dist/adapters/util.js.map +1 -0
  51. package/dist/cli/index.js +479 -0
  52. package/dist/cli/index.js.map +1 -0
  53. package/dist/cli/output.js +65 -0
  54. package/dist/cli/output.js.map +1 -0
  55. package/dist/core/exit.js +20 -0
  56. package/dist/core/exit.js.map +1 -0
  57. package/dist/core/orchestrator.js +24 -0
  58. package/dist/core/orchestrator.js.map +1 -0
  59. package/dist/core/types.js +20 -0
  60. package/dist/core/types.js.map +1 -0
  61. package/dist/creds/load.js +68 -0
  62. package/dist/creds/load.js.map +1 -0
  63. package/dist/creds/schema.js +30 -0
  64. package/dist/creds/schema.js.map +1 -0
  65. package/dist/infra/crypto.js +12 -0
  66. package/dist/infra/crypto.js.map +1 -0
  67. package/dist/infra/http.js +87 -0
  68. package/dist/infra/http.js.map +1 -0
  69. package/dist/pkginfo/apk-icon.js +89 -0
  70. package/dist/pkginfo/apk-icon.js.map +1 -0
  71. package/dist/pkginfo/icon.js +83 -0
  72. package/dist/pkginfo/icon.js.map +1 -0
  73. package/dist/pkginfo/index.js +33 -0
  74. package/dist/pkginfo/index.js.map +1 -0
  75. package/docs/android-markets.md +190 -0
  76. package/docs/credentials.md +72 -0
  77. package/docs/providers.md +60 -0
  78. package/lib/common.mjs +265 -0
  79. package/lib/harmony.mjs +190 -0
  80. package/lib/huawei.mjs +153 -0
  81. package/lib/ios.mjs +477 -0
  82. package/package.json +70 -0
  83. package/shipup.mjs +160 -0
@@ -0,0 +1,479 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join, resolve } from 'node:path';
5
+ import { Command } from 'commander';
6
+ import { parse as parseYaml } from 'yaml';
7
+ import { ExitCode, UsageError, CredsError, InputError } from '../core/exit.js';
8
+ import { loadCreds, getChannelCreds } from '../creds/load.js';
9
+ import { validateChannelCreds, validateIosCreds } from '../creds/schema.js';
10
+ import { parsePackage, detectCompat32 } from '../pkginfo/index.js';
11
+ import { getAndroidAdapter, getIosAdapter } from '../adapters/registry.js';
12
+ import { runUploads } from '../core/orchestrator.js';
13
+ import { buildOutput, exitCodeFor, printOutput } from './output.js';
14
+ // 版本号从 package.json 读取,避免与 .version() 字面量不一致。
15
+ const VERSION = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf8')).version;
16
+ const DEFAULT_CREDS = join(homedir(), '.config', 'shipup', 'credentials.yaml');
17
+ function resolveCredsPath(value) {
18
+ const path = value || process.env.SHIPUP_CREDS || DEFAULT_CREDS;
19
+ if (!existsSync(path)) {
20
+ throw new CredsError('未找到凭证:请传 --creds、设置 SHIPUP_CREDS,或创建 ~/.config/shipup/credentials.yaml');
21
+ }
22
+ return path;
23
+ }
24
+ function readText(v) {
25
+ if (!v)
26
+ return undefined;
27
+ if (v.startsWith('@')) {
28
+ const p = resolve(v.slice(1));
29
+ if (!existsSync(p))
30
+ throw new InputError(`文件不存在: ${p}`);
31
+ return readFileSync(p, 'utf8');
32
+ }
33
+ return v;
34
+ }
35
+ function parseUploads(items) {
36
+ if (!items || items.length === 0)
37
+ throw new UsageError('至少需要一个 --upload 渠道=包路径');
38
+ return items.map((s) => {
39
+ const i = s.indexOf('=');
40
+ if (i <= 0)
41
+ throw new UsageError(`--upload 格式应为 渠道=路径: ${s}`);
42
+ return { channel: s.slice(0, i).trim(), path: s.slice(i + 1).trim() };
43
+ });
44
+ }
45
+ function parseTimeoutMs(opts) {
46
+ if (!['json', 'text'].includes(opts.output)) {
47
+ throw new UsageError('--output 只能是 json 或 text');
48
+ }
49
+ const seconds = Number(opts.timeout);
50
+ if (!Number.isFinite(seconds) || seconds <= 0) {
51
+ throw new UsageError('--timeout 必须是正数(秒)');
52
+ }
53
+ return seconds * 1000;
54
+ }
55
+ function parseConcurrency(value) {
56
+ const concurrency = Number(value);
57
+ if (!Number.isInteger(concurrency) || concurrency <= 0) {
58
+ throw new UsageError('--concurrency 必须是正整数');
59
+ }
60
+ return concurrency;
61
+ }
62
+ // ---------- android upload ----------
63
+ async function androidUpload(opts) {
64
+ const creds = loadCreds(resolveCredsPath(opts.creds), 'android');
65
+ const uploads = parseUploads(opts.upload);
66
+ const timeoutMs = parseTimeoutMs(opts);
67
+ const concurrency = parseConcurrency(opts.concurrency);
68
+ const releaseNote = readText(opts.releaseNote);
69
+ const iconPath = opts.icon;
70
+ if (iconPath && !existsSync(iconPath))
71
+ throw new InputError(`图标文件不存在: ${iconPath}`);
72
+ const screenshots = opts.screenshot ?? [];
73
+ for (const s of screenshots) {
74
+ if (!existsSync(s))
75
+ throw new InputError(`截图文件不存在: ${s}`);
76
+ }
77
+ const appName = opts.appName;
78
+ const summary = opts.summary;
79
+ const description = readText(opts.description);
80
+ if (!opts.submitReview) {
81
+ console.error('[shipup] 注意:Android 各渠道 upload 即提交审核/发布,无法只传不提审;--submit-review 仅作显式声明。');
82
+ }
83
+ // 单渠道预检失败(凭证缺字段 / 包文件缺失 / 渠道名错)降级为该渠道 failed 结果,不中断整批。
84
+ const tasks = [];
85
+ const preFailed = [];
86
+ for (const u of uploads) {
87
+ try {
88
+ const adapter = getAndroidAdapter(u.channel);
89
+ const chCreds = getChannelCreds(creds, u.channel);
90
+ validateChannelCreds(u.channel, chCreds);
91
+ if (!existsSync(u.path))
92
+ throw new InputError(`包文件不存在: ${u.path}`);
93
+ let packageName = creds.package_name ?? '';
94
+ let versionName = opts.versionName ?? '';
95
+ let versionCode = opts.versionCode ?? '';
96
+ if (!packageName || !versionName || !versionCode) {
97
+ const meta = await parsePackage(u.path);
98
+ packageName ||= meta.packageName;
99
+ versionName ||= meta.versionName;
100
+ versionCode ||= meta.versionCode;
101
+ }
102
+ const compat32 = detectCompat32(u.path);
103
+ const ctx = {
104
+ pkg: u.path,
105
+ packageName,
106
+ versionName,
107
+ versionCode,
108
+ releaseNote,
109
+ submitReview: !!opts.submitReview,
110
+ compat32,
111
+ iconPath,
112
+ updateIcon: !!opts.updateIcon,
113
+ screenshots,
114
+ appName,
115
+ summary,
116
+ description,
117
+ creds: chCreds,
118
+ timeoutMs,
119
+ };
120
+ tasks.push({ adapter, ctx });
121
+ }
122
+ catch (e) {
123
+ const code = e instanceof CredsError
124
+ ? 'creds'
125
+ : e instanceof InputError
126
+ ? 'input'
127
+ : e instanceof UsageError
128
+ ? 'usage'
129
+ : 'error';
130
+ preFailed.push({
131
+ channel: u.channel,
132
+ action: 'upload',
133
+ status: 'failed',
134
+ errorCode: code,
135
+ message: e instanceof Error ? e.message : String(e),
136
+ });
137
+ console.error(`[shipup] ${u.channel} 预检失败: [${code}] ${e instanceof Error ? e.message : e}`);
138
+ }
139
+ }
140
+ if (opts.dryRun) {
141
+ const dryResults = tasks.map((task) => ({
142
+ channel: task.adapter.channel,
143
+ packageName: task.ctx.packageName,
144
+ versionName: task.ctx.versionName,
145
+ versionCode: task.ctx.versionCode,
146
+ action: task.ctx.submitReview ? 'upload+submit' : 'upload',
147
+ status: 'skipped',
148
+ message: 'dry-run',
149
+ }));
150
+ const out = buildOutput('android', 'upload', [...dryResults, ...preFailed]);
151
+ printOutput(out, opts.output);
152
+ process.exit(exitCodeFor(out));
153
+ }
154
+ const results = [...(await runUploads(tasks, concurrency)), ...preFailed];
155
+ const out = buildOutput('android', 'upload', results);
156
+ printOutput(out, opts.output);
157
+ process.exit(exitCodeFor(out));
158
+ }
159
+ // ---------- android status ----------
160
+ async function androidStatus(opts) {
161
+ const timeoutMs = parseTimeoutMs(opts);
162
+ const creds = loadCreds(resolveCredsPath(opts.creds), 'android');
163
+ const adapter = getAndroidAdapter(opts.channel);
164
+ const chCreds = getChannelCreds(creds, opts.channel);
165
+ validateChannelCreds(opts.channel, chCreds);
166
+ if (opts.dryRun) {
167
+ const out = buildOutput('android', 'status', [{
168
+ channel: opts.channel,
169
+ packageName: opts.packageName ?? creds.package_name,
170
+ versionName: opts.versionName,
171
+ versionCode: opts.versionCode,
172
+ action: 'status',
173
+ status: 'skipped',
174
+ message: 'dry-run',
175
+ }]);
176
+ printOutput(out, opts.output);
177
+ process.exit(ExitCode.OK);
178
+ }
179
+ const res = await adapter.queryStatus({
180
+ packageName: opts.packageName ?? creds.package_name,
181
+ versionName: opts.versionName,
182
+ versionCode: opts.versionCode,
183
+ creds: chCreds,
184
+ timeoutMs,
185
+ });
186
+ const out = buildOutput('android', 'status', [res]);
187
+ printOutput(out, opts.output);
188
+ process.exit(exitCodeFor(out));
189
+ }
190
+ // 发布策略校验:仅 MANUAL / AFTER_APPROVAL。SCHEDULED(定时发布)需要 earliestReleaseDate,
191
+ // 全链路未实现日期参数,故主动拒绝,避免设置了 releaseType 却无日期的无效版本。
192
+ function assertReleaseType(rt) {
193
+ if (rt && rt !== 'MANUAL' && rt !== 'AFTER_APPROVAL') {
194
+ throw new UsageError(`--release-type 仅支持 MANUAL | AFTER_APPROVAL(收到 "${rt}")。SCHEDULED 定时发布暂不支持(需发布日期参数,未实现)。`);
195
+ }
196
+ }
197
+ // ---------- ios upload ----------
198
+ async function iosUpload(opts) {
199
+ const timeoutMs = parseTimeoutMs(opts);
200
+ const creds = loadCreds(resolveCredsPath(opts.creds), 'ios');
201
+ validateIosCreds(creds);
202
+ assertReleaseType(opts.releaseType);
203
+ if (!existsSync(opts.package))
204
+ throw new InputError(`ipa 不存在: ${opts.package}`);
205
+ if (opts.submitReview && !(opts.appId ?? creds.app_id)) {
206
+ throw new UsageError('iOS 提审需要 app Apple ID:请传 --app-id 或在 creds 配 app_id');
207
+ }
208
+ let versionName = opts.versionName ?? '';
209
+ let versionCode = opts.buildVersion ?? '';
210
+ if (!versionName || !versionCode) {
211
+ const meta = await parsePackage(opts.package).catch(() => null);
212
+ if (meta) {
213
+ versionName ||= meta.versionName;
214
+ versionCode ||= meta.versionCode;
215
+ }
216
+ }
217
+ let metadata;
218
+ if (opts.metadata) {
219
+ if (!existsSync(opts.metadata))
220
+ throw new InputError(`metadata 文件不存在: ${opts.metadata}`);
221
+ metadata = parseYaml(readFileSync(opts.metadata, 'utf8'));
222
+ }
223
+ const adapter = getIosAdapter();
224
+ const ctx = {
225
+ pkg: opts.package,
226
+ packageName: opts.appId ?? '',
227
+ versionName,
228
+ versionCode,
229
+ releaseNote: readText(opts.whatsNew),
230
+ submitReview: !!opts.submitReview,
231
+ metadata,
232
+ releaseType: opts.releaseType,
233
+ creds: { ...creds, team_id: opts.teamId ?? creds.team_id, app_id: opts.appId ?? creds.app_id },
234
+ timeoutMs,
235
+ };
236
+ if (opts.dryRun) {
237
+ const out = buildOutput('ios', 'upload', [{
238
+ channel: 'appstore',
239
+ packageName: ctx.packageName,
240
+ versionName: ctx.versionName,
241
+ versionCode: ctx.versionCode,
242
+ action: ctx.submitReview ? 'upload+submit' : 'upload',
243
+ status: 'skipped',
244
+ message: 'dry-run',
245
+ }]);
246
+ printOutput(out, opts.output);
247
+ process.exit(ExitCode.OK);
248
+ }
249
+ const res = await adapter.upload(ctx);
250
+ const out = buildOutput('ios', 'upload', [res]);
251
+ printOutput(out, opts.output);
252
+ process.exit(exitCodeFor(out));
253
+ }
254
+ // ---------- ios status ----------
255
+ async function iosStatus(opts) {
256
+ const timeoutMs = parseTimeoutMs(opts);
257
+ const creds = loadCreds(resolveCredsPath(opts.creds), 'ios');
258
+ validateIosCreds(creds);
259
+ if (!opts.appId && !creds.app_id && !opts.bundleId)
260
+ throw new UsageError('iOS 查状态需要 app 标识:请传 --app-id 或 --bundle-id(或在 creds 配 app_id)');
261
+ if (opts.dryRun) {
262
+ const out = buildOutput('ios', 'status', [{
263
+ channel: 'appstore', action: 'status', status: 'skipped',
264
+ versionName: opts.appVersion, message: 'dry-run',
265
+ }]);
266
+ printOutput(out, opts.output);
267
+ process.exit(ExitCode.OK);
268
+ }
269
+ const adapter = getIosAdapter();
270
+ const res = await adapter.queryStatus({
271
+ versionName: opts.appVersion,
272
+ bundleId: opts.bundleId,
273
+ creds: { ...creds, app_id: opts.appId ?? creds.app_id },
274
+ timeoutMs,
275
+ });
276
+ const out = buildOutput('ios', 'status', [res]);
277
+ printOutput(out, opts.output);
278
+ process.exit(exitCodeFor(out));
279
+ }
280
+ // ---------- ios release ----------
281
+ async function iosRelease(opts) {
282
+ const timeoutMs = parseTimeoutMs(opts);
283
+ const creds = loadCreds(resolveCredsPath(opts.creds), 'ios');
284
+ validateIosCreds(creds);
285
+ if (!opts.appId && !creds.app_id && !opts.bundleId)
286
+ throw new UsageError('iOS 发布需要 app 标识:请传 --app-id 或 --bundle-id(或在 creds 配 app_id)');
287
+ if (opts.dryRun) {
288
+ const out = buildOutput('ios', 'release', [{
289
+ channel: 'appstore', action: 'release', status: 'skipped',
290
+ versionName: opts.appVersion, message: 'dry-run',
291
+ }]);
292
+ printOutput(out, opts.output);
293
+ process.exit(ExitCode.OK);
294
+ }
295
+ const adapter = getIosAdapter();
296
+ const res = await adapter.release({
297
+ appId: opts.appId ?? creds.app_id,
298
+ bundleId: opts.bundleId,
299
+ version: opts.appVersion,
300
+ creds,
301
+ phased: !!opts.phased,
302
+ complete: !!opts.complete,
303
+ pause: !!opts.pause,
304
+ resume: !!opts.resume,
305
+ timeoutMs,
306
+ });
307
+ const out = buildOutput('ios', 'release', [res]);
308
+ printOutput(out, opts.output);
309
+ process.exit(exitCodeFor(out));
310
+ }
311
+ // ---------- ios submit ----------
312
+ async function iosSubmit(opts) {
313
+ const timeoutMs = parseTimeoutMs(opts);
314
+ const creds = loadCreds(resolveCredsPath(opts.creds), 'ios');
315
+ validateIosCreds(creds);
316
+ assertReleaseType(opts.releaseType);
317
+ const appId = opts.appId ?? creds.app_id;
318
+ if (!appId && !opts.bundleId)
319
+ throw new UsageError('iOS 提审需要 app 标识:请传 --app-id 或 --bundle-id(或在 creds 配 app_id)');
320
+ let metadata;
321
+ if (opts.metadata) {
322
+ if (!existsSync(opts.metadata))
323
+ throw new InputError(`metadata 文件不存在: ${opts.metadata}`);
324
+ metadata = parseYaml(readFileSync(opts.metadata, 'utf8'));
325
+ }
326
+ if (opts.dryRun) {
327
+ const out = buildOutput('ios', 'submit', [{
328
+ channel: 'appstore', action: 'submit', status: 'skipped',
329
+ versionName: opts.appVersion, versionCode: opts.buildVersion, message: 'dry-run',
330
+ }]);
331
+ printOutput(out, opts.output);
332
+ process.exit(ExitCode.OK);
333
+ }
334
+ const adapter = getIosAdapter();
335
+ const res = await adapter.submit({
336
+ appId,
337
+ bundleId: opts.bundleId,
338
+ version: opts.appVersion,
339
+ buildVersion: opts.buildVersion,
340
+ creds,
341
+ metadata,
342
+ whatsNew: readText(opts.whatsNew),
343
+ releaseType: opts.releaseType,
344
+ timeoutMs,
345
+ });
346
+ const out = buildOutput('ios', 'submit', [res]);
347
+ printOutput(out, opts.output);
348
+ process.exit(exitCodeFor(out));
349
+ }
350
+ function mapError(e) {
351
+ if (e instanceof UsageError)
352
+ return ExitCode.USAGE;
353
+ if (e instanceof CredsError)
354
+ return ExitCode.CREDS;
355
+ if (e instanceof InputError)
356
+ return ExitCode.INPUT;
357
+ if (e instanceof Error && e.name === 'TimeoutError')
358
+ return ExitCode.TIMEOUT;
359
+ return ExitCode.ALL_FAILED;
360
+ }
361
+ function build() {
362
+ const program = new Command();
363
+ program
364
+ .name('shipup')
365
+ .description('跨平台应用商店上传、提审、状态查询与发布 CLI')
366
+ .version(VERSION);
367
+ const android = program.command('android').description('Android 多渠道传包/提审/状态');
368
+ android
369
+ .command('upload')
370
+ .description('上传(并按需提审)一个或多个单渠道包')
371
+ .option('--upload <map...>', '渠道=包路径,可重复,如 huawei=./app-huawei.apk')
372
+ .option('--creds <file>', '凭证 YAML;默认 SHIPUP_CREDS 或 ~/.config/shipup/credentials.yaml')
373
+ .option('--submit-review', '上传后提交审核(部分渠道 upload 即 submit)', false)
374
+ .option('--version-name <v>', '缺省从 APK 读取')
375
+ .option('--version-code <v>', '缺省从 APK 读取')
376
+ .option('--release-note <v>', '更新说明,支持 @file')
377
+ .option('--icon <path>', '图标文件(小米/魅族必需;其余渠道需配合 --update-icon)')
378
+ .option('--update-icon', '同时更新华为/荣耀/OPPO/vivo/三星的图标(默认沿用商店现有图标)', false)
379
+ .option('--screenshot <path...>', '截图/介绍图文件,可多次/多值;非空时更新该渠道截图')
380
+ .option('--app-name <v>', '更新应用名称(注意各渠道限改频率与禁特殊符号)')
381
+ .option('--summary <v>', '更新一句话简介 / 推荐语')
382
+ .option('--description <v>', '更新应用简介 / 长描述,支持 @file')
383
+ .option('--concurrency <n>', '渠道并发数', '3')
384
+ .option('--timeout <s>', '单渠道超时(秒)', '900')
385
+ .option('--output <fmt>', 'json | text', 'text')
386
+ .option('--dry-run', '只校验参数与凭证,不真正上传', false)
387
+ .action(androidUpload);
388
+ android
389
+ .command('status')
390
+ .description('查询某渠道审核/上架状态')
391
+ .requiredOption('--channel <channel>', '单个渠道(huawei|honor|oppo|vivo|xiaomi|samsung|qq|meizu)')
392
+ .option('--creds <file>', '凭证 YAML;默认 SHIPUP_CREDS 或 ~/.config/shipup/credentials.yaml')
393
+ .option('--package-name <v>', '应用包名(缺省用 creds.package_name)')
394
+ .option('--version-name <v>', '版本名,用于定位具体版本')
395
+ .option('--version-code <v>', '版本号,用于定位具体版本(优先于 version-name)')
396
+ .option('--timeout <s>', '查询超时(秒)', '900')
397
+ .option('--output <fmt>', '输出格式 json | text', 'text')
398
+ .option('--dry-run', '只校验参数与凭证,不查询', false)
399
+ .action(androidStatus);
400
+ const ios = program.command('ios').description('iOS App Store Connect 传包/提审/发布');
401
+ ios
402
+ .command('upload')
403
+ .description('altool 上传 + 建版本 + 文案 + 合规 + 关联 build +(可选)提交审核')
404
+ .requiredOption('--package <ipa>', '已签名 ipa 路径')
405
+ .option('--creds <file>', '凭证 YAML;默认 SHIPUP_CREDS 或 ~/.config/shipup/credentials.yaml')
406
+ .option('--team-id <v>', '开发者 Team ID(缺省用 creds.team_id)')
407
+ .option('--app-id <v>', 'ASC 上的 app Apple ID(提审必填,缺省用 creds.app_id)')
408
+ .option('--metadata <file>', '多地区文案 YAML(locale → whatsNew/description/promotionalText/keywords)')
409
+ .option('--whats-new <v>', '单一 locale 的 whatsNew,支持 @file(无 metadata 时作 zh-Hans)')
410
+ .option('--submit-review', '上传后走 ASC API 提交 App Store 审核', false)
411
+ .option('--release-type <v>', '发布策略 MANUAL | AFTER_APPROVAL')
412
+ .option('--version-name <v>', '营销版本号,缺省从 ipa 读取')
413
+ .option('--build-version <v>', 'build 号(CFBundleVersion),缺省从 ipa 读取')
414
+ .option('--timeout <s>', 'altool 上传 + 提审超时(秒)', '1800')
415
+ .option('--output <fmt>', '输出格式 json | text', 'text')
416
+ .option('--dry-run', '只校验参数与凭证,不上传', false)
417
+ .action(iosUpload);
418
+ ios
419
+ .command('status')
420
+ .description('查询 App Store 审核/版本/灰度状态')
421
+ .option('--creds <file>', '凭证 YAML;默认 SHIPUP_CREDS 或 ~/.config/shipup/credentials.yaml')
422
+ .option('--app-id <v>', 'ASC 上的 app Apple ID(与 --bundle-id 二选一,缺省用 creds.app_id)')
423
+ .option('--bundle-id <v>', 'app bundle id,自动反查 Apple ID(与 --app-id 二选一)')
424
+ .requiredOption('--app-version <v>', '要查询的版本号')
425
+ .option('--timeout <s>', '查询超时(秒)', '900')
426
+ .option('--output <fmt>', '输出格式 json | text', 'text')
427
+ .option('--dry-run', '只校验参数与凭证,不查询', false)
428
+ .action(iosStatus);
429
+ ios
430
+ .command('release')
431
+ .description('审核通过后发布(手动 release / 灰度)')
432
+ .option('--creds <file>', '凭证 YAML;默认 SHIPUP_CREDS 或 ~/.config/shipup/credentials.yaml')
433
+ .option('--app-id <v>', 'ASC 上的 app Apple ID(与 --bundle-id 二选一,缺省用 creds.app_id)')
434
+ .option('--bundle-id <v>', 'app bundle id,自动反查 Apple ID(与 --app-id 二选一)')
435
+ .requiredOption('--app-version <v>', '要发布的版本号')
436
+ .option('--phased', '以灰度方式开始发布(不向所有用户全量)', false)
437
+ .option('--complete', '把进行中的灰度立即转为全量', false)
438
+ .option('--pause', '暂停进行中的灰度', false)
439
+ .option('--resume', '恢复已暂停的灰度', false)
440
+ .option('--timeout <s>', '操作超时(秒)', '900')
441
+ .option('--output <fmt>', '输出格式 json | text', 'text')
442
+ .option('--dry-run', '只校验参数与凭证,不发布', false)
443
+ .action(iosRelease);
444
+ ios
445
+ .command('submit')
446
+ .description('提审已上传的 build(不重传;build 由上游 altool 上传)')
447
+ .option('--creds <file>', '凭证 YAML;默认 SHIPUP_CREDS 或 ~/.config/shipup/credentials.yaml')
448
+ .option('--app-id <v>', 'ASC 上的 app Apple ID(与 --bundle-id 二选一,缺省用 creds.app_id)')
449
+ .option('--bundle-id <v>', 'app bundle id,自动反查 Apple ID(与 --app-id 二选一)')
450
+ .requiredOption('--app-version <v>', '营销版本号 versionString')
451
+ .requiredOption('--build-version <v>', 'build 号 CFBundleVersion(用于定位已上传的 build)')
452
+ .option('--metadata <file>', '多地区文案 YAML(locale → whatsNew/description/...)')
453
+ .option('--whats-new <v>', '单一 locale 的 whatsNew,支持 @file(无 metadata 时作 zh-Hans)')
454
+ .option('--release-type <v>', '发布策略 MANUAL | AFTER_APPROVAL')
455
+ .option('--timeout <s>', '等 build 就绪 + 提审超时(秒)', '1800')
456
+ .option('--output <fmt>', '输出格式 json | text', 'text')
457
+ .option('--dry-run', '只校验参数与凭证,不调用 ASC', false)
458
+ .action(iosSubmit);
459
+ return program;
460
+ }
461
+ const normalizedArgv = [...process.argv];
462
+ if (normalizedArgv[2] === 'ios') {
463
+ const command = normalizedArgv[3];
464
+ for (let i = 4; i < normalizedArgv.length; i++) {
465
+ if (normalizedArgv[i] === '--version') {
466
+ normalizedArgv[i] = command === 'upload' ? '--version-name' : '--app-version';
467
+ }
468
+ else if (normalizedArgv[i] === '--build') {
469
+ normalizedArgv[i] = '--build-version';
470
+ }
471
+ }
472
+ }
473
+ build()
474
+ .parseAsync(normalizedArgv)
475
+ .catch((e) => {
476
+ process.stderr.write(`shipup: ${e instanceof Error ? e.message : String(e)}\n`);
477
+ process.exit(mapError(e));
478
+ });
479
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { ExitCode } from '../core/exit.js';
2
+ // 只有「操作失败」才算 failed;rejected/offline 是查询到的**业务状态**,操作本身成功
3
+ // (status 命令查到应用被驳回/下架不应判为「失败」,否则调用方会误判查询出错)。
4
+ const OP_FAILED = new Set([
5
+ 'failed',
6
+ 'not_implemented',
7
+ ]);
8
+ function classify(results) {
9
+ let succeeded = 0;
10
+ let skipped = 0;
11
+ let failed = 0;
12
+ for (const r of results) {
13
+ if (r.status === 'skipped')
14
+ skipped++;
15
+ else if (OP_FAILED.has(r.status))
16
+ failed++;
17
+ else
18
+ succeeded++; // 操作成功(含 uploaded/submitted/.../rejected/offline 等业务态)
19
+ }
20
+ return { succeeded, skipped, failed };
21
+ }
22
+ export function buildOutput(platform, command, results) {
23
+ const c = classify(results);
24
+ return {
25
+ tool: 'shipup',
26
+ platform,
27
+ command,
28
+ ok: c.failed === 0,
29
+ summary: { total: results.length, succeeded: c.succeeded, failed: c.failed, skipped: c.skipped },
30
+ results,
31
+ };
32
+ }
33
+ export function exitCodeFor(out) {
34
+ if (out.summary.total === 0)
35
+ return ExitCode.USAGE;
36
+ if (out.summary.failed === 0)
37
+ return ExitCode.OK;
38
+ if (out.summary.succeeded === 0 && out.summary.skipped === 0) {
39
+ // 全部失败:若失败全是超时则用 124,便于调用方据退出码识别超时。
40
+ const opFailed = out.results.filter((r) => r.status === 'failed' || r.status === 'not_implemented');
41
+ if (opFailed.length > 0 && opFailed.every((r) => r.errorCode === 'timeout'))
42
+ return ExitCode.TIMEOUT;
43
+ return ExitCode.ALL_FAILED;
44
+ }
45
+ return ExitCode.PARTIAL;
46
+ }
47
+ export function printOutput(out, format) {
48
+ if (format === 'json') {
49
+ process.stdout.write(JSON.stringify(out, null, 2) + '\n');
50
+ return;
51
+ }
52
+ const { summary } = out;
53
+ process.stdout.write(`shipup ${out.platform} ${out.command} — ${out.ok ? 'OK' : 'FAILED'}\n`);
54
+ process.stdout.write(` total=${summary.total} ok=${summary.succeeded} failed=${summary.failed} skipped=${summary.skipped}\n`);
55
+ for (const r of out.results) {
56
+ const ver = r.versionName ? ` ${r.versionName}` : '';
57
+ const extra = r.status === 'failed' || r.status === 'not_implemented'
58
+ ? ` [${r.errorCode ?? '-'}] ${r.message ?? ''}`
59
+ : r.marketVersion
60
+ ? ` (线上 ${r.marketVersion})`
61
+ : '';
62
+ process.stdout.write(` - ${r.channel}${ver}: ${r.status}${extra}\n`);
63
+ }
64
+ }
65
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ // 退出码(与需求文档 §3.4.6 一致)
2
+ export const ExitCode = {
3
+ OK: 0, // 全部成功
4
+ PARTIAL: 1, // 部分渠道失败
5
+ ALL_FAILED: 2, // 全部失败
6
+ USAGE: 3, // 参数 / 用法错误
7
+ CREDS: 4, // 凭证缺失或无效
8
+ INPUT: 5, // 输入包文件不存在 / 不可读
9
+ TIMEOUT: 124, // 超时
10
+ };
11
+ /** 用法错误:参数不合法时抛出,CLI 层捕获后以 USAGE 退出 */
12
+ export class UsageError extends Error {
13
+ }
14
+ /** 凭证错误 */
15
+ export class CredsError extends Error {
16
+ }
17
+ /** 输入错误(包文件缺失等) */
18
+ export class InputError extends Error {
19
+ }
20
+ //# sourceMappingURL=exit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit.js","sourceRoot":"","sources":["../../src/core/exit.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,EAAE,EAAE,CAAC,EAAE,OAAO;IACd,OAAO,EAAE,CAAC,EAAE,SAAS;IACrB,UAAU,EAAE,CAAC,EAAE,OAAO;IACtB,KAAK,EAAE,CAAC,EAAE,YAAY;IACtB,KAAK,EAAE,CAAC,EAAE,UAAU;IACpB,KAAK,EAAE,CAAC,EAAE,iBAAiB;IAC3B,OAAO,EAAE,GAAG,EAAE,KAAK;CACX,CAAC;AAIX,uCAAuC;AACvC,MAAM,OAAO,UAAW,SAAQ,KAAK;CAAG;AACxC,WAAW;AACX,MAAM,OAAO,UAAW,SAAQ,KAAK;CAAG;AACxC,mBAAmB;AACnB,MAAM,OAAO,UAAW,SAAQ,KAAK;CAAG"}
@@ -0,0 +1,24 @@
1
+ // 多渠道并发编排:p-limit 控并发,单渠道失败隔离,聚合结果。
2
+ import pLimit from 'p-limit';
3
+ import { toFailed } from '../adapters/util.js';
4
+ export async function runUploads(tasks, concurrency) {
5
+ const limit = pLimit(Math.max(1, concurrency));
6
+ return Promise.all(tasks.map((t) => limit(async () => {
7
+ const start = Date.now();
8
+ const ch = t.adapter.channel;
9
+ // 进度走 stderr(不污染 stdout 的 JSON),便于调用方/人看出跑到哪个渠道。
10
+ console.error(`[shipup] ${ch} 开始上传…`);
11
+ try {
12
+ const r = await t.adapter.upload(t.ctx);
13
+ console.error(`[shipup] ${ch} 结束: ${r.status} (${Date.now() - start}ms)`);
14
+ return r;
15
+ }
16
+ catch (e) {
17
+ // adapter 内部一般已自捕获;此处兜底
18
+ const r = toFailed(ch, e, start, 'upload', t.ctx);
19
+ console.error(`[shipup] ${ch} 失败: [${r.errorCode}] ${r.message} (${Date.now() - start}ms)`);
20
+ return r;
21
+ }
22
+ })));
23
+ }
24
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAO/C,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAmB,EACnB,WAAmB;IAEnB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACd,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QAC7B,iDAAiD;QACjD,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,CAAC;YAC1E,OAAO,CAAC,CAAC;QACX,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,wBAAwB;YACxB,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,CAAC;YAC5F,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC,CAAC,CACH,CACF,CAAC;AACJ,CAAC"}