resolveRemoteSymlinks resolves symlinks in a remote GitHub repository path. The GitHub Contents API doesn't follow symlinks in path components. For example, if .github/workflows/shared is a symlink to ../../gh-agent-workflows/shared, fetching .github/workflows/shared/elastic-tools.md returns 404. Th
(client *api.RESTClient, owner, repo, filePath, ref string)
| 793 | // This function walks the path components and resolves any symlinks found. |
| 794 | // The caller must provide a REST client (already authenticated for the correct host). |
| 795 | func resolveRemoteSymlinks(client *api.RESTClient, owner, repo, filePath, ref string) (string, error) { |
| 796 | parts := strings.Split(filePath, "/") |
| 797 | if len(parts) <= 1 { |
| 798 | return "", fmt.Errorf("no directory components to resolve in path: %s", filePath) |
| 799 | } |
| 800 | |
| 801 | if client == nil { |
| 802 | return "", fmt.Errorf("no REST client available for symlink resolution of %s/%s/%s@%s", owner, repo, filePath, ref) |
| 803 | } |
| 804 | |
| 805 | remoteLog.Printf("Attempting symlink resolution for %s/%s/%s@%s (%d path components)", owner, repo, filePath, ref, len(parts)) |
| 806 | |
| 807 | for i := 1; i < len(parts); i++ { |
| 808 | dirPath := strings.Join(parts[:i], "/") |
| 809 | resolvedPath, found, err := resolveRemoteSymlinkComponent(client, owner, repo, filePath, ref, parts, i, dirPath) |
| 810 | if err != nil { |
| 811 | return "", err |
| 812 | } |
| 813 | if found { |
| 814 | return resolvedPath, nil |
| 815 | } |
| 816 | } |
| 817 | |
| 818 | remoteLog.Printf("No symlinks found after checking all %d directory components of %s", len(parts)-1, filePath) |
| 819 | return "", fmt.Errorf("no symlinks found in path: %s", filePath) |
| 820 | } |
| 821 | |
| 822 | func resolveRemoteSymlinkComponent( |
| 823 | client *api.RESTClient, |