MCPcopy Create free account
hub / github.com/github/gh-aw / ViewWorkflowRun

Function ViewWorkflowRun

pkg/cli/view_command.go:119–182  ·  view source on GitHub ↗

ViewWorkflowRun downloads artifacts for the given run (if not already cached) and renders the unified event timeline, safe outputs, and a link to the run page.

(ctx context.Context, runID int64, opts ViewOptions)

Source from the content-addressed store, hash-verified

117// ViewWorkflowRun downloads artifacts for the given run (if not already cached)
118// and renders the unified event timeline, safe outputs, and a link to the run page.
119func ViewWorkflowRun(ctx context.Context, runID int64, opts ViewOptions) error {
120 viewLog.Printf("Starting view for run %d (owner=%s, repo=%s, hostname=%s)", runID, opts.Owner, opts.Repo, opts.Hostname)
121
122 // Auto-detect GHES host from git remote when not explicitly provided.
123 hostname := opts.Hostname
124 if hostname == "" {
125 hostname = getHostFromOriginRemote()
126 if hostname != "github.com" {
127 viewLog.Printf("Auto-detected GHES host from git remote: %s", hostname)
128 }
129 }
130
131 runDir := filepath.Join(opts.OutputDir, fmt.Sprintf("run-%d", runID))
132 if absDir, err := filepath.Abs(runDir); err == nil {
133 runDir = absDir
134 }
135
136 if opts.Verbose {
137 fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Viewing run %d...", runID)))
138 fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Run directory: "+runDir))
139 }
140
141 // Download artifacts when the run directory does not yet contain the JSONL
142 // log files we need. We deliberately pass a nil artifact filter so that all
143 // artifacts are downloaded — the timeline relies on whichever JSONL files
144 // happen to be present; no single one is strictly required.
145 if err := downloadRunArtifacts(ctx, runID, runDir, opts.Verbose, opts.Owner, opts.Repo, hostname, nil); err != nil {
146 if !errors.Is(err, ErrNoArtifacts) {
147 return fmt.Errorf("failed to download artifacts for run %d: %w", runID, err)
148 }
149 // No artifacts is non-fatal: the run may still have useful events in the
150 // workflow logs or the directory may have been populated by a previous run.
151 if opts.Verbose {
152 fmt.Fprintln(os.Stderr, console.FormatWarningMessage("No artifacts attached to this run; timeline may be empty."))
153 }
154 }
155
156 // Collect and merge events from all available JSONL sources.
157 events, err := BuildUnifiedTimeline(runDir, opts.Verbose)
158 if err != nil {
159 return fmt.Errorf("failed to build timeline for run %d: %w", runID, err)
160 }
161
162 if len(events) == 0 {
163 fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("No timeline events found for run %d.", runID)))
164 fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Ensure the workflow has gateway.jsonl, audit.jsonl, or events.jsonl artifacts."))
165 } else {
166 output := renderUnifiedTimelineStream(events)
167 if output != "" {
168 fmt.Print(output)
169 }
170 }
171
172 // Render safe outputs if any were created during the run.
173 renderViewSafeOutputs(runDir)
174
175 // Finish with a link to the GitHub Actions run page.
176 runURL := buildRunHTMLURL(hostname, opts.Owner, opts.Repo, runID)

Calls 11

FormatInfoMessageFunction · 0.92
FormatWarningMessageFunction · 0.92
getHostFromOriginRemoteFunction · 0.85
downloadRunArtifactsFunction · 0.85
BuildUnifiedTimelineFunction · 0.85
renderViewSafeOutputsFunction · 0.85
buildRunHTMLURLFunction · 0.85
PrintMethod · 0.80
PrintfMethod · 0.45
ErrorfMethod · 0.45