fetchGenericURLWorkflow fetches a workflow from an arbitrary HTTP(S) URL and dispatches on the response Content-Type to produce a FetchedWorkflow. Supported content types: - text/markdown, text/x-markdown → treated as raw gh-aw workflow markdown. - application/json (or any +json suffix) → treated a
(ctx context.Context, spec *WorkflowSpec, verbose bool)
| 298 | // Any other content type is an error with an actionable message. |
| 299 | // Warnings from JSON conversion are printed to stderr when verbose is true. |
| 300 | func fetchGenericURLWorkflow(ctx context.Context, spec *WorkflowSpec, verbose bool) (*FetchedWorkflow, error) { |
| 301 | remoteWorkflowLog.Printf("Fetching generic URL workflow") |
| 302 | |
| 303 | if verbose { |
| 304 | fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Fetching workflow from URL...")) |
| 305 | } |
| 306 | |
| 307 | resource, err := FetchImportURL(ctx, spec.RawURL, FetchOptions{}) |
| 308 | if err != nil { |
| 309 | return nil, err |
| 310 | } |
| 311 | |
| 312 | ct := resource.ContentType |
| 313 | remoteWorkflowLog.Printf("Fetched URL resource: content_type=%q bytes=%d", ct, len(resource.Body)) |
| 314 | |
| 315 | switch { |
| 316 | case ct == "text/markdown" || ct == "text/x-markdown": |
| 317 | remoteWorkflowLog.Printf("URL returned markdown content (%d bytes)", len(resource.Body)) |
| 318 | if verbose { |
| 319 | fmt.Fprintln(os.Stderr, console.FormatSuccessMessage(fmt.Sprintf("Downloaded workflow markdown (%d bytes)", len(resource.Body)))) |
| 320 | } |
| 321 | return &FetchedWorkflow{ |
| 322 | Content: resource.Body, |
| 323 | CommitSHA: "", |
| 324 | IsLocal: false, |
| 325 | SourcePath: spec.RawURL, |
| 326 | }, nil |
| 327 | |
| 328 | case ct == "application/json" || strings.HasSuffix(ct, "+json"): |
| 329 | remoteWorkflowLog.Printf("URL returned JSON content (%d bytes); converting", len(resource.Body)) |
| 330 | if verbose { |
| 331 | fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Downloaded JSON workflow (%d bytes); converting to markdown...", len(resource.Body)))) |
| 332 | } |
| 333 | |
| 334 | remoteWorkflowLog.Printf("JSON payload:\n%s", string(resource.Body)) |
| 335 | |
| 336 | var wf JSONWorkflow |
| 337 | if err := json.Unmarshal(resource.Body, &wf); err != nil { |
| 338 | return nil, fmt.Errorf("failed to parse JSON workflow from URL: %w", err) |
| 339 | } |
| 340 | |
| 341 | nameOverride := selectJSONImportNameOverride(spec.WorkflowName, &wf) |
| 342 | generated, err := ConvertJSONWorkflowToMarkdown(&wf, ConvertOptions{NameOverride: nameOverride}) |
| 343 | if err != nil { |
| 344 | return nil, fmt.Errorf("failed to convert JSON workflow: %w", err) |
| 345 | } |
| 346 | |
| 347 | remoteWorkflowLog.Printf("Converted JSON to markdown: filename=%s bytes=%d warnings=%d", |
| 348 | generated.Filename, len(generated.Markdown), len(generated.Warnings)) |
| 349 | |
| 350 | if verbose { |
| 351 | for _, w := range generated.Warnings { |
| 352 | fmt.Fprintln(os.Stderr, console.FormatWarningMessage("JSON workflow import: "+w)) |
| 353 | } |
| 354 | } |
| 355 | |
| 356 | // Use the generated filename as the WorkflowName on the spec so that |
| 357 | // downstream code (e.g. add_command.go) uses the correct file name. |
no test coverage detected