automata-cli 0.1.0-005-azdo-remote-support.27 → 0.1.0-005-azdo-remote-support.29

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 (2) hide show
  1. package/dist/index.js +118 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -299,13 +299,49 @@ function getCurrentBranch() {
299
299
  }
300
300
  return stdout.trim();
301
301
  }
302
+ function parseOwnerRepo() {
303
+ const { stdout, status } = run2("git", ["remote", "get-url", "origin"]);
304
+ if (status !== 0) return null;
305
+ const url = stdout.trim();
306
+ const https = url.match(/github\.com\/([^/]+\/[^/]+?)(?:\.git)?$/);
307
+ if (https) return https[1];
308
+ const ssh = url.match(/github\.com:([^/]+\/[^/]+?)(?:\.git)?$/);
309
+ if (ssh) return ssh[1];
310
+ return null;
311
+ }
312
+ function extractLastMarkdownUrl(markdown) {
313
+ const matches = [...markdown.matchAll(/\]\((https?:\/\/[^)]+)\)/g)];
314
+ return matches.length > 0 ? matches[matches.length - 1][1] ?? null : null;
315
+ }
316
+ function fetchCheckRunOutputs(ownerRepo, sha) {
317
+ const { stdout, status } = run2("gh", [
318
+ "api",
319
+ `repos/${ownerRepo}/commits/${sha}/check-runs`,
320
+ "--jq",
321
+ ".check_runs[] | {name, html_url, details_url, output}"
322
+ ]);
323
+ const map = /* @__PURE__ */ new Map();
324
+ if (status !== 0) return map;
325
+ for (const line of stdout.trim().split("\n")) {
326
+ if (!line) continue;
327
+ try {
328
+ const item = JSON.parse(line);
329
+ const title = item.output?.title ?? "";
330
+ const summaryUrl = item.output?.summary ? extractLastMarkdownUrl(item.output.summary) : null;
331
+ const detailsUrl = summaryUrl ?? (item.details_url !== item.html_url ? item.details_url : "") ?? item.html_url;
332
+ map.set(item.name, { title, detailsUrl });
333
+ } catch {
334
+ }
335
+ }
336
+ return map;
337
+ }
302
338
  function getPrInfoGh(branch) {
303
339
  const { stdout, stderr, status } = run2("gh", [
304
340
  "pr",
305
341
  "view",
306
342
  branch,
307
343
  "--json",
308
- "number,title,state,url,statusCheckRollup"
344
+ "number,title,state,url,headRefOid,statusCheckRollup"
309
345
  ]);
310
346
  if (status !== 0) {
311
347
  if (stderr.includes("no pull requests found") || stderr.includes("Could not resolve")) {
@@ -314,13 +350,21 @@ function getPrInfoGh(branch) {
314
350
  throw new Error(stderr.trim() || "Failed to query GitHub. Is `gh` installed and authenticated?");
315
351
  }
316
352
  const raw = JSON.parse(stdout);
317
- const checks = (raw.statusCheckRollup ?? []).map((c) => ({
318
- name: c.name,
319
- status: c.status,
320
- conclusion: c.conclusion,
321
- description: c.description ?? "",
322
- detailsUrl: c.detailsUrl ?? ""
323
- }));
353
+ const failedChecks = (raw.statusCheckRollup ?? []).filter(
354
+ (c) => c.conclusion !== null && ["FAILURE", "TIMED_OUT", "ACTION_REQUIRED", "CANCELLED"].includes(c.conclusion)
355
+ );
356
+ const ownerRepo = failedChecks.length > 0 ? parseOwnerRepo() : null;
357
+ const checkOutputs = ownerRepo ? fetchCheckRunOutputs(ownerRepo, raw.headRefOid) : /* @__PURE__ */ new Map();
358
+ const checks = (raw.statusCheckRollup ?? []).map((c) => {
359
+ const enriched = checkOutputs.get(c.name);
360
+ return {
361
+ name: c.name,
362
+ status: c.status,
363
+ conclusion: c.conclusion,
364
+ description: enriched?.title || c.description || "",
365
+ detailsUrl: enriched?.detailsUrl || c.detailsUrl || ""
366
+ };
367
+ });
324
368
  return { number: raw.number, title: raw.title, state: raw.state, url: raw.url, checks };
325
369
  }
326
370
  function getPrInfo2(branch) {
@@ -374,7 +418,7 @@ function checkSymbol(check) {
374
418
  function formatCheckSummary(checks) {
375
419
  const running = checks.some((c) => c.status !== "COMPLETED");
376
420
  const failed = checks.filter((c) => c.conclusion !== null && FAIL_CONCLUSIONS.has(c.conclusion));
377
- const errors = failed.length === 0 ? "none" : failed.map((c) => `${c.name}: ${c.description.trim() || "no details available"}`).join("; ");
421
+ const errors = failed.length === 0 ? "none" : failed.map((c) => `${c.name}: ${c.description.trim() || c.detailsUrl || "no details available"}`).join("; ");
378
422
  return `Checks Running: ${String(running)}
379
423
  Check Errors: ${errors}
380
424
  `;
@@ -387,13 +431,32 @@ function formatChecks(checks) {
387
431
  const pending = check.status !== "COMPLETED" ? " (pending)" : "";
388
432
  lines.push(` ${sym} ${check.name}${pending}`);
389
433
  if (check.conclusion !== null && FAIL_CONCLUSIONS.has(check.conclusion)) {
390
- const detail = check.description.trim() || "(no details available)";
391
- lines.push(` Details: ${detail}`);
434
+ const desc = check.description.trim();
435
+ const url = check.detailsUrl.trim();
436
+ if (desc) lines.push(` Details: ${desc}`);
437
+ if (url) lines.push(` URL: ${url}`);
438
+ if (!desc && !url) lines.push(` Details: (no details available)`);
392
439
  }
393
440
  }
394
441
  return lines.join("\n") + "\n";
395
442
  }
396
- var getPrInfoCmd = new Command2("get-pr-info").description("Show pull request info for the current branch").option("--json", "Output as JSON").addHelpText(
443
+ function sleep(ms) {
444
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
445
+ }
446
+ function formatFailedChecks(failed) {
447
+ const lines = [];
448
+ for (const check of failed) {
449
+ lines.push(` \u2717 ${check.name}`);
450
+ const desc = check.description.trim();
451
+ const url = check.detailsUrl.trim();
452
+ if (desc) lines.push(` Details: ${desc}`);
453
+ if (url) lines.push(` URL: ${url}`);
454
+ if (!desc && !url) lines.push(` Details: (no details available)`);
455
+ }
456
+ return lines.join("\n") + "\n";
457
+ }
458
+ var POLL_INTERVAL_MS = 1e4;
459
+ var getPrInfoCmd = new Command2("get-pr-info").description("Show pull request info for the current branch").option("--json", "Output as JSON").option("--wait-finish-checks", "Poll until all checks complete, then report pass/fail (exit 1 on failure)").addHelpText(
397
460
  "after",
398
461
  `
399
462
  Check status symbols:
@@ -404,7 +467,7 @@ Check status symbols:
404
467
 
405
468
  Failure details are printed beneath each \u2717 check.
406
469
  See docs/git.md for full output reference.`
407
- ).action((options) => {
470
+ ).action(async (options) => {
408
471
  let branch;
409
472
  try {
410
473
  branch = getCurrentBranch();
@@ -413,6 +476,48 @@ See docs/git.md for full output reference.`
413
476
  `);
414
477
  process.exit(1);
415
478
  }
479
+ if (options.waitFinishChecks) {
480
+ let pr2;
481
+ while (true) {
482
+ try {
483
+ pr2 = getPrInfo2(branch);
484
+ } catch (err) {
485
+ process.stderr.write(`Error: ${err.message}
486
+ `);
487
+ process.exit(1);
488
+ }
489
+ if (pr2 === null) {
490
+ process.stderr.write(`Error: No pull request found for branch: ${branch}
491
+ `);
492
+ process.exit(1);
493
+ }
494
+ const running = pr2.checks.filter((c) => c.status !== "COMPLETED");
495
+ if (running.length === 0) break;
496
+ process.stdout.write(`Waiting for ${running.length} check(s) to complete...
497
+ `);
498
+ await sleep(POLL_INTERVAL_MS);
499
+ }
500
+ const failed = pr2.checks.filter((c) => c.conclusion !== null && FAIL_CONCLUSIONS.has(c.conclusion));
501
+ if (failed.length === 0) {
502
+ if (options.json) {
503
+ process.stdout.write(JSON.stringify({ result: "passed" }, null, 2) + "\n");
504
+ } else {
505
+ process.stdout.write(`All checks passed. \u2713
506
+ `);
507
+ }
508
+ process.exit(0);
509
+ } else {
510
+ if (options.json) {
511
+ process.stdout.write(JSON.stringify({ result: "failed", failed }, null, 2) + "\n");
512
+ } else {
513
+ process.stdout.write(`${failed.length} check(s) failed:
514
+ `);
515
+ process.stdout.write(formatFailedChecks(failed));
516
+ }
517
+ process.exit(1);
518
+ }
519
+ return;
520
+ }
416
521
  let pr;
417
522
  try {
418
523
  pr = getPrInfo2(branch);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "automata-cli",
3
- "version": "0.1.0-005-azdo-remote-support.27",
3
+ "version": "0.1.0-005-azdo-remote-support.29",
4
4
  "description": "Automata CLI tool",
5
5
  "type": "module",
6
6
  "bin": {