Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
51b7653
feat(discussion/client): add discussion client package
babakks Jun 1, 2026
d3a1538
feat(discussion/shared): add shared utilities for discussion commands
babakks Jun 1, 2026
8b73951
feat(discussion list): add discussion list command
babakks Jun 1, 2026
57008e7
feat(discussion view): add discussion view command
babakks Jun 1, 2026
7bd67a8
feat(discussion create): add discussion create command
babakks Jun 1, 2026
797effe
feat(discussion edit): add discussion edit command
babakks Jun 1, 2026
dc5d7c1
fix(discussion): various polish and small fixes
babakks Jun 4, 2026
0d93148
refactor(discussion): extract command-level consts for enums
babakks Jun 4, 2026
97b2296
refactor(discussion list): make pager call/error consistent with view…
babakks Jun 4, 2026
dcd3507
docs(discussion/client): add godoc to exported consts
babakks Jun 4, 2026
d6a089d
chore(discussion/client): fix formatting
babakks Jun 4, 2026
b102900
fix(discussion): handle partial failure on create/update label mutations
babakks Jun 5, 2026
6dcb0b0
docs(discussion view): improve long help text for clarity
babakks Jun 5, 2026
fbd733e
refactor(discussion): add Cursor field and ExportData to DiscussionLi…
babakks Jun 5, 2026
e104885
refactor(discussion/client): precheck discussions enabled via getRepo…
babakks Jun 5, 2026
ca8e126
fix(discussion list): print "answered" instead of checkmark in non-tt…
babakks Jun 5, 2026
ada8583
test(discussion): add acceptance tests for discussion commands
babakks Jun 5, 2026
8ec0830
docs(acceptance): add new jq2env and jq-assert functions
babakks Jun 5, 2026
f147d02
test(discussion list): consolidate tests into table-driven format
babakks Jun 5, 2026
e61df07
Merge branch 'trunk' into feature/discussion
babakks Jun 5, 2026
c1f3c1a
fix(discussion): add missing repo flag override
babakks Jun 8, 2026
9d413e7
test(discussion list): rename TestNewCmdList2 to TestNewCmdList
babakks Jun 9, 2026
e2d150d
fix(discussion): remove redundant error wrapping on ListCategories
babakks Jun 9, 2026
95fc89c
chore(discussion): remove unused HttpClient field from create and edit
babakks Jun 9, 2026
4166ecf
chore: apply formatting
babakks Jun 9, 2026
2618999
feat(discussion/client): add comment manipulation methods
babakks Jun 6, 2026
6f5e114
feat(discussion): add discussion comment command
babakks Jun 8, 2026
82ac0d7
refactor(acceptance): use discussion comment command instead of raw A…
babakks Jun 8, 2026
2629753
test(acceptance): add discussion comment acceptance test
babakks Jun 8, 2026
61a4476
test(discussion comment): add non-tty delete flag validation test case
babakks Jun 8, 2026
d026f8f
feat(discussion): support comment URLs in --replies and comment command
babakks Jun 8, 2026
6394ca8
test(acceptance): cover discussion comment URLs in comment and view t…
babakks Jun 8, 2026
bc7ed48
chore: fix formatting
babakks Jun 8, 2026
55928c9
refactor(discussion view): replace --replies flag with positional com…
babakks Jun 10, 2026
8747c69
refactor(discussion/client): take host instead of repo in GetComment
babakks Jun 10, 2026
869c044
test(acceptance): use positional comment argument in discussion view …
babakks Jun 10, 2026
8d2b059
fix(discussion view): error when --comments is used with a comment ar…
babakks Jun 10, 2026
42db02d
Merge pull request #13620 from cli/babakks/add-discussion-comment
babakks Jun 10, 2026
27aabfa
fix(discussion view): use color scheme method for success icon
babakks Jun 10, 2026
951d76e
refactor(discussion list): simplify no-results message and use succes…
babakks Jun 10, 2026
9f2da11
fix(discussion view): show comments and replies in chronological order
babakks Jun 10, 2026
06d2e34
docs(discussion list): clarify answered examples refer to Q&A discuss…
babakks Jun 10, 2026
5d77247
fix(discussion view): print only requested items in non-tty output
babakks Jun 10, 2026
d63ab8d
fix(discussion/shared): error on out-of-range discussion number in URL
babakks Jun 10, 2026
5e6a58b
test(acceptance): fix discussion comment acceptance tests
babakks Jun 10, 2026
616d929
chore(discussion/client): rename client files
babakks Jun 10, 2026
69855b7
fix(discussion comment): fix bug in requiring body/body-file in add/e…
babakks Jun 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(discussion): add Cursor field and ExportData to DiscussionLi…
…stResult

Track the input pagination cursor on DiscussionListResult and add an
ExportData method that conditionally includes cursor/next fields.
Use ExportData in the list command instead of manually building the
JSON envelope.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Loading branch information
babakks and Copilot committed Jun 5, 2026
commit fbd733e3a255e8a22ed42f9c9405ccf311594940
8 changes: 6 additions & 2 deletions pkg/cmd/discussion/client/client_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ func (c *discussionClient) List(repo ghrepo.Interface, filters ListFilters, afte
variables["answered"] = githubv4.Boolean(*filters.Answered)
}

var result DiscussionListResult
result := DiscussionListResult{
Cursor: after,
}
remaining := limit

for {
Expand Down Expand Up @@ -326,7 +328,9 @@ func (c *discussionClient) Search(repo ghrepo.Interface, filters SearchFilters,
variables["after"] = githubv4.String(after)
}

var result DiscussionListResult
result := DiscussionListResult{
Cursor: after,
}
remaining := limit

for {
Expand Down
30 changes: 18 additions & 12 deletions pkg/cmd/discussion/client/client_impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func minimalNodes(count int) string {
}

// listResp builds a mock repository.discussions JSON response.
func listResp(hasNext bool, cursor string, total int, nodes string) string {
func listResp(hasNext bool, endCursor string, total int, nodes string) string {
return heredoc.Docf(`
{
"data": {
Expand All @@ -84,11 +84,11 @@ func listResp(hasNext bool, cursor string, total int, nodes string) string {
}
}
}
`, total, hasNext, cursor, nodes)
`, total, hasNext, endCursor, nodes)
}

// searchResp builds a mock search JSON response.
func searchResp(hasNext bool, cursor string, count int, nodes string) string {
func searchResp(hasNext bool, endCursor string, count int, nodes string) string {
return heredoc.Docf(`
{
"data": {
Expand All @@ -102,7 +102,7 @@ func searchResp(hasNext bool, cursor string, count int, nodes string) string {
}
}
}
`, count, hasNext, cursor, nodes)
`, count, hasNext, endCursor, nodes)
}

func TestList(t *testing.T) {
Expand Down Expand Up @@ -180,6 +180,7 @@ func TestList(t *testing.T) {
wantErr string
wantTotal int
wantLen int
wantNextCursor string
wantCursor string
wantTitles []string
wantSingleDisc *Discussion
Expand Down Expand Up @@ -291,6 +292,7 @@ func TestList(t *testing.T) {
}),
)
},
wantCursor: "someCursor",
},
{
name: "open state filter",
Expand Down Expand Up @@ -478,9 +480,9 @@ func TestList(t *testing.T) {
httpmock.StringResponse(listResp(true, "cursor42", 5, minimalNode("D1", "Discussion 1"))),
)
},
wantLen: 1,
wantTotal: 5,
wantCursor: "cursor42",
wantLen: 1,
wantTotal: 5,
wantNextCursor: "cursor42",
},
{
// Two pages are fetched when limit exceeds the first page's results.
Expand Down Expand Up @@ -537,7 +539,8 @@ func TestList(t *testing.T) {
require.NotNil(t, result)
assert.Equal(t, tt.wantTotal, result.TotalCount)
assert.Len(t, result.Discussions, tt.wantLen)
assert.Equal(t, tt.wantCursor, result.NextCursor)
assert.Equal(t, tt.wantCursor, result.Cursor)
assert.Equal(t, tt.wantNextCursor, result.NextCursor)

for i, title := range tt.wantTitles {
assert.Equal(t, title, result.Discussions[i].Title)
Expand Down Expand Up @@ -609,6 +612,7 @@ func TestSearch(t *testing.T) {
wantTotal int
wantLen int
wantCursor string
wantNextCursor string
wantTitles []string
wantSingleDisc *Discussion
}{
Expand Down Expand Up @@ -695,6 +699,7 @@ func TestSearch(t *testing.T) {
}),
)
},
wantCursor: "someCursor",
},
{
name: "open state filter",
Expand Down Expand Up @@ -860,9 +865,9 @@ func TestSearch(t *testing.T) {
httpmock.StringResponse(searchResp(true, "searchCursor42", 5, minimalNode("D1", "Discussion 1"))),
)
},
wantLen: 1,
wantTotal: 5,
wantCursor: "searchCursor42",
wantLen: 1,
wantTotal: 5,
wantNextCursor: "searchCursor42",
},
{
// Two pages are fetched when limit exceeds the first page's results.
Expand Down Expand Up @@ -919,7 +924,8 @@ func TestSearch(t *testing.T) {
require.NotNil(t, result)
assert.Equal(t, tt.wantTotal, result.TotalCount)
assert.Len(t, result.Discussions, tt.wantLen)
assert.Equal(t, tt.wantCursor, result.NextCursor)
assert.Equal(t, tt.wantCursor, result.Cursor)
assert.Equal(t, tt.wantNextCursor, result.NextCursor)

for i, title := range tt.wantTitles {
assert.Equal(t, title, result.Discussions[i].Title)
Expand Down
21 changes: 21 additions & 0 deletions pkg/cmd/discussion/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,30 @@ const (
type DiscussionListResult struct {
Discussions []Discussion
TotalCount int
Cursor string
NextCursor string
}

// ExportData returns a map suitable for JSON output, including pagination
// fields only when they are non-empty.
func (r DiscussionListResult) ExportData(fields []string) map[string]interface{} {
discussions := make([]interface{}, len(r.Discussions))
for i, d := range r.Discussions {
discussions[i] = d.ExportData(fields)
}
m := map[string]interface{}{
"totalCount": r.TotalCount,
"discussions": discussions,
}
if r.NextCursor != "" {
m["next"] = r.NextCursor
}
if r.Cursor != "" {
m["cursor"] = r.Cursor
}
return m
}

// ListFilters holds parameters for the repository.discussions query.
// CategoryID must be resolved by the caller before passing to List.
// A nil State indicates no state filtering (all states).
Expand Down
7 changes: 1 addition & 6 deletions pkg/cmd/discussion/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,7 @@ func listRun(opts *ListOptions) error {
}

if opts.Exporter != nil {
envelope := map[string]interface{}{
"totalCount": result.TotalCount,
"discussions": result.Discussions,
"next": result.NextCursor,
}
return opts.Exporter.Write(opts.IO, envelope)
return opts.Exporter.Write(opts.IO, result)
}

if len(result.Discussions) == 0 {
Expand Down