@capawesome/cli 3.6.0 → 3.7.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/CHANGELOG.md +7 -0
- package/dist/commands/apps/builds/create.js +55 -17
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [3.7.0](https://github.com/capawesome-team/cli/compare/v3.6.0...v3.7.0) (2025-12-02)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **apps:builds:create:** add JSON output option ([#101](https://github.com/capawesome-team/cli/issues/101)) ([32797f9](https://github.com/capawesome-team/cli/commit/32797f93229848fc23565e89f245772e3e509500))
|
|
11
|
+
|
|
5
12
|
## [3.6.0](https://github.com/capawesome-team/cli/compare/v3.5.0...v3.6.0) (2025-11-29)
|
|
6
13
|
|
|
7
14
|
|
|
@@ -44,6 +44,7 @@ export default defineCommand({
|
|
|
44
44
|
.union([z.boolean(), z.string()])
|
|
45
45
|
.optional()
|
|
46
46
|
.describe('Download the generated IPA file (iOS only). Optionally provide a file path.'),
|
|
47
|
+
json: z.boolean().optional().describe('Output in JSON format.'),
|
|
47
48
|
platform: z
|
|
48
49
|
.enum(['ios', 'android'], {
|
|
49
50
|
message: 'Platform must be either `ios` or `android`.',
|
|
@@ -56,7 +57,7 @@ export default defineCommand({
|
|
|
56
57
|
.describe('The type of build. For iOS, supported values are `simulator`, `development`, `ad-hoc`, `app-store`, and `enterprise`. For Android, supported values are `debug` and `release`.'),
|
|
57
58
|
})),
|
|
58
59
|
action: async (options) => {
|
|
59
|
-
let { appId, platform, type, gitRef, environment, certificate } = options;
|
|
60
|
+
let { appId, platform, type, gitRef, environment, certificate, json } = options;
|
|
60
61
|
// Check if the user is logged in
|
|
61
62
|
if (!authorizationService.hasAuthorizationToken()) {
|
|
62
63
|
consola.error('You must be logged in to run this command.');
|
|
@@ -193,7 +194,9 @@ export default defineCommand({
|
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
// Create the app build
|
|
196
|
-
|
|
197
|
+
if (!json) {
|
|
198
|
+
consola.start('Creating build...');
|
|
199
|
+
}
|
|
197
200
|
const response = await appBuildsService.create({
|
|
198
201
|
appCertificateName: certificate,
|
|
199
202
|
appEnvironmentName: environment,
|
|
@@ -202,10 +205,12 @@ export default defineCommand({
|
|
|
202
205
|
platform,
|
|
203
206
|
type,
|
|
204
207
|
});
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
208
|
+
if (!json) {
|
|
209
|
+
consola.success(`Build created successfully.`);
|
|
210
|
+
consola.info(`Build Number: ${response.numberAsString}`);
|
|
211
|
+
consola.info(`Build ID: ${response.id}`);
|
|
212
|
+
consola.info(`Build URL: ${DEFAULT_CONSOLE_BASE_URL}/apps/${appId}/builds/${response.id}`);
|
|
213
|
+
}
|
|
209
214
|
// Wait for build job to complete by default, unless --detached flag is set
|
|
210
215
|
const shouldWait = !options.detached;
|
|
211
216
|
if (shouldWait) {
|
|
@@ -226,7 +231,7 @@ export default defineCommand({
|
|
|
226
231
|
const jobStatus = build.job.status;
|
|
227
232
|
// Show spinner while queued or pending
|
|
228
233
|
if (jobStatus === 'queued' || jobStatus === 'pending') {
|
|
229
|
-
if (isWaitingForStart) {
|
|
234
|
+
if (isWaitingForStart && !json) {
|
|
230
235
|
consola.start(`Waiting for build to start (status: ${jobStatus})...`);
|
|
231
236
|
}
|
|
232
237
|
await wait(3000);
|
|
@@ -235,10 +240,12 @@ export default defineCommand({
|
|
|
235
240
|
// Stop spinner when job moves to in_progress
|
|
236
241
|
if (isWaitingForStart && jobStatus === 'in_progress') {
|
|
237
242
|
isWaitingForStart = false;
|
|
238
|
-
|
|
243
|
+
if (!json) {
|
|
244
|
+
consola.success('Build started...');
|
|
245
|
+
}
|
|
239
246
|
}
|
|
240
247
|
// Print new logs
|
|
241
|
-
if (build.job.jobLogs && build.job.jobLogs.length > 0) {
|
|
248
|
+
if (!json && build.job.jobLogs && build.job.jobLogs.length > 0) {
|
|
242
249
|
const newLogs = build.job.jobLogs
|
|
243
250
|
.filter((log) => log.number > lastPrintedLogNumber)
|
|
244
251
|
.sort((a, b) => a.number - b.number);
|
|
@@ -253,10 +260,14 @@ export default defineCommand({
|
|
|
253
260
|
jobStatus === 'canceled' ||
|
|
254
261
|
jobStatus === 'rejected' ||
|
|
255
262
|
jobStatus === 'timed_out') {
|
|
256
|
-
|
|
257
|
-
if (jobStatus === 'succeeded') {
|
|
258
|
-
consola.success('Build completed successfully.');
|
|
263
|
+
if (!json) {
|
|
259
264
|
console.log(); // New line for better readability
|
|
265
|
+
}
|
|
266
|
+
if (jobStatus === 'succeeded') {
|
|
267
|
+
if (!json) {
|
|
268
|
+
consola.success('Build completed successfully.');
|
|
269
|
+
console.log(); // New line for better readability
|
|
270
|
+
}
|
|
260
271
|
// Download artifacts if flags are set
|
|
261
272
|
if (options.apk && platform === 'android') {
|
|
262
273
|
await handleArtifactDownload({
|
|
@@ -265,6 +276,7 @@ export default defineCommand({
|
|
|
265
276
|
buildArtifacts: build.appBuildArtifacts,
|
|
266
277
|
artifactType: 'apk',
|
|
267
278
|
filePath: typeof options.apk === 'string' ? options.apk : undefined,
|
|
279
|
+
json,
|
|
268
280
|
});
|
|
269
281
|
}
|
|
270
282
|
if (options.aab && platform === 'android') {
|
|
@@ -274,6 +286,7 @@ export default defineCommand({
|
|
|
274
286
|
buildArtifacts: build.appBuildArtifacts,
|
|
275
287
|
artifactType: 'aab',
|
|
276
288
|
filePath: typeof options.aab === 'string' ? options.aab : undefined,
|
|
289
|
+
json,
|
|
277
290
|
});
|
|
278
291
|
}
|
|
279
292
|
if (options.ipa && platform === 'ios') {
|
|
@@ -283,8 +296,17 @@ export default defineCommand({
|
|
|
283
296
|
buildArtifacts: build.appBuildArtifacts,
|
|
284
297
|
artifactType: 'ipa',
|
|
285
298
|
filePath: typeof options.ipa === 'string' ? options.ipa : undefined,
|
|
299
|
+
json,
|
|
286
300
|
});
|
|
287
301
|
}
|
|
302
|
+
// Output JSON if json flag is set
|
|
303
|
+
if (json) {
|
|
304
|
+
console.log(JSON.stringify({
|
|
305
|
+
id: response.id,
|
|
306
|
+
numberAsString: response.numberAsString,
|
|
307
|
+
}, null, 2));
|
|
308
|
+
}
|
|
309
|
+
// Exit successfully
|
|
288
310
|
process.exit(0);
|
|
289
311
|
}
|
|
290
312
|
else if (jobStatus === 'failed') {
|
|
@@ -313,24 +335,38 @@ export default defineCommand({
|
|
|
313
335
|
}
|
|
314
336
|
}
|
|
315
337
|
}
|
|
338
|
+
else {
|
|
339
|
+
if (json) {
|
|
340
|
+
console.log(JSON.stringify({
|
|
341
|
+
id: response.id,
|
|
342
|
+
numberAsString: response.numberAsString,
|
|
343
|
+
}, null, 2));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
316
346
|
},
|
|
317
347
|
});
|
|
318
348
|
/**
|
|
319
349
|
* Download a build artifact (APK, AAB, or IPA).
|
|
320
350
|
*/
|
|
321
351
|
const handleArtifactDownload = async (options) => {
|
|
322
|
-
const { appId, buildId, buildArtifacts, artifactType, filePath } = options;
|
|
352
|
+
const { appId, buildId, buildArtifacts, artifactType, filePath, json } = options;
|
|
323
353
|
try {
|
|
324
354
|
const artifactTypeUpper = artifactType.toUpperCase();
|
|
325
|
-
|
|
355
|
+
if (!json) {
|
|
356
|
+
consola.start(`Downloading ${artifactTypeUpper}...`);
|
|
357
|
+
}
|
|
326
358
|
// Find the artifact
|
|
327
359
|
const artifact = buildArtifacts?.find((artifact) => artifact.type === artifactType);
|
|
328
360
|
if (!artifact) {
|
|
329
|
-
|
|
361
|
+
if (!json) {
|
|
362
|
+
consola.warn(`No ${artifactTypeUpper} artifact found for this build.`);
|
|
363
|
+
}
|
|
330
364
|
return;
|
|
331
365
|
}
|
|
332
366
|
if (artifact.status !== 'ready') {
|
|
333
|
-
|
|
367
|
+
if (!json) {
|
|
368
|
+
consola.warn(`${artifactTypeUpper} artifact is not ready (status: ${artifact.status}).`);
|
|
369
|
+
}
|
|
334
370
|
return;
|
|
335
371
|
}
|
|
336
372
|
// Download the artifact
|
|
@@ -351,7 +387,9 @@ const handleArtifactDownload = async (options) => {
|
|
|
351
387
|
}
|
|
352
388
|
// Save the file
|
|
353
389
|
await fs.writeFile(outputPath, Buffer.from(artifactData));
|
|
354
|
-
|
|
390
|
+
if (!json) {
|
|
391
|
+
consola.success(`${artifactTypeUpper} downloaded successfully: ${outputPath}`);
|
|
392
|
+
}
|
|
355
393
|
}
|
|
356
394
|
catch (error) {
|
|
357
395
|
consola.error(`Failed to download ${artifactType.toUpperCase()}:`, error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capawesome/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "The Capawesome Cloud Command Line Interface (CLI) to manage Live Updates and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"fmt": "npm run prettier -- --write",
|
|
14
14
|
"prettier": "prettier \"**/*.{css,html,ts,js}\"",
|
|
15
15
|
"sentry:releases:new": "sentry-cli releases new capawesome-team-cli@$npm_package_version --org genz-it-solutions-gmbh --project capawesome-team-cli",
|
|
16
|
-
"sentry:releases:set-commits": "sentry-cli releases set-commits capawesome-team-cli@$npm_package_version --auto --org genz-it-solutions-gmbh --project capawesome-team-cli
|
|
16
|
+
"sentry:releases:set-commits": "sentry-cli releases set-commits capawesome-team-cli@$npm_package_version --auto --org genz-it-solutions-gmbh --project capawesome-team-cli",
|
|
17
17
|
"sentry:releases:finalize": "sentry-cli releases finalize capawesome-team-cli@$npm_package_version --org genz-it-solutions-gmbh --project capawesome-team-cli",
|
|
18
18
|
"release": "commit-and-tag-version",
|
|
19
19
|
"prepublishOnly": "npm run build && npm run sentry:releases:new && npm run sentry:releases:set-commits",
|