Skip to content

feat(repositories): add type filter to list repos APIs#36891

Open
appleboy wants to merge 12 commits intogo-gitea:mainfrom
appleboy:feature/list-repos-type-filter
Open

feat(repositories): add type filter to list repos APIs#36891
appleboy wants to merge 12 commits intogo-gitea:mainfrom
appleboy:feature/list-repos-type-filter

Conversation

@appleboy
Copy link
Member

Summary

  • Add type query parameter (all | public | private) to three repo listing endpoints:
    • GET /user/repos — list authenticated user's repos
    • GET /users/{username}/repos — list a user's repos
    • GET /orgs/{org}/repos — list an org's repos
  • Introduce IsPrivate optional filter support in GetUserRepositories to handle explicit public/private queries
  • Return 422 Unprocessable Entity for invalid type values
  • Update Swagger documentation for all three endpoints
  • Extract shared parseRepoTypeFilter helper to avoid duplicating the switch logic

Changes

File Change
models/repo/repo_list.go GetUserRepositories: honour opts.IsPrivate when set, falling back to existing opts.Private behaviour
routers/api/v1/user/repo.go Add parseRepoTypeFilter helper; apply filter in listUserRepos and ListMyRepos
templates/swagger/v1_json.tmpl Document new type parameter and 422 response for all three endpoints
tests/integration/api_user_repos_test.go Integration tests covering public, private, all, no-filter, and invalid-type scenarios

Test plan

  • TestAPIListMyReposGET /user/repos
  • TestAPIListUserReposByTypeGET /users/{username}/repos
  • TestAPIListOrgReposByTypeGET /orgs/{org}/repos

All tests pass with make test-sqlite.

🤖 Generated with Claude Code

- Add support for filtering repositories by type query parameter with values all, public, or private across user, org, and self repo listing APIs
- Introduce an optional IsPrivate filter in repository search logic to explicitly handle public or private queries
- Return a 422 validation error for invalid type query values
- Update pagination handling to use list options consistently after refactoring search options
- Extend Swagger API documentation to describe the new type filter and validation error responses
- Add comprehensive integration tests covering public, private, all, no filter, and invalid type scenarios for all relevant endpoints

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Copilot AI review requested due to automatic review settings March 12, 2026 07:12
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Mar 12, 2026
@github-actions github-actions bot added modifies/api This PR adds API routes or modifies them modifies/go Pull requests that update Go code labels Mar 12, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a type query filter (all | public | private) to repository listing APIs and wires it through to the repository query layer, with Swagger and integration-test updates to match.

Changes:

  • Add type query parsing in API handlers and map it to SearchRepoOptions.IsPrivate.
  • Update GetUserRepositories to honor opts.IsPrivate when provided.
  • Extend Swagger docs and add integration tests for the new filter values and invalid input (422).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
models/repo/repo_list.go Applies IsPrivate as an explicit is_private condition when set.
routers/api/v1/user/repo.go Adds parseRepoTypeFilter helper and applies IsPrivate to list endpoints.
templates/swagger/v1_json.tmpl Documents type query parameter and 422 validation response for the three endpoints.
tests/integration/api_user_repos_test.go Adds integration tests covering public/private/all/no filter/invalid filter for the endpoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
appleboy and others added 6 commits March 12, 2026 15:33
…ount leaking

- Fix GetUserRepositories: Private=false (access gate) now takes precedence
  over IsPrivate, so unauthenticated callers cannot use type=private to
  query private repos regardless of the IsPrivate filter
- Short-circuit listUserRepos to empty result (total=0) when caller is
  unauthenticated and requests type=private, preventing X-Total-Count
  header from leaking private repo existence
- Add TypePrivateUnauthenticated test case to verify body is empty and
  X-Total-Count is 0 for unauthenticated type=private requests

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Per reviewer feedback (wxiaoguang, lunny): remove the dual Private bool /
IsPrivate optional.Option[bool] pattern in GetUserRepositories and use
only IsPrivate.

- GetUserRepositories: drop opts.Private gate, rely solely on opts.IsPrivate
  (None = no filter, Some(false) = public only, Some(true) = private only)
- listUserRepos: encode access-control into IsPrivate before calling the
  model layer — unauthenticated callers get Some(false); type=private from
  an unauthenticated caller short-circuits to an empty result with
  X-Total-Count: 0 so private repo existence is never leaked
- All other GetUserRepositories callers use Private: true (= want all repos)
  which maps cleanly to IsPrivate = None (zero value, no filter)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
GetUserRepositories no longer uses opts.Private to restrict results
to public repos by default. Callers that want public-only results
must now set opts.IsPrivate = Some(false) explicitly.

Update the test setup call to pass IsPrivate: optional.Some(false)
to preserve the original intent of the test.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ld in SearchRepoOptions

Remove the `Private bool` field from `SearchRepoOptions` and use only
`IsPrivate optional.Option[bool]` for controlling repository visibility
filtering. This eliminates the confusing overlap between the two fields.

Semantics:
- IsPrivate=None: include both public and private (with access control)
- IsPrivate=Some(true): include only private repos (with access control)
- IsPrivate=Some(false): include only public repos (no private/limited orgs)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added the modifies/cli PR changes something on the CLI, i.e. gitea doctor or gitea admin label Mar 13, 2026
appleboy and others added 2 commits March 13, 2026 23:28
Test cases named "Public*" previously relied on the default
Private=false to restrict results to public repos. With the
field removed, they need explicit IsPrivate=Some(false).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@appleboy
Copy link
Member Author

@lunny, please note that this feature must be included in the Enterprise version. Thank you.

@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Mar 14, 2026
@lunny lunny added this to the 1.26.0 milestone Mar 14, 2026
@appleboy
Copy link
Member Author

@wxiaoguang need your approval :)

@wxiaoguang
Copy link
Contributor

I don't have time to review. Can other maintainers help.

@appleboy appleboy requested a review from Zettat123 March 15, 2026 14:23
- Guard `is_private` query parameter so it only applies when the user is signed in and not in PublicOnly mode, preventing unauthenticated users from overriding the public-only visibility restriction

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 1 This PR needs approval from one additional maintainer to be merged. modifies/api This PR adds API routes or modifies them modifies/cli PR changes something on the CLI, i.e. gitea doctor or gitea admin modifies/go Pull requests that update Go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants