2.0 KB72 lines
Blame
1import { spinner, log, note } from "@clack/prompts";
2import { hubRequest } from "../api.js";
3import { getRepoSlug } from "../config.js";
4import { STATUS_COLORS, STATUS_ICONS, RESET, formatDurationRange } from "../format.js";
5
6interface PipelineRun {
7 id: number;
8 pipeline_name: string;
9 status: string;
10 trigger_ref: string | null;
11 commit_id: string | null;
12 started_at: string | null;
13 finished_at: string | null;
14 duration_ms: number | null;
15}
16
17interface PipelineStep {
18 id: number;
19 name: string;
20 image: string;
21 status: string;
22 started_at: string | null;
23 finished_at: string | null;
24 step_index: number;
25}
26
27export async function ciStatus(args: string[]) {
28 const slug = await getRepoSlug(args);
29
30 // Find run ID: first positional arg that's a number
31 let runId = args.find((a) => !a.startsWith("--") && /^\d+$/.test(a));
32
33 if (!runId) {
34 // Get latest run
35 const s = spinner();
36 s.start("Fetching latest run");
37 const { runs } = await hubRequest<{ runs: any[] }>(
38 `/api/repos/${slug}/canopy/runs?limit=1`
39 );
40 if (runs.length === 0) {
41 s.stop("No runs found");
42 log.info("No pipeline runs.");
43 return;
44 }
45 runId = String(runs[0].id);
46 s.stop(`Run #${runId}`);
47 }
48
49 const s2 = spinner();
50 s2.start(`Fetching run #${runId}`);
51 const { run, steps } = await hubRequest<{ run: PipelineRun; steps: PipelineStep[] }>(
52 `/api/repos/${slug}/canopy/runs/${runId}`
53 );
54 s2.stop(`${run.pipeline_name}`);
55
56 // Header
57 const color = STATUS_COLORS[run.status] ?? "";
58 const headerLines = [
59 `Run #${run.id} ${color}${run.status}${RESET} branch: ${run.trigger_ref ?? "-"}`,
60 ];
61 if (run.commit_id) headerLines.push(`Commit: ${run.commit_id.slice(0, 12)}`);
62 note(headerLines.join("\n"), run.pipeline_name);
63
64 // Steps
65 for (const step of steps) {
66 const icon = STATUS_ICONS[step.status] ?? "?";
67 const dur = formatDurationRange(step.started_at, step.finished_at);
68 const durStr = dur ? ` (${dur})` : "";
69 log.message(`${icon} ${step.step_index}. ${step.name}${durStr}`);
70 }
71}
72