FetchIncludeFromSource fetches an include file from GitHub directly using a workflowspec format path. The includePath should be in the format: owner/repo/path/to/file.md[@ref] If the includePath is a relative path, it's resolved relative to the baseSpec. Returns: (content, section, error) where sect
(includePath string, baseSpec *WorkflowSpec, verbose bool)
| 27 | // If the includePath is a relative path, it's resolved relative to the baseSpec. |
| 28 | // Returns: (content, section, error) where section is the #fragment from the path (e.g., "#section-name"). |
| 29 | func FetchIncludeFromSource(includePath string, baseSpec *WorkflowSpec, verbose bool) ([]byte, string, error) { |
| 30 | baseSpecStr := "<nil>" |
| 31 | if baseSpec != nil { |
| 32 | baseSpecStr = baseSpec.String() |
| 33 | } |
| 34 | remoteWorkflowLog.Printf("Fetching include from source: path=%s, base=%s", includePath, baseSpecStr) |
| 35 | |
| 36 | // Extract section reference (e.g., "#section-name") from the path upfront |
| 37 | // This ensures consistent behavior regardless of which code path is taken |
| 38 | cleanPath := includePath |
| 39 | var section string |
| 40 | if idx := strings.Index(includePath, "#"); idx != -1 { |
| 41 | cleanPath = includePath[:idx] |
| 42 | section = includePath[idx:] |
| 43 | } |
| 44 | |
| 45 | // Check if this is a workflowspec format (owner/repo/path[@ref]) |
| 46 | if isWorkflowSpecFormat(cleanPath) { |
| 47 | // Split on @ to get path and ref |
| 48 | parts := strings.SplitN(cleanPath, "@", 2) |
| 49 | pathPart := parts[0] |
| 50 | var ref string |
| 51 | if len(parts) == 2 { |
| 52 | ref = parts[1] |
| 53 | } else { |
| 54 | ref = "main" |
| 55 | } |
| 56 | |
| 57 | // Parse path: owner/repo/path/to/file.md |
| 58 | slashParts := strings.Split(pathPart, "/") |
| 59 | if len(slashParts) < 3 { |
| 60 | return nil, section, errors.New("invalid workflowspec: must be owner/repo/path[@ref]") |
| 61 | } |
| 62 | |
| 63 | owner := slashParts[0] |
| 64 | repo := slashParts[1] |
| 65 | filePath := strings.Join(slashParts[2:], "/") |
| 66 | |
| 67 | // Download the file |
| 68 | content, err := parser.DownloadFileFromGitHub(owner, repo, filePath, ref) |
| 69 | if err != nil { |
| 70 | return nil, section, fmt.Errorf("failed to fetch include from %s: %w", includePath, err) |
| 71 | } |
| 72 | |
| 73 | return content, section, nil |
| 74 | } |
| 75 | |
| 76 | // For relative paths, resolve against the base spec |
| 77 | if baseSpec != nil && baseSpec.RepoSlug != "" { |
| 78 | parts := strings.SplitN(baseSpec.RepoSlug, "/", 2) |
| 79 | if len(parts) == 2 { |
| 80 | owner := parts[0] |
| 81 | repo := parts[1] |
| 82 | ref := baseSpec.Version |
| 83 | if ref == "" { |
| 84 | ref = "main" |
| 85 | } |
| 86 |