🐛 Fix GitHub repo tree to show file contents instead of empty#4063
🐛 Fix GitHub repo tree to show file contents instead of empty#4063clubanderson merged 1 commit intomainfrom
Conversation
toggleNode for github source nodes was always calling /api/github/repos?hasMissionsDir=true regardless of whether the node is the root "My Repositories" or a child repo. Now distinguishes: - Root node (id=github): lists user's repos - Child repo node: lists repo contents via GitHub Contents API This was the root cause of "Empty" for watched GitHub repos. Signed-off-by: Andrew Anderson <andy@clubanderson.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
✅ Deploy Preview for kubestellarconsole ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hey @clubanderson — thanks for opening this PR!
This is an automated message. |
|
Thank you for your contribution! Your PR has been merged. Check out what's new:
Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey |
There was a problem hiding this comment.
Pull request overview
Fixes the Mission Explorer GitHub repo tree expansion so watched repository nodes fetch and display repository contents (mission-relevant files/directories) instead of listing repos again and showing “Empty”.
Changes:
- Updated
toggleNodeto distinguish the GitHub root node (id=github) from child repo nodes. - For child repo nodes, fetches repo contents via the GitHub Contents API proxy and filters to mission file extensions + directories.
| const repoPath = node.path | ||
| const { data: ghEntries } = await api.get<Array<{ name: string; path: string; type: string; size?: number }>>( | ||
| `/api/github/repos/${repoPath}/contents` |
There was a problem hiding this comment.
repoPath is taken from node.path and interpolated into /api/github/repos/${repoPath}/contents. Once a repo has been expanded, directory nodes will have node.path like owner/repo/someDir, which produces a proxy call to /repos/owner/repo/someDir/contents (not a valid GitHub Contents API route). Parse node.path into owner, repo, and an optional subPath, and call the Contents endpoint as /api/github/repos/${owner}/${repo}/contents/${subPath} (root should use an empty subPath with a trailing slash). Also consider applying the same fix to the similar GitHub directory listing code in selectNode.
| const repoPath = node.path | |
| const { data: ghEntries } = await api.get<Array<{ name: string; path: string; type: string; size?: number }>>( | |
| `/api/github/repos/${repoPath}/contents` | |
| const pathParts = node.path.split('/') | |
| const [owner, repo, ...subPathParts] = pathParts | |
| const subPath = subPathParts.join('/') | |
| const repoPath = `${owner}/${repo}` | |
| const contentsUrl = subPath | |
| ? `/api/github/repos/${owner}/${repo}/contents/${subPath}` | |
| : `/api/github/repos/${owner}/${repo}/contents/` | |
| const { data: ghEntries } = await api.get<Array<{ name: string; path: string; type: string; size?: number }>>( | |
| contentsUrl |
| if (nodeId === 'github') { | ||
| // Root "My Repositories" — list user's repos | ||
| const { data: repos } = await api.get<Array<{ name: string; full_name: string }>>( | ||
| '/api/github/repos?hasMissionsDir=true' |
There was a problem hiding this comment.
The root branch uses /api/github/repos?hasMissionsDir=true, but the backend GitHub proxy only allows /repos/, /rate_limit, /user, and /notifications (see pkg/api/handlers/github_proxy.go), so /api/github/repos (no trailing slash / no owner+repo) will be rejected with 403. Also, the root github node is initialized with loaded: true, so this fetch path is currently unreachable. Either remove this branch, or change the root node loading strategy and use a valid GitHub API endpoint (e.g. /api/github/user/repos) with client-side filtering.
| '/api/github/repos?hasMissionsDir=true' | |
| '/api/github/user/repos?hasMissionsDir=true' |
| children = (ghEntries || []) | ||
| .filter(e => e.type === 'dir' || isMissionFile(e.name)) | ||
| .map(e => ({ | ||
| id: `${nodeId}/${e.name}`, | ||
| name: e.name, | ||
| path: `${repoPath.split('/').slice(0, 2).join('/')}/${e.path}`, | ||
| type: (e.type === 'dir' ? 'directory' : 'file') as TreeNode['type'], | ||
| source: 'github' as const, | ||
| loaded: e.type !== 'dir', | ||
| description: e.size ? `${e.size} bytes` : undefined, | ||
| })) |
There was a problem hiding this comment.
MissionBrowser has unit tests, but the new GitHub tree expansion behavior isn’t covered. Add a test that triggers toggleNode on a watched GitHub repo node, verifies the correct contents API URL is requested, and asserts children are filtered to directories + isMissionFile matches (and that non-mission files are excluded).
🔄 Auto-Applying Copilot Code ReviewCopilot code review found 2 code suggestion(s) and 1 general comment(s). @copilot Please apply all of the following code review suggestions:
Also address these general comments:
Push all fixes in a single commit. Run Auto-generated by copilot-review-apply workflow. |
Summary
Root cause fix for "Empty" showing when expanding watched GitHub repos in the Mission Explorer.
toggleNodeforgithubsource nodes was always calling/api/github/repos?hasMissionsDir=true— this lists the user's repos, which is correct for the root "My Repositories" node but wrong for a child repo likesample-runbooks. Now distinguishes by node ID:id=github): lists user repos/api/github/repos/{owner}/{repo}/contentsvia the GitHub Contents API proxy, filtered to mission file extensionsTest plan
clubanderson/sample-runbooks→ expand → should show 9 files (YAML + MD)