feat(github): add six read-only list actions#21412
Conversation
Add AI-optimized list actions that expose props previously only reachable
via async-options dropdowns (unusable through MCP):
- github-list-repository-labels
- github-list-repository-collaborators
- github-list-milestones
- github-list-projects
- github-list-project-statuses
- github-list-project-items
Supporting changes:
- getRepositoryMilestones: reorder so a caller-supplied `state` flows
through (still defaults to `open`), enabling open/closed/all filtering.
- Add static propDefinitions (projectOwnerStatic, projectRepoStatic,
projectNumberStatic) for the Projects (V2) discovery chain.
- Add hasNextPage to the Projects (V2) list queries; list-projects now
accepts a `cursor` prop and returns { projects, nextCursor } for
reliable pagination.
- Bump components/github to 3.1.0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds six GitHub listing actions for milestones, Projects V2 items/statuses/projects, collaborators, and labels. It also adds bounded pagination, Projects V2 page metadata, shared result-limit props, package version updates, and component metadata updates. ChangesGitHub listing actions
Estimated code review effort: 3 (Moderate) | ~30 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ed files The app file and common/queries.mjs changed in this branch, so every component that imports them gets a version bump per registry conventions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/github/actions/list-projects/list-projects.mjs`:
- Around line 78-89: Update the truncation logic before the summary in the
projects action so that when projects exceeds maxResults and is sliced,
nextCursor is cleared; preserve the cursor when no truncation occurs, ensuring
pagination cannot skip the discarded projects.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 128eb169-b353-4e86-8d24-7e8dabf71053
📒 Files selected for processing (9)
components/github/actions/list-milestones/list-milestones.mjscomponents/github/actions/list-project-items/list-project-items.mjscomponents/github/actions/list-project-statuses/list-project-statuses.mjscomponents/github/actions/list-projects/list-projects.mjscomponents/github/actions/list-repository-collaborators/list-repository-collaborators.mjscomponents/github/actions/list-repository-labels/list-repository-labels.mjscomponents/github/common/queries.mjscomponents/github/github.app.mjscomponents/github/package.json
When the final page overshoots maxResults, the extra items are sliced off but sat between the last returned project and nextCursor, so returning nextCursor would silently skip them on continuation. Clear nextCursor when truncation occurs; preserve it otherwise. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…/collaborators Address review feedback: - list-project-items: GitHub GraphQL rejects last/first > 100, so cap the maxResults prop (max: 100) and clamp `amount` in run(). Clarify the description that it returns the most recent items, up to 100. - getRepositoryLabels/getRepositoryCollaborators: paginate with early termination via a shared _paginateWithLimit helper so a bounded maxResults no longer pulls every page. When maxResults is omitted (propDefinition option loaders) all pages are still fetched — behavior preserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/github/actions/list-project-items/list-project-items.mjs`:
- Around line 52-54: Update the amount calculation in the list-project-items
request to handle an undefined maxResults value by applying a safe integer
fallback before capping it at 100. Preserve the existing maximum limit and
ensure the resulting GraphQL variable is always valid.
In `@components/github/github.app.mjs`:
- Around line 494-507: Update _paginateWithLimit so maxResults = 0 immediately
enforces the limit and returns an empty array instead of paginating all results.
Replace the truthiness checks in the loop condition and final slicing logic with
nullish checks, preserving unlimited pagination only when maxResults is
undefined.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: a5b51960-a9fa-4555-936c-ef9303f65643
📒 Files selected for processing (4)
components/github/actions/list-project-items/list-project-items.mjscomponents/github/actions/list-repository-collaborators/list-repository-collaborators.mjscomponents/github/actions/list-repository-labels/list-repository-labels.mjscomponents/github/github.app.mjs
Address review feedback on edge-case handling: - list-project-items: fall back to 100 before capping so an undefined maxResults no longer yields NaN in the GraphQL `amount` variable. - _paginateWithLimit: use nullish checks so maxResults=0 returns an empty array immediately instead of paginating every page and returning all rows; unlimited paging is preserved only when maxResults is undefined. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address review feedback: - list-milestones now paginates (via a generalized _paginateWithLimit that accepts query params) instead of a single per_page:100 request, so maxResults > 100 is reachable and behavior matches labels/collaborators. The milestoneNumber propDefinition (no maxResults) now fetches all pages. - list-projects: document that cursor continuation requires a Max Results that is a multiple of the 10-item page size; a mid-page value clears nextCursor on the final partial page. - list-project-items: description now states the item title is nested under fieldValueByName.text (not a flat title field) and drops the unwarranted "most recent items" ordering claim. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/github/actions/list-projects/list-projects.mjs (1)
42-96: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winHandle
undefinedfor the optionalmaxResultsprop.If
maxResultsis omitted and evaluates toundefined, the conditionprojects.length < maxResultswill evaluate tofalse(0 < undefinedis false). This bypasses the fetch loop entirely, causing the action to unexpectedly return an empty array instead of defaulting to a limit.Provide a safe integer fallback for
maxResultsto ensure it works properly when left undefined.🐛 Proposed fix
async run({ $ }) { const { github, owner: repoOwner, repo: repoName, maxResults, } = this; + const limit = maxResults ?? 100; let projects = []; let cursor = this.cursor ?? null; // The cursor to hand back so the caller can fetch the next page. Only set // when GitHub reports more results exist beyond what we return. let nextCursor = null; - while (projects.length < maxResults) { + while (projects.length < limit) { const { projects: batch, nextCursor: endCursor, hasNextPage, } = await github.getProjectsV2({ repoOwner, repoName, cursor, }); if (!batch?.length) { nextCursor = null; break; } projects = projects.concat(batch); nextCursor = hasNextPage ? endCursor : null; if (!hasNextPage) { break; } cursor = endCursor; } - if (projects.length > maxResults) { + if (projects.length > limit) { // The final page overshot maxResults. The discarded items sit between the // last returned project and nextCursor, so handing back nextCursor would // silently skip them. Clear it — better to stop than to skip results. - projects = projects.slice(0, maxResults); + projects = projects.slice(0, limit); nextCursor = null; } $.export("$summary", `Found ${projects.length} project(s) for ${repoName ? `${repoOwner}/${repoName}` : repoOwner}${nextCursor ? " (more available)" : ""}`); return { projects, nextCursor, }; },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/github/actions/list-projects/list-projects.mjs` around lines 42 - 96, Update the maxResults handling in run so an undefined value is replaced with the action’s safe integer default before the fetch loop and result-trimming logic use it. Preserve explicitly provided valid limits, and ensure the normalized value drives projects.length < maxResults.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@components/github/actions/list-projects/list-projects.mjs`:
- Around line 42-96: Update the maxResults handling in run so an undefined value
is replaced with the action’s safe integer default before the fetch loop and
result-trimming logic use it. Preserve explicitly provided valid limits, and
ensure the normalized value drives projects.length < maxResults.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 84b1e9ae-e3a9-4fb7-bcfe-fa85569591b2
📒 Files selected for processing (4)
components/github/actions/list-milestones/list-milestones.mjscomponents/github/actions/list-project-items/list-project-items.mjscomponents/github/actions/list-projects/list-projects.mjscomponents/github/github.app.mjs
- list-projects: default an undefined maxResults to 100 before the fetch loop, so `projects.length < maxResults` isn't false on the first iteration (which would skip the loop and return nothing). - list-project-items: document that the action returns at most 100 items with no pagination — a project with more than 100 items exposes only the last 100 (the tail of the connection), so earlier items aren't retrievable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| default: "open", | ||
| optional: true, | ||
| }, | ||
| maxResults: { |
There was a problem hiding this comment.
As per the api doc there is no maxResults prop. Only "per_page" prop is accepted in the query param.
Can you specify use case of the max results?
If so Centralize the shared maxResults prop.
The other new listing actions define the same input inline. Add a shared GitHub app propDefinition and reference it here; keep this action-specific max: 100 constraint in the shared definition if it applies to this API contract. As per coding guidelines, “Any prop used by more than one component must be defined in the app file's propDefinitions and referenced via propDefinition.”
There was a problem hiding this comment.
maxResults is passed to _paginateWithLimit() and used to limit the results.
| // caller-supplied `state` (spread via `...args`) overrides it; without | ||
| // one, GitHub defaults to `open`, which the `milestoneNumber` | ||
| // propDefinition relies on (it passes no maxResults, so all are fetched). | ||
| return this._paginateWithLimit(`GET /repos/${repoFullname}/milestones`, maxResults, { |
There was a problem hiding this comment.
As per the document below is the API needs to be used right?
https://docs.github.com/en/rest/issues/milestones?apiVersion=2026-03-10#list-milestones
/repos/{owner}/{repo}/milestones
There was a problem hiding this comment.
Correct. As the prop description shows, repoFullname consists of owner/repo.
The name of the repository (not case sensitive). The format should be
owner/repo(for example,PipedreamHQ/pipedream).
| async getRepositoryLabels({ | ||
| repoFullname, maxResults, | ||
| }) { | ||
| return this._paginateWithLimit(`GET /repos/${repoFullname}/labels`, maxResults); |
There was a problem hiding this comment.
As per the document below is the right API. Kindly check on it.
https://docs.github.com/en/rest/issues/labels?apiVersion=2026-03-10#list-labels-for-a-repository
/repos/{owner}/{repo}/labels
There was a problem hiding this comment.
Correct. repoFullName is "owner/repo".
| readOnlyHint: true, | ||
| }, | ||
| type: "action", | ||
| props: { |
There was a problem hiding this comment.
As per the API document Github Repo owner prop is required kindly check on it.
https://docs.github.com/en/rest/issues/labels?apiVersion=2026-03-10#list-labels-for-a-repository
Also update document link
There was a problem hiding this comment.
repoFullName is already required. Doc link is correct.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/github/actions/list-projects/list-projects.mjs`:
- Around line 57-65: Cap the `first` argument in the `github.getProjectsV2` call
within the project-listing pagination flow to 100, while still requesting no
more than the calculated `remaining` count. Preserve the existing pagination
behavior for requests where `remaining` is already within the API limit.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9bff1091-6fd1-4b26-abf7-7ac923070681
📒 Files selected for processing (14)
components/github/actions/list-branches/list-branches.mjscomponents/github/actions/list-commits/list-commits.mjscomponents/github/actions/list-milestones/list-milestones.mjscomponents/github/actions/list-project-items/list-project-items.mjscomponents/github/actions/list-project-statuses/list-project-statuses.mjscomponents/github/actions/list-projects/list-projects.mjscomponents/github/actions/list-repositories/list-repositories.mjscomponents/github/actions/list-repository-collaborators/list-repository-collaborators.mjscomponents/github/actions/list-repository-labels/list-repository-labels.mjscomponents/github/actions/list-workflow-runs/list-workflow-runs.mjscomponents/github/actions/list-workflows/list-workflows.mjscomponents/github/actions/search-issues-and-pull-requests/search-issues-and-pull-requests.mjscomponents/github/common/queries.mjscomponents/github/github.app.mjs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
What
Adds six AI-optimized, read-only GitHub list actions. These expose data that was previously only reachable through
async options()dropdowns on prop definitions — which are unusable via MCP / AI tool-calling — so there was no standalone action to retrieve them.New actions:
github-list-repository-labels— RESTGET /repos/{owner}/{repo}/labelsgithub-list-repository-collaborators— RESTGET /repos/{owner}/{repo}/collaboratorsgithub-list-milestones— RESTGET /repos/{owner}/{repo}/milestones(open/closed/all)github-list-projects— GraphQL, Projects (V2) for an org or repo, cursor-paginatedgithub-list-project-statuses— GraphQL, a Project (V2) Status field's optionsgithub-list-project-items— GraphQL, items in a Project (V2)Details
additionalProps/reloadProps/ async-options), so they resolve in a single MCP call. GitHub identifiers are human-readable, so dropdowns add no value.getRepositoryMilestones: reordered so a caller-suppliedstateflows through (still defaults toopen) — previously a hardcodedstate: "open"overrode the argument.propDefinitions(projectOwnerStatic,projectRepoStatic,projectNumberStatic) shared by the Projects (V2) actions.hasNextPageto the Projects (V2) list queries;list-projectsaccepts acursorprop and returns{ projects, nextCursor }(cursor set only when more results exist) for reliable pagination. Change is additive — the existingprojectV2async-options propDefinition is unaffected.components/githubto3.1.0.Testing
Exercised end-to-end via an MCP eval harness against a live GitHub account (labels/collaborators/milestones on a seeded repo; Projects V2 against a real org project with default statuses and items). All six actions pass, each with a single tool call.
Note: user-owned Projects (V2) are not supported — consistent with the existing GraphQL queries, which only cover the
organization(login:)andrepository(owner,name:)roots.🤖 Generated with Claude Code
Summary by CodeRabbit
hasNextPage).maxResults-limited fetching to relevant listing actions.