fetchRemoteWorkflow fetches a workflow file directly from GitHub using the API
(ctx context.Context, spec *WorkflowSpec, verbose bool)
| 86 | |
| 87 | // fetchRemoteWorkflow fetches a workflow file directly from GitHub using the API |
| 88 | func fetchRemoteWorkflow(ctx context.Context, spec *WorkflowSpec, verbose bool) (*FetchedWorkflow, error) { |
| 89 | remoteWorkflowLog.Printf("Fetching remote workflow: repo=%s, path=%s, version=%s", |
| 90 | spec.RepoSlug, spec.WorkflowPath, spec.Version) |
| 91 | |
| 92 | // Parse owner and repo from the slug |
| 93 | parts := strings.SplitN(spec.RepoSlug, "/", 2) |
| 94 | if len(parts) != 2 { |
| 95 | return nil, fmt.Errorf("invalid repository slug: %s", spec.RepoSlug) |
| 96 | } |
| 97 | owner := parts[0] |
| 98 | repo := parts[1] |
| 99 | |
| 100 | // Determine the ref to use |
| 101 | ref := spec.Version |
| 102 | if ref == "" { |
| 103 | ref = "main" // Default to main branch |
| 104 | remoteWorkflowLog.Print("No version specified, defaulting to 'main'") |
| 105 | } |
| 106 | |
| 107 | if verbose { |
| 108 | fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Fetching %s/%s/%s@%s...", owner, repo, spec.WorkflowPath, ref))) |
| 109 | } |
| 110 | |
| 111 | // Resolve the ref to a commit SHA for source tracking. |
| 112 | commitSHA, err := resolveCommitSHAWithRetries(ctx, owner, repo, ref, spec.WorkflowPath, spec.Host, verbose) |
| 113 | if err != nil { |
| 114 | return nil, err |
| 115 | } |
| 116 | if verbose { |
| 117 | fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Resolved to commit: "+commitSHA[:7])) |
| 118 | } |
| 119 | |
| 120 | // Download the workflow file from GitHub |
| 121 | content, err := downloadFileFromGitHubForHost(owner, repo, spec.WorkflowPath, ref, spec.Host) |
| 122 | if err != nil { |
| 123 | // Try with common workflow directory prefixes if the direct path fails. |
| 124 | // This handles short workflow names without path separators (e.g. "my-workflow.md"). |
| 125 | if !strings.HasPrefix(spec.WorkflowPath, "workflows/") && !strings.Contains(spec.WorkflowPath, "/") { |
| 126 | for _, prefix := range []string{"workflows/", constants.WorkflowsDirSlash} { |
| 127 | altPath := prefix + spec.WorkflowPath |
| 128 | if !strings.HasSuffix(altPath, ".md") { |
| 129 | altPath += ".md" |
| 130 | } |
| 131 | remoteWorkflowLog.Printf("Direct path failed, trying: %s", altPath) |
| 132 | if altContent, altErr := downloadFileFromGitHubForHost(owner, repo, altPath, ref, spec.Host); altErr == nil { |
| 133 | remoteWorkflowLog.Printf("Downloaded workflow via alt path: %s (%d bytes)", altPath, len(altContent)) |
| 134 | return &FetchedWorkflow{ |
| 135 | Content: altContent, |
| 136 | CommitSHA: commitSHA, |
| 137 | IsLocal: false, |
| 138 | SourcePath: altPath, |
| 139 | }, nil |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | return nil, fmt.Errorf("failed to download workflow from %s/%s/%s@%s: %w", owner, repo, spec.WorkflowPath, ref, err) |
| 144 | } |
| 145 |
no test coverage detected