RunWorkflowsOnGitHub runs multiple agentic workflows on GitHub Actions, optionally repeating a specified number of times
(ctx context.Context, workflowNames []string, opts RunOptions)
| 499 | |
| 500 | // RunWorkflowsOnGitHub runs multiple agentic workflows on GitHub Actions, optionally repeating a specified number of times |
| 501 | func RunWorkflowsOnGitHub(ctx context.Context, workflowNames []string, opts RunOptions) error { |
| 502 | if len(workflowNames) == 0 { |
| 503 | return errors.New("at least one workflow name or ID is required") |
| 504 | } |
| 505 | |
| 506 | // Check context cancellation at the start |
| 507 | select { |
| 508 | case <-ctx.Done(): |
| 509 | fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Operation cancelled")) |
| 510 | return ctx.Err() |
| 511 | default: |
| 512 | } |
| 513 | |
| 514 | // Validate all workflows exist and are runnable before starting |
| 515 | for _, workflowName := range workflowNames { |
| 516 | if workflowName == "" { |
| 517 | return errors.New("workflow name cannot be empty") |
| 518 | } |
| 519 | |
| 520 | // Validate workflow exists |
| 521 | if opts.RepoOverride != "" { |
| 522 | // For remote repositories, use remote validation |
| 523 | if err := validateRemoteWorkflow(workflowName, opts.RepoOverride, opts.Verbose); err != nil { |
| 524 | return fmt.Errorf("failed to validate remote workflow '%s': %w", workflowName, err) |
| 525 | } |
| 526 | } else { |
| 527 | // For local workflows, use existing local validation |
| 528 | workflowFile, err := resolveWorkflowFile(workflowName, opts.Verbose) |
| 529 | if err != nil { |
| 530 | // Return error directly without wrapping - it already contains formatted message with suggestions |
| 531 | return err |
| 532 | } |
| 533 | |
| 534 | runnable, err := IsRunnable(workflowFile) |
| 535 | if err != nil { |
| 536 | return fmt.Errorf("failed to check if workflow '%s' is runnable: %w", workflowName, err) |
| 537 | } |
| 538 | |
| 539 | if !runnable { |
| 540 | return fmt.Errorf("workflow '%s' cannot be run on GitHub Actions - it must have 'workflow_dispatch' trigger", workflowName) |
| 541 | } |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | // Function to run all workflows once |
| 546 | runAllWorkflows := func() error { |
| 547 | fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Running %d workflow(s)...", len(workflowNames)))) |
| 548 | |
| 549 | for i, workflowName := range workflowNames { |
| 550 | // Check for cancellation before each workflow |
| 551 | select { |
| 552 | case <-ctx.Done(): |
| 553 | fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Operation cancelled")) |
| 554 | return ctx.Err() |
| 555 | default: |
| 556 | } |
| 557 | |
| 558 | if len(workflowNames) > 1 { |