bdy 1.25.7-dev → 1.25.8-dev

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 (30) hide show
  1. package/distTs/package.json +1 -1
  2. package/distTs/src/cliCommand.js +41 -0
  3. package/distTs/src/command/agent/uninstall.js +1 -1
  4. package/distTs/src/command/artifact/delete.js +1 -2
  5. package/distTs/src/command/artifact/version/delete.js +1 -2
  6. package/distTs/src/command/context/remove.js +1 -2
  7. package/distTs/src/command/distro/delete.js +1 -2
  8. package/distTs/src/command/distro/route/delete.js +1 -2
  9. package/distTs/src/command/environment/delete.js +1 -2
  10. package/distTs/src/command/pipeline/delete.js +1 -2
  11. package/distTs/src/command/pipeline/run/approve.js +3 -2
  12. package/distTs/src/command/pipeline/run/cancel.js +3 -2
  13. package/distTs/src/command/pipeline/run/find.js +87 -0
  14. package/distTs/src/command/pipeline/run/findFilters.js +68 -0
  15. package/distTs/src/command/pipeline/run/retry.js +5 -2
  16. package/distTs/src/command/pipeline/run/start.js +3 -2
  17. package/distTs/src/command/pipeline/run/status.js +3 -2
  18. package/distTs/src/command/pipeline/run.js +3 -0
  19. package/distTs/src/command/sandbox/destroy.js +1 -2
  20. package/distTs/src/command/sandbox/endpoint/delete.js +1 -2
  21. package/distTs/src/command/sandbox/exec/kill.js +1 -2
  22. package/distTs/src/command/sandbox/snapshot/delete.js +1 -2
  23. package/distTs/src/command/target/delete.js +1 -1
  24. package/distTs/src/command/target/exec/kill.js +2 -3
  25. package/distTs/src/input.js +36 -0
  26. package/distTs/src/output/pipeline.js +84 -13
  27. package/distTs/src/output.js +17 -0
  28. package/distTs/src/texts.js +150 -29
  29. package/distTs/src/types/pipelineRunFind.js +2 -0
  30. package/package.json +1 -1
@@ -65,15 +65,34 @@ class OutputPipeline {
65
65
  }
66
66
  return await this._runLogsNonInteractive(client, workspace, project, identifier, pipelineId, runId, runActionId, noWait, isJson, semanticExitCode);
67
67
  }
68
- static async runStatus(client, workspace, project, identifier, pipelineId, runId, noWait, noFollow, isJson, semanticExitCode = false) {
68
+ static findRuns(result) {
69
+ if (result.executions.length) {
70
+ const rows = result.executions.map((run) => [
71
+ String(run.id),
72
+ this.runStatusText((run.status || '-')),
73
+ run.start_date || '-',
74
+ [run.branch?.name, run.tag?.name, run.pull_request?.name]
75
+ .filter(Boolean)
76
+ .join(', ') || '-',
77
+ run.to_revision?.revision?.slice(0, 7) || '-',
78
+ run.html_url || '-',
79
+ ]);
80
+ output_1.default.table([[...texts_1.TXT_PIPELINE_RUN_FIND_COLUMNS], ...rows]);
81
+ }
82
+ output_1.default.normal((0, texts_1.TXT_PIPELINE_RUN_FIND_SUMMARY)(result.executions.length, result.scanned));
83
+ if (result.has_more)
84
+ output_1.default.normal(texts_1.TXT_PIPELINE_RUN_FIND_MORE);
85
+ }
86
+ static async runStatus(client, workspace, project, identifier, pipelineId, runId, noWait, noFollow, isJson, semanticExitCode = false, failedLogs = false) {
69
87
  if (output_1.default.isTTY() &&
70
88
  !noWait &&
71
89
  !noFollow &&
72
90
  !isJson &&
73
- !semanticExitCode) {
91
+ !semanticExitCode &&
92
+ !failedLogs) {
74
93
  return await this._runStatusInteractive(client, workspace, project, pipelineId, runId);
75
94
  }
76
- return await this._runStatusNonInteractive(client, workspace, project, identifier, pipelineId, runId, noWait, noFollow, isJson, semanticExitCode);
95
+ return await this._runStatusNonInteractive(client, workspace, project, identifier, pipelineId, runId, noWait, noFollow, isJson, semanticExitCode, failedLogs);
77
96
  }
78
97
  static _canCancel(status) {
79
98
  return ![
@@ -1327,7 +1346,12 @@ class OutputPipeline {
1327
1346
  }
1328
1347
  }, false, semanticExitCode);
1329
1348
  }
1330
- static async _runStatusNonInteractive(client, workspace, project, identifier, pipelineId, runId, noWait, noFollow, isJson, semanticExitCode = false) {
1349
+ static async _runStatusNonInteractive(client, workspace, project, identifier, pipelineId, runId, noWait, noFollow, isJson, semanticExitCode = false, failedLogs = false) {
1350
+ const finishRun = async (run) => {
1351
+ if (failedLogs)
1352
+ await this.failedActionLogs(client, workspace, project, pipelineId, run, isJson);
1353
+ this._exitByStatus(isJson, run.status, semanticExitCode);
1354
+ };
1331
1355
  let run = null;
1332
1356
  let totalFetchesCount = 0;
1333
1357
  const tabs = 40;
@@ -1395,7 +1419,7 @@ class OutputPipeline {
1395
1419
  });
1396
1420
  run = r;
1397
1421
  };
1398
- run = await this._runStatusLoop(client, workspace, project, pipelineId, runId, (run) => {
1422
+ run = await this._runStatusLoop(client, workspace, project, pipelineId, runId, async (run) => {
1399
1423
  totalFetchesCount += 1;
1400
1424
  if (!noFollow || noWait) {
1401
1425
  if (isJson)
@@ -1418,9 +1442,8 @@ class OutputPipeline {
1418
1442
  throw error;
1419
1443
  }
1420
1444
  }
1421
- if (noWait) {
1422
- this._exitByStatus(isJson, run.status, semanticExitCode);
1423
- }
1445
+ if (noWait)
1446
+ await finishRun(run);
1424
1447
  }, false, semanticExitCode);
1425
1448
  if (isJson) {
1426
1449
  this.jsonRun(identifier, run);
@@ -1465,7 +1488,55 @@ class OutputPipeline {
1465
1488
  output_1.default.normal(this._dimLine());
1466
1489
  output_1.default.normal(this._runActionsLogsHelp(identifier, runId));
1467
1490
  }
1468
- this._exitByStatus(isJson, run.status, semanticExitCode);
1491
+ await finishRun(run);
1492
+ }
1493
+ static async failedActionLogs(client, workspace, project, pipelineId, run, isJson) {
1494
+ for (const action of run.actions) {
1495
+ if (action.status !== pipeline_1.PIPELINE_RUN_STATUS.FAILED)
1496
+ continue;
1497
+ const identity = {
1498
+ action_run_id: action.runId,
1499
+ action_name: action.name,
1500
+ };
1501
+ try {
1502
+ let page = await client.getPipelineRunActionLogs(workspace, project, pipelineId, run.runId, action.runId, 0, texts_1.FAILED_LOGS_LIMIT);
1503
+ if (typeof page.total_element_count !== 'number' ||
1504
+ !Number.isInteger(page.total_element_count) ||
1505
+ page.total_element_count < 0) {
1506
+ throw new cliError_1.default('command_failed', texts_1.ERR_PIPELINE_FAILED_LOGS_COUNT);
1507
+ }
1508
+ // The count lets us jump to the tail without downloading the full log.
1509
+ if (page.total_element_count > texts_1.FAILED_LOGS_LIMIT) {
1510
+ page = await client.getPipelineRunActionLogs(workspace, project, pipelineId, run.runId, action.runId, page.total_element_count - texts_1.FAILED_LOGS_LIMIT, texts_1.FAILED_LOGS_LIMIT);
1511
+ }
1512
+ if (!isJson)
1513
+ output_1.default.data((0, texts_1.TXT_PIPELINE_FAILED_LOGS_HEADER)(action.name, action.runId));
1514
+ const logs = page.logs.slice(-texts_1.FAILED_LOGS_LIMIT);
1515
+ if (!logs.length) {
1516
+ if (isJson)
1517
+ output_1.default.json({
1518
+ type: 'info',
1519
+ ...identity,
1520
+ message: texts_1.TXT_PIPELINE_FAILED_LOGS_EMPTY,
1521
+ });
1522
+ else
1523
+ output_1.default.data(texts_1.TXT_PIPELINE_FAILED_LOGS_EMPTY);
1524
+ }
1525
+ for (const log of logs) {
1526
+ if (isJson)
1527
+ output_1.default.json({ type: 'log', ...identity, log });
1528
+ else
1529
+ output_1.default.data(log);
1530
+ }
1531
+ }
1532
+ catch (error) {
1533
+ const details = cliError_1.default.details(error);
1534
+ if (isJson)
1535
+ output_1.default.json({ type: 'warning', ...identity, error: details });
1536
+ else
1537
+ output_1.default.noteWarning((0, texts_1.TXT_PIPELINE_FAILED_LOGS_ERROR)(action.name, action.runId, details.message));
1538
+ }
1539
+ }
1469
1540
  }
1470
1541
  static async _actionLogsLoop(client, workspace, project, pipelineId, runId, actionExecutionId, onChange) {
1471
1542
  let logs = [];
@@ -1664,11 +1735,11 @@ class OutputPipeline {
1664
1735
  context = {};
1665
1736
  context['Environment'] = run.environment.identifier;
1666
1737
  }
1667
- if (run.package && run.package_version) {
1738
+ if (run.artifact && run.artifact_version) {
1668
1739
  if (!context)
1669
1740
  context = {};
1670
- context['Package'] =
1671
- `${run.package.identifier}:${run.package_version.version}`;
1741
+ context['Artifact'] =
1742
+ `${run.artifact.identifier}:${run.artifact_version.version}`;
1672
1743
  }
1673
1744
  if (run.loop_details) {
1674
1745
  if (!context)
@@ -1768,7 +1839,7 @@ class OutputPipeline {
1768
1839
  context,
1769
1840
  actions,
1770
1841
  };
1771
- onChange(r, forceFetchRun);
1842
+ await onChange(r, forceFetchRun);
1772
1843
  return r;
1773
1844
  };
1774
1845
  lastRun = await forceFetchRun();
@@ -187,6 +187,15 @@ class Output {
187
187
  static data(txt, newLine = true) {
188
188
  process.stdout.write(newLine ? `${txt}\n` : txt);
189
189
  }
190
+ static examples(command, examples, format) {
191
+ if (format === 'json')
192
+ return this.json({ command, examples });
193
+ if (format === 'jsonl')
194
+ return this.json({ type: 'examples', command, examples });
195
+ if (!examples.length)
196
+ return this.data(`No examples for ${command}.`);
197
+ this.data(`EXAMPLES:\n${examples.map((example) => ` ### ${example.description}\n ${example.command}`).join('\n')}`);
198
+ }
190
199
  // For payload embedded in terminal-kit markup (e.g. a dimmed log line):
191
200
  // neutralizes the ^-markup and %-formatting the payload would otherwise
192
201
  // trigger, so it renders verbatim while the surrounding markup still
@@ -375,6 +384,14 @@ class Output {
375
384
  }
376
385
  });
377
386
  }
387
+ static async confirmDestructive(force, message, quiet = false) {
388
+ if (force)
389
+ return true;
390
+ if (!this.isStdInTTY()) {
391
+ throw new cliError_1.default('usage_error', texts_1.ERR_CONFIRM_REQUIRED, texts_1.TXT_CONFIRM_FORCE_HINT);
392
+ }
393
+ return await this.confirm(message, quiet);
394
+ }
378
395
  static async confirm(message = 'Are you sure?', quiet = false) {
379
396
  if (this.isStdInTTY()) {
380
397
  const prompts = require('@inquirer/prompts');