Skip to content

feat(ci): add step summary command#504

Merged
121watts merged 5 commits intomainfrom
watts/dep-4421-ci-step-summaries-cli
May 7, 2026
Merged

feat(ci): add step summary command#504
121watts merged 5 commits intomainfrom
watts/dep-4421-ci-step-summaries-cli

Conversation

@121watts
Copy link
Copy Markdown
Contributor

@121watts 121watts commented May 7, 2026

Summary

depot ci summary now gives humans and agents a direct way to read authored CI step summary markdown for one job or attempt. The command supports plain markdown for humans and structured JSON for automation, so scripts do not have to parse terminal text.

Details

  • Adds depot ci summary <attempt-id | job-id>.
  • Uses the single GetJobSummary API contract from depot/api#3648.
  • Resolves positional IDs as jobs first, then falls back to attempts when the job is not found.
  • Resolves job IDs to the current/latest attempt; human output writes that resolution note to stderr.
  • Adds --output json / -o json with IDs, statuses, has_summary, empty_reason, step_count, and markdown.
  • Keeps JSON stdout clean, including missing-ID error paths.
  • Shares CI text/json output validation helpers with depot ci metrics.
  • Keeps no-summary and no-attempt states as successful, machine-readable results.

The command intentionally does not add plural workflow/run summary discovery. It depends on the API contract in https://github.com/depot/api/pull/3648 being merged and deployed before it works against production.

Verification

  • make generate
  • go test ./pkg/api ./pkg/cmd/ci
  • go test ./...
  • go build -o ./depot ./cmd/depot
  • git diff --check
  • Independent ORC2 review: SHIP

Compound Engineering
Codex


Note

Medium Risk
Adds a new CLI surface and wires in a new CI RPC (GetJobSummary) including regenerated protobuf/connect code; risk is mainly around API compatibility and correctly resolving job vs attempt IDs and output formatting.

Overview
Adds a new depot ci summary command to fetch authored CI step summary markdown for a job or attempt, with optional --output json for automation and clean stdout/stderr behavior.

Introduces a new CI API wrapper CIGetJobSummary and plumbs a new GetJobSummary RPC through the protobuf and Connect client/server stubs. Also centralizes output validation (text vs json) in output.go and updates ci metrics to use the shared helpers.

Reviewed by Cursor Bugbot for commit 0802bb1. Bugbot is set up for automated code reviews on this repo. Configure here.

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 7, 2026

DEP-4421

DEP-4426

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Duplicated output helpers already exist in metrics.go
    • Consolidated validateOutputFormat and isJSONOutput into output.go, removing duplicate functions from summary.go and metrics.go.

Create PR

Or push these changes by commenting:

@cursor push 1198fe54fc
Preview (1198fe54fc)
diff --git a/pkg/cmd/ci/metrics.go b/pkg/cmd/ci/metrics.go
--- a/pkg/cmd/ci/metrics.go
+++ b/pkg/cmd/ci/metrics.go
@@ -38,7 +38,7 @@
   depot ci metrics --job job_123 --output json
   depot ci metrics --run run_123 --output json`,
 		RunE: func(cmd *cobra.Command, args []string) error {
-			if err := validateMetricsOutput(output); err != nil {
+			if err := validateOutputFormat(output); err != nil {
 				return err
 			}
 			if len(args) > 1 {
@@ -84,7 +84,7 @@
 					}
 					return fmt.Errorf("failed to get job metrics: %w", err)
 				}
-				if metricsOutputJSON(output) {
+				if isJSONOutput(output) {
 					return writeJSON(buildJobMetricsJSON(resp))
 				}
 				printJobMetrics(resp, orgFlag)
@@ -96,7 +96,7 @@
 					}
 					return fmt.Errorf("failed to get run metrics: %w", err)
 				}
-				if metricsOutputJSON(output) {
+				if isJSONOutput(output) {
 					return writeJSON(buildRunMetricsJSON(resp))
 				}
 				printRunMetrics(resp, orgFlag)
@@ -108,7 +108,7 @@
 					}
 					return fmt.Errorf("failed to get attempt metrics: %w", err)
 				}
-				if metricsOutputJSON(output) {
+				if isJSONOutput(output) {
 					return writeJSON(buildAttemptMetricsJSON(resp))
 				}
 				printAttemptMetrics(resp, orgFlag)
@@ -451,17 +451,6 @@
 	return ""
 }
 
-func validateMetricsOutput(output string) error {
-	if output == "" || output == "text" || output == "json" {
-		return nil
-	}
-	return fmt.Errorf("unsupported output %q (valid: text, json)", output)
-}
-
-func metricsOutputJSON(output string) bool {
-	return output == "json"
-}
-
 func countNonEmpty(values ...string) int {
 	count := 0
 	for _, value := range values {

diff --git a/pkg/cmd/ci/output.go b/pkg/cmd/ci/output.go
--- a/pkg/cmd/ci/output.go
+++ b/pkg/cmd/ci/output.go
@@ -2,6 +2,7 @@
 
 import (
 	"encoding/json"
+	"fmt"
 	"os"
 )
 
@@ -12,3 +13,17 @@
 	enc.SetIndent("", "  ")
 	return enc.Encode(v)
 }
+
+// validateOutputFormat validates that the output format is one of: "", "text", or "json".
+// Used by CI verbs that support --output flags.
+func validateOutputFormat(output string) error {
+	if output == "" || output == "text" || output == "json" {
+		return nil
+	}
+	return fmt.Errorf("unsupported output %q (valid: text, json)", output)
+}
+
+// isJSONOutput returns true if the output format is "json".
+func isJSONOutput(output string) bool {
+	return output == "json"
+}

diff --git a/pkg/cmd/ci/summary.go b/pkg/cmd/ci/summary.go
--- a/pkg/cmd/ci/summary.go
+++ b/pkg/cmd/ci/summary.go
@@ -33,7 +33,7 @@
   depot ci summary <job-id>
   depot ci summary <attempt-id> --output json`,
 		RunE: func(cmd *cobra.Command, args []string) error {
-			if err := validateSummaryOutput(output); err != nil {
+			if err := validateOutputFormat(output); err != nil {
 				return err
 			}
 			if len(args) == 0 {
@@ -60,7 +60,7 @@
 
 			resp, attemptErr := ciGetJobAttemptSummary(ctx, tokenVal, orgID, id)
 			if attemptErr == nil {
-				if summaryOutputJSON(output) {
+				if isJSONOutput(output) {
 					return writeJSON(buildSummaryJSON(resp))
 				}
 				return printSummaryResponse(cmd.OutOrStdout(), resp)
@@ -82,7 +82,7 @@
 				return fmt.Errorf("failed to get job summary: %w", jobErr)
 			}
 
-			if summaryOutputJSON(output) {
+			if isJSONOutput(output) {
 				return writeJSON(buildSummaryJSON(resp))
 			}
 
@@ -156,14 +156,3 @@
 		return "No CI step summary was produced."
 	}
 }
-
-func validateSummaryOutput(output string) error {
-	if output == "" || output == "text" || output == "json" {
-		return nil
-	}
-	return fmt.Errorf("unsupported output %q (valid: text, json)", output)
-}
-
-func summaryOutputJSON(output string) bool {
-	return output == "json"
-}

You can send follow-ups to the cloud agent here.

Comment thread pkg/cmd/ci/summary.go Outdated
Comment thread pkg/cmd/ci/summary.go Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: JSON mode emits non-JSON help text to stdout
    • Modified the code to return a structured error instead of calling cmd.Help() when --output json is set but no arguments are provided.

Create PR

Or push these changes by commenting:

@cursor push 730f9a8d6b
Preview (730f9a8d6b)
diff --git a/pkg/cmd/ci/summary.go b/pkg/cmd/ci/summary.go
--- a/pkg/cmd/ci/summary.go
+++ b/pkg/cmd/ci/summary.go
@@ -36,6 +36,9 @@
 				return err
 			}
 			if len(args) == 0 {
+				if outputIsJSON(output) {
+					return fmt.Errorf("expected exactly one attempt or job ID")
+				}
 				return cmd.Help()
 			}
 			if len(args) > 1 {

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 2488b57. Configure here.

Comment thread pkg/cmd/ci/summary.go
@121watts 121watts merged commit 3c4b4a7 into main May 7, 2026
10 checks passed
@121watts 121watts deleted the watts/dep-4421-ci-step-summaries-cli branch May 7, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants