feat: add --type filter flag to issue list

Filter issues by type using the search API path. The --type flag
appends a type: qualifier to the search query, forcing the search
path (same as --label and --milestone).

Updated FilterOptions with IssueType field, IsDefault(), and
SearchQueryBuild() to include the type qualifier.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Kynan Ware 2026-03-29 16:48:23 -06:00
parent b7ee31d791
commit 67f63a1096
2 changed files with 19 additions and 2 deletions

View file

@ -37,6 +37,7 @@ type ListOptions struct {
Mention string
Milestone string
Search string
IssueType string
WebMode bool
Exporter cmdutil.Exporter
@ -77,6 +78,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
$ gh issue list --milestone "The big 1.0"
$ gh issue list --search "error no:assignee sort:created-asc"
$ gh issue list --state all
$ gh issue list --type Bug
`),
Aliases: []string{"ls"},
Args: cmdutil.NoArgsQuoteReminder,
@ -113,6 +115,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
cmd.Flags().StringVar(&opts.Mention, "mention", "", "Filter by mention")
cmd.Flags().StringVarP(&opts.Milestone, "milestone", "m", "", "Filter by milestone number or title")
cmd.Flags().StringVarP(&opts.Search, "search", "S", "", "Search issues with `query`")
cmd.Flags().StringVar(&opts.IssueType, "type", "", "Filter by issue type `name`")
cmdutil.AddJSONFlags(cmd, &opts.Exporter, api.IssueFields)
return cmd
@ -158,6 +161,7 @@ func listRun(opts *ListOptions) error {
Mention: opts.Mention,
Milestone: opts.Milestone,
Search: opts.Search,
IssueType: opts.IssueType,
Fields: fields,
}
@ -227,7 +231,7 @@ func listRun(opts *ListOptions) error {
func issueList(client *http.Client, detector fd.Detector, repo ghrepo.Interface, filters prShared.FilterOptions, limit int) (*api.IssuesAndTotalCount, error) {
apiClient := api.NewClientFromHTTP(client)
if filters.Search != "" || len(filters.Labels) > 0 || filters.Milestone != "" {
if filters.Search != "" || len(filters.Labels) > 0 || filters.Milestone != "" || filters.IssueType != "" {
if milestoneNumber, err := strconv.ParseInt(filters.Milestone, 10, 32); err == nil {
milestone, err := milestoneByNumber(client, repo, int32(milestoneNumber))
if err != nil {

View file

@ -176,6 +176,7 @@ type FilterOptions struct {
Entity string
Fields []string
HeadBranch string
IssueType string
Labels []string
Mention string
Milestone string
@ -212,6 +213,9 @@ func (opts *FilterOptions) IsDefault() bool {
if opts.Search != "" {
return false
}
if opts.IssueType != "" {
return false
}
return true
}
@ -236,6 +240,15 @@ func SearchQueryBuild(options FilterOptions, advancedIssueSearchSyntax bool) str
case "merged":
is = "merged"
}
searchTerms := options.Search
if options.IssueType != "" {
if searchTerms != "" {
searchTerms += " "
}
searchTerms += "type:" + options.IssueType
}
query := search.Query{
Qualifiers: search.Qualifiers{
Assignee: options.Assignee,
@ -251,7 +264,7 @@ func SearchQueryBuild(options FilterOptions, advancedIssueSearchSyntax bool) str
Is: []string{is},
Type: options.Entity,
},
ImmutableKeywords: options.Search,
ImmutableKeywords: searchTerms,
}
if !advancedIssueSearchSyntax {