From b89249dadc4a0b422dacec654ebcc1650a235195 Mon Sep 17 00:00:00 2001 From: Andrew Barnes <169967362+Bortlesboat@users.noreply.github.com> Date: Thu, 6 Aug 2026 13:21:58 -0400 Subject: [PATCH 1/4] github: add stacked pull request endpoints --- github/github-accessors.go | 64 +++++++ github/github-accessors_test.go | 85 +++++++++ github/github-iterators.go | 31 ++++ github/github-iterators_test.go | 72 ++++++++ github/pulls.go | 22 ++- github/pulls_stacks.go | 143 +++++++++++++++ github/pulls_stacks_test.go | 314 ++++++++++++++++++++++++++++++++ 7 files changed, 725 insertions(+), 6 deletions(-) create mode 100644 github/pulls_stacks.go create mode 100644 github/pulls_stacks_test.go diff --git a/github/github-accessors.go b/github/github-accessors.go index ccefd992380..d2224e705a3 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -718,6 +718,14 @@ func (a *AddProjectV2FieldRequest) GetSingleSelectOptions() []*ProjectV2FieldSin return a.SingleSelectOptions } +// GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. +func (a *AddPullRequestsToStackRequest) GetPullRequests() []int { + if a == nil || a.PullRequests == nil { + return nil + } + return a.PullRequests +} + // GetMessage returns the Message field if it's non-nil, zero value otherwise. func (a *AddResourcesToCostCenterResponse) GetMessage() string { if a == nil || a.Message == nil { @@ -11670,6 +11678,14 @@ func (c *CreatePullRequest) GetTitle() string { return *c.Title } +// GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. +func (c *CreatePullRequestStackRequest) GetPullRequests() []int { + if c == nil || c.PullRequests == nil { + return nil + } + return c.PullRequests +} + // GetRef returns the Ref field. func (c *CreateRef) GetRef() string { if c == nil { @@ -31438,6 +31454,14 @@ func (p *PullRequestListOptions) GetState() string { return p.State } +// GetPullRequest returns the PullRequest field. +func (p *PullRequestListStacksOptions) GetPullRequest() int { + if p == nil { + return 0 + } + return p.PullRequest +} + // GetMerged returns the Merged field if it's non-nil, zero value otherwise. func (p *PullRequestMergeResult) GetMerged() bool { if p == nil || p.Merged == nil { @@ -32006,6 +32030,14 @@ func (p *PullRequestStack) GetBase() *PullRequestStackBase { return p.Base } +// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetCreatedAt() Timestamp { + if p == nil || p.CreatedAt == nil { + return Timestamp{} + } + return *p.CreatedAt +} + // GetID returns the ID field if it's non-nil, zero value otherwise. func (p *PullRequestStack) GetID() int64 { if p == nil || p.ID == nil { @@ -32014,6 +32046,14 @@ func (p *PullRequestStack) GetID() int64 { return *p.ID } +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetNodeID() string { + if p == nil || p.NodeID == nil { + return "" + } + return *p.NodeID +} + // GetNumber returns the Number field if it's non-nil, zero value otherwise. func (p *PullRequestStack) GetNumber() int { if p == nil || p.Number == nil { @@ -32022,6 +32062,14 @@ func (p *PullRequestStack) GetNumber() int { return *p.Number } +// GetOpen returns the Open field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetOpen() bool { + if p == nil || p.Open == nil { + return false + } + return *p.Open +} + // GetPosition returns the Position field if it's non-nil, zero value otherwise. func (p *PullRequestStack) GetPosition() int { if p == nil || p.Position == nil { @@ -32030,6 +32078,14 @@ func (p *PullRequestStack) GetPosition() int { return *p.Position } +// GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. +func (p *PullRequestStack) GetPullRequests() []*PullRequest { + if p == nil || p.PullRequests == nil { + return nil + } + return p.PullRequests +} + // GetSize returns the Size field if it's non-nil, zero value otherwise. func (p *PullRequestStack) GetSize() int { if p == nil || p.Size == nil { @@ -32038,6 +32094,14 @@ func (p *PullRequestStack) GetSize() int { return *p.Size } +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetURL() string { + if p == nil || p.URL == nil { + return "" + } + return *p.URL +} + // GetRef returns the Ref field. func (p *PullRequestStackBase) GetRef() string { if p == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 6ae6420e82b..7a9fdd7fe5b 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -908,6 +908,17 @@ func TestAddProjectV2FieldRequest_GetSingleSelectOptions(tt *testing.T) { a.GetSingleSelectOptions() } +func TestAddPullRequestsToStackRequest_GetPullRequests(tt *testing.T) { + tt.Parallel() + zeroValue := []int{} + a := &AddPullRequestsToStackRequest{PullRequests: zeroValue} + a.GetPullRequests() + a = &AddPullRequestsToStackRequest{} + a.GetPullRequests() + a = nil + a.GetPullRequests() +} + func TestAddResourcesToCostCenterResponse_GetMessage(tt *testing.T) { tt.Parallel() var zeroValue string @@ -14794,6 +14805,17 @@ func TestCreatePullRequest_GetTitle(tt *testing.T) { c.GetTitle() } +func TestCreatePullRequestStackRequest_GetPullRequests(tt *testing.T) { + tt.Parallel() + zeroValue := []int{} + c := &CreatePullRequestStackRequest{PullRequests: zeroValue} + c.GetPullRequests() + c = &CreatePullRequestStackRequest{} + c.GetPullRequests() + c = nil + c.GetPullRequests() +} + func TestCreateRef_GetRef(tt *testing.T) { tt.Parallel() c := &CreateRef{} @@ -39497,6 +39519,14 @@ func TestPullRequestListOptions_GetState(tt *testing.T) { p.GetState() } +func TestPullRequestListStacksOptions_GetPullRequest(tt *testing.T) { + tt.Parallel() + p := &PullRequestListStacksOptions{} + p.GetPullRequest() + p = nil + p.GetPullRequest() +} + func TestPullRequestMergeResult_GetMerged(tt *testing.T) { tt.Parallel() var zeroValue bool @@ -40146,6 +40176,17 @@ func TestPullRequestStack_GetBase(tt *testing.T) { p.GetBase() } +func TestPullRequestStack_GetCreatedAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + p := &PullRequestStack{CreatedAt: &zeroValue} + p.GetCreatedAt() + p = &PullRequestStack{} + p.GetCreatedAt() + p = nil + p.GetCreatedAt() +} + func TestPullRequestStack_GetID(tt *testing.T) { tt.Parallel() var zeroValue int64 @@ -40157,6 +40198,17 @@ func TestPullRequestStack_GetID(tt *testing.T) { p.GetID() } +func TestPullRequestStack_GetNodeID(tt *testing.T) { + tt.Parallel() + var zeroValue string + p := &PullRequestStack{NodeID: &zeroValue} + p.GetNodeID() + p = &PullRequestStack{} + p.GetNodeID() + p = nil + p.GetNodeID() +} + func TestPullRequestStack_GetNumber(tt *testing.T) { tt.Parallel() var zeroValue int @@ -40168,6 +40220,17 @@ func TestPullRequestStack_GetNumber(tt *testing.T) { p.GetNumber() } +func TestPullRequestStack_GetOpen(tt *testing.T) { + tt.Parallel() + var zeroValue bool + p := &PullRequestStack{Open: &zeroValue} + p.GetOpen() + p = &PullRequestStack{} + p.GetOpen() + p = nil + p.GetOpen() +} + func TestPullRequestStack_GetPosition(tt *testing.T) { tt.Parallel() var zeroValue int @@ -40179,6 +40242,17 @@ func TestPullRequestStack_GetPosition(tt *testing.T) { p.GetPosition() } +func TestPullRequestStack_GetPullRequests(tt *testing.T) { + tt.Parallel() + zeroValue := []*PullRequest{} + p := &PullRequestStack{PullRequests: zeroValue} + p.GetPullRequests() + p = &PullRequestStack{} + p.GetPullRequests() + p = nil + p.GetPullRequests() +} + func TestPullRequestStack_GetSize(tt *testing.T) { tt.Parallel() var zeroValue int @@ -40190,6 +40264,17 @@ func TestPullRequestStack_GetSize(tt *testing.T) { p.GetSize() } +func TestPullRequestStack_GetURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + p := &PullRequestStack{URL: &zeroValue} + p.GetURL() + p = &PullRequestStack{} + p.GetURL() + p = nil + p.GetURL() +} + func TestPullRequestStackBase_GetRef(tt *testing.T) { tt.Parallel() p := &PullRequestStackBase{} diff --git a/github/github-iterators.go b/github/github-iterators.go index 05120877ca5..ed78aa55ba3 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -5355,6 +5355,37 @@ func (s *PullRequestsService) ListReviewsIter(ctx context.Context, owner string, } } +// ListStacksIter returns an iterator that paginates through all results of ListStacks. +func (s *PullRequestsService) ListStacksIter(ctx context.Context, owner string, repo string, opts *PullRequestListStacksOptions) iter.Seq2[*PullRequestStack, error] { + return func(yield func(*PullRequestStack, error) bool) { + // Create a copy of opts to avoid mutating the caller's struct + if opts == nil { + opts = &PullRequestListStacksOptions{} + } else { + opts = Ptr(*opts) + } + + for { + results, resp, err := s.ListStacks(ctx, owner, repo, opts) + if err != nil { + yield(nil, err) + return + } + + for _, item := range results { + if !yield(item, nil) { + return + } + } + + if resp.NextPage == 0 { + break + } + opts.ListOptions.Page = resp.NextPage + } + } +} + // ListCommentReactionsIter returns an iterator that paginates through all results of ListCommentReactions. func (s *ReactionsService) ListCommentReactionsIter(ctx context.Context, owner string, repo string, id int64, opts *ListReactionOptions) iter.Seq2[*Reaction, error] { return func(yield func(*Reaction, error) bool) { diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index 75bc9f90c2b..7928777e627 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -11823,6 +11823,78 @@ func TestPullRequestsService_ListReviewsIter(t *testing.T) { } } +func TestPullRequestsService_ListStacksIter(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + var callNum int + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + callNum++ + switch callNum { + case 1: + w.Header().Set("Link", `; rel="next"`) + fmt.Fprint(w, `[{},{},{}]`) + case 2: + fmt.Fprint(w, `[{},{},{},{}]`) + case 3: + fmt.Fprint(w, `[{},{}]`) + case 4: + w.WriteHeader(http.StatusNotFound) + case 5: + fmt.Fprint(w, `[{},{}]`) + } + }) + + iter := client.PullRequests.ListStacksIter(t.Context(), "", "", nil) + var gotItems int + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 7; gotItems != want { + t.Errorf("client.PullRequests.ListStacksIter call 1 got %v items; want %v", gotItems, want) + } + + opts := &PullRequestListStacksOptions{} + iter = client.PullRequests.ListStacksIter(t.Context(), "", "", opts) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 2; gotItems != want { + t.Errorf("client.PullRequests.ListStacksIter call 2 got %v items; want %v", gotItems, want) + } + + iter = client.PullRequests.ListStacksIter(t.Context(), "", "", nil) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err == nil { + t.Error("expected error; got nil") + } + } + if gotItems != 1 { + t.Errorf("client.PullRequests.ListStacksIter call 3 got %v items; want 1 (an error)", gotItems) + } + + iter = client.PullRequests.ListStacksIter(t.Context(), "", "", nil) + gotItems = 0 + iter(func(item *PullRequestStack, err error) bool { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + return false + }) + if gotItems != 1 { + t.Errorf("client.PullRequests.ListStacksIter call 4 got %v items; want 1 (an error)", gotItems) + } +} + func TestReactionsService_ListCommentReactionsIter(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/pulls.go b/github/pulls.go index 81bc9f89535..b35ccc720e7 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -124,10 +124,10 @@ type PullRequestBranch struct { User *User `json:"user,omitempty"` } -// PullRequestStack represents the stack a pull request belongs to, in -// repositories that use stacked pull requests. Base reports the branch the -// entire stack ultimately targets, which can differ from the pull request's own -// Base branch (the branch below it in the stack). +// PullRequestStack represents a stack of pull requests. When embedded in a +// PullRequest, Base reports the branch the entire stack ultimately targets, +// which can differ from the pull request's own Base branch (the branch below it +// in the stack), and Position reports that pull request's place in the stack. type PullRequestStack struct { // Base is the base of the stack: the branch the entire stack ultimately targets. Base *PullRequestStackBase `json:"base"` @@ -136,10 +136,20 @@ type PullRequestStack struct { // Position is the one-based position of this pull request within the stack, // where 1 is the bottom of the stack. Position *int `json:"position,omitempty"` - // ID is the ID of the stack that this pull request belongs to. + // ID is the ID of the stack. ID *int64 `json:"id,omitempty"` - // Number is the number of the stack that this pull request belongs to. + // Number is the number of the stack. Number *int `json:"number,omitempty"` + // NodeID is the global node ID of the stack. + NodeID *string `json:"node_id,omitempty"` + // URL is the API URL of the stack. + URL *string `json:"url,omitempty"` + // Open reports whether the stack contains any open pull requests. + Open *bool `json:"open,omitempty"` + // CreatedAt is the time the stack was created. + CreatedAt *Timestamp `json:"created_at,omitempty"` + // PullRequests contains the pull requests in the stack, from bottom to top. + PullRequests []*PullRequest `json:"pull_requests,omitempty"` } // PullRequestStackBase represents the base of a stacked pull request's stack: diff --git a/github/pulls_stacks.go b/github/pulls_stacks.go new file mode 100644 index 00000000000..09a7d668e2b --- /dev/null +++ b/github/pulls_stacks.go @@ -0,0 +1,143 @@ +// Copyright 2026 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// PullRequestListStacksOptions specifies the optional parameters to the +// PullRequestsService.ListStacks method. +type PullRequestListStacksOptions struct { + // PullRequest filters stacks to the stack containing this pull request number. + PullRequest int `url:"pull_request,omitempty"` + + ListOptions +} + +// CreatePullRequestStackRequest represents a request to create a pull request stack. +type CreatePullRequestStackRequest struct { + // PullRequests is an ordered list of pull request numbers from the bottom of the stack to the top. + PullRequests []int `json:"pull_requests"` +} + +// AddPullRequestsToStackRequest represents a request to append pull requests to a stack. +type AddPullRequestsToStackRequest struct { + // PullRequests is an ordered list of pull request numbers to append from the current top upward. + PullRequests []int `json:"pull_requests"` +} + +// ListStacks lists pull request stacks in a repository. +// +// GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#list-pull-request-stacks +// +//meta:operation GET /repos/{owner}/{repo}/stacks +func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string, opts *PullRequestListStacksOptions) ([]*PullRequestStack, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/stacks", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + var stacks []*PullRequestStack + resp, err := s.client.Do(req, &stacks) + if err != nil { + return nil, resp, err + } + + return stacks, resp, nil +} + +// CreateStack creates a pull request stack from an ordered list of pull request numbers. +// +// GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#create-a-pull-request-stack +// +//meta:operation POST /repos/{owner}/{repo}/stacks +func (s *PullRequestsService) CreateStack(ctx context.Context, owner, repo string, body CreatePullRequestStackRequest) (*PullRequestStack, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/stacks", owner, repo) + req, err := s.client.NewRequest(ctx, "POST", u, body) + if err != nil { + return nil, nil, err + } + + var stack *PullRequestStack + resp, err := s.client.Do(req, &stack) + if err != nil { + return nil, resp, err + } + + return stack, resp, nil +} + +// GetStack gets a pull request stack by its stack number. +// +// GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#get-a-pull-request-stack +// +//meta:operation GET /repos/{owner}/{repo}/stacks/{stack_number} +func (s *PullRequestsService) GetStack(ctx context.Context, owner, repo string, stackNumber int) (*PullRequestStack, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/stacks/%v", owner, repo, stackNumber) + req, err := s.client.NewRequest(ctx, "GET", u, nil) + if err != nil { + return nil, nil, err + } + + var stack *PullRequestStack + resp, err := s.client.Do(req, &stack) + if err != nil { + return nil, resp, err + } + + return stack, resp, nil +} + +// AddToStack appends pull requests to a pull request stack. +// +// GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#add-pull-requests-to-a-pull-request-stack +// +//meta:operation POST /repos/{owner}/{repo}/stacks/{stack_number}/add +func (s *PullRequestsService) AddToStack(ctx context.Context, owner, repo string, stackNumber int, body AddPullRequestsToStackRequest) (*PullRequestStack, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/stacks/%v/add", owner, repo, stackNumber) + req, err := s.client.NewRequest(ctx, "POST", u, body) + if err != nil { + return nil, nil, err + } + + var stack *PullRequestStack + resp, err := s.client.Do(req, &stack) + if err != nil { + return nil, resp, err + } + + return stack, resp, nil +} + +// Unstack removes the unmerged pull requests from a pull request stack. It +// returns nil when no pull requests remain and the stack is dissolved. +// +// GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#remove-pull-requests-from-a-pull-request-stack +// +//meta:operation POST /repos/{owner}/{repo}/stacks/{stack_number}/unstack +func (s *PullRequestsService) Unstack(ctx context.Context, owner, repo string, stackNumber int) (*PullRequestStack, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/stacks/%v/unstack", owner, repo, stackNumber) + req, err := s.client.NewRequest(ctx, "POST", u, nil) + if err != nil { + return nil, nil, err + } + + var stack *PullRequestStack + resp, err := s.client.Do(req, &stack) + if err != nil { + return nil, resp, err + } + + return stack, resp, nil +} diff --git a/github/pulls_stacks_test.go b/github/pulls_stacks_test.go new file mode 100644 index 00000000000..d4f0358374f --- /dev/null +++ b/github/pulls_stacks_test.go @@ -0,0 +1,314 @@ +// Copyright 2026 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func testPullRequestStackResponse() string { + return `{ + "id":1, + "number":42, + "node_id":"S_kwDOABCDEF4AAAAA", + "url":"https://api.github.com/repos/o/r/stacks/42", + "base":{"ref":"main"}, + "open":true, + "created_at":` + referenceTimeStr + `, + "pull_requests":[{ + "number":101, + "state":"open", + "draft":false, + "merged_at":null, + "head":{"ref":"feature","sha":"abc123"} + }] + }` +} + +func testPullRequestStack() *PullRequestStack { + return &PullRequestStack{ + ID: Ptr(int64(1)), + Number: Ptr(42), + NodeID: Ptr("S_kwDOABCDEF4AAAAA"), + URL: Ptr("https://api.github.com/repos/o/r/stacks/42"), + Base: &PullRequestStackBase{Ref: "main"}, + Open: Ptr(true), + CreatedAt: &referenceTimestamp, + PullRequests: []*PullRequest{{ + Number: Ptr(101), + State: Ptr("open"), + Draft: Ptr(false), + Head: &PullRequestBranch{ + Ref: Ptr("feature"), + SHA: Ptr("abc123"), + }, + }}, + } +} + +func TestPullRequestsService_ListStacks(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/stacks", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "pull_request": "101", + "page": "2", + "per_page": "50", + }) + fmt.Fprintf(w, "[%s]", testPullRequestStackResponse()) + }) + + opts := &PullRequestListStacksOptions{ + PullRequest: 101, + ListOptions: ListOptions{Page: 2, PerPage: 50}, + } + ctx := t.Context() + stacks, _, err := client.PullRequests.ListStacks(ctx, "o", "r", opts) + if err != nil { + t.Errorf("PullRequests.ListStacks returned error: %v", err) + } + + want := []*PullRequestStack{testPullRequestStack()} + if !cmp.Equal(stacks, want) { + t.Errorf("PullRequests.ListStacks returned %+v, want %+v", stacks, want) + } + + const methodName = "ListStacks" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.PullRequests.ListStacks(ctx, "\n", "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.PullRequests.ListStacks(ctx, "o", "r", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestPullRequestsService_ListStacks_invalidOwner(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + _, _, err := client.PullRequests.ListStacks(t.Context(), "%", "%", nil) + testURLParseError(t, err) +} + +func TestPullRequestsService_CreateStack(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + input := CreatePullRequestStackRequest{PullRequests: []int{101, 102}} + + mux.HandleFunc("/repos/o/r/stacks", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testJSONBody(t, r, input) + w.WriteHeader(http.StatusCreated) + fmt.Fprint(w, testPullRequestStackResponse()) + }) + + ctx := t.Context() + stack, _, err := client.PullRequests.CreateStack(ctx, "o", "r", input) + if err != nil { + t.Errorf("PullRequests.CreateStack returned error: %v", err) + } + if want := testPullRequestStack(); !cmp.Equal(stack, want) { + t.Errorf("PullRequests.CreateStack returned %+v, want %+v", stack, want) + } + + const methodName = "CreateStack" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.PullRequests.CreateStack(ctx, "\n", "\n", input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.PullRequests.CreateStack(ctx, "o", "r", input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestPullRequestsService_CreateStack_invalidOwner(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + _, _, err := client.PullRequests.CreateStack(t.Context(), "%", "%", CreatePullRequestStackRequest{}) + testURLParseError(t, err) +} + +func TestPullRequestsService_GetStack(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/stacks/42", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, testPullRequestStackResponse()) + }) + + ctx := t.Context() + stack, _, err := client.PullRequests.GetStack(ctx, "o", "r", 42) + if err != nil { + t.Errorf("PullRequests.GetStack returned error: %v", err) + } + if want := testPullRequestStack(); !cmp.Equal(stack, want) { + t.Errorf("PullRequests.GetStack returned %+v, want %+v", stack, want) + } + + const methodName = "GetStack" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.PullRequests.GetStack(ctx, "\n", "\n", 42) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.PullRequests.GetStack(ctx, "o", "r", 42) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestPullRequestsService_GetStack_invalidOwner(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + _, _, err := client.PullRequests.GetStack(t.Context(), "%", "%", 42) + testURLParseError(t, err) +} + +func TestPullRequestsService_AddToStack(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + input := AddPullRequestsToStackRequest{PullRequests: []int{103, 104}} + + mux.HandleFunc("/repos/o/r/stacks/42/add", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testJSONBody(t, r, input) + fmt.Fprint(w, testPullRequestStackResponse()) + }) + + ctx := t.Context() + stack, _, err := client.PullRequests.AddToStack(ctx, "o", "r", 42, input) + if err != nil { + t.Errorf("PullRequests.AddToStack returned error: %v", err) + } + if want := testPullRequestStack(); !cmp.Equal(stack, want) { + t.Errorf("PullRequests.AddToStack returned %+v, want %+v", stack, want) + } + + const methodName = "AddToStack" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.PullRequests.AddToStack(ctx, "\n", "\n", 42, input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.PullRequests.AddToStack(ctx, "o", "r", 42, input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestPullRequestsService_AddToStack_invalidOwner(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + _, _, err := client.PullRequests.AddToStack(t.Context(), "%", "%", 42, AddPullRequestsToStackRequest{}) + testURLParseError(t, err) +} + +func TestPullRequestsService_Unstack(t *testing.T) { + t.Parallel() + + t.Run("returns updated stack", func(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + mux.HandleFunc("/repos/o/r/stacks/42/unstack", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, testPullRequestStackResponse()) + }) + + stack, _, err := client.PullRequests.Unstack(t.Context(), "o", "r", 42) + if err != nil { + t.Errorf("PullRequests.Unstack returned error: %v", err) + } + if want := testPullRequestStack(); !cmp.Equal(stack, want) { + t.Errorf("PullRequests.Unstack returned %+v, want %+v", stack, want) + } + }) + + t.Run("returns nil when stack is dissolved", func(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + mux.HandleFunc("/repos/o/r/stacks/42/unstack", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + w.WriteHeader(http.StatusNoContent) + }) + + stack, resp, err := client.PullRequests.Unstack(t.Context(), "o", "r", 42) + if err != nil { + t.Errorf("PullRequests.Unstack returned error: %v", err) + } + if stack != nil { + t.Errorf("PullRequests.Unstack returned %+v, want nil", stack) + } + if resp.StatusCode != http.StatusNoContent { + t.Errorf("PullRequests.Unstack returned status %v, want %v", resp.StatusCode, http.StatusNoContent) + } + }) + + client, _, _ := setup(t) + ctx := t.Context() + const methodName = "Unstack" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.PullRequests.Unstack(ctx, "\n", "\n", 42) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.PullRequests.Unstack(ctx, "o", "r", 42) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestPullRequestsService_Unstack_invalidOwner(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + _, _, err := client.PullRequests.Unstack(t.Context(), "%", "%", 42) + testURLParseError(t, err) +} + +func TestPullRequestStack_unmarshal(t *testing.T) { + t.Parallel() + testJSONUnmarshalOnly(t, testPullRequestStack(), testPullRequestStackResponse()) +} + +func TestCreatePullRequestStackRequest_marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &CreatePullRequestStackRequest{PullRequests: []int{101, 102}}, `{"pull_requests":[101,102]}`) +} + +func TestAddPullRequestsToStackRequest_marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &AddPullRequestsToStackRequest{PullRequests: []int{103}}, `{"pull_requests":[103]}`) +} From 295dd70a878e78fe4063cdd198cc71babf30739c Mon Sep 17 00:00:00 2001 From: Bortlesboat <169967362+Bortlesboat@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:13:19 -0400 Subject: [PATCH 2/4] Split pull request stack response types --- github/github-accessors.go | 102 ++++++++++++++--------- github/github-accessors_test.go | 140 +++++++++++++++++++------------- github/github-iterators.go | 4 +- github/github-iterators_test.go | 2 +- github/pulls.go | 22 ++--- github/pulls_stacks.go | 41 +++++++--- github/pulls_stacks_test.go | 31 ++----- 7 files changed, 196 insertions(+), 146 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index d2224e705a3..786c25af31a 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -32030,8 +32030,64 @@ func (p *PullRequestStack) GetBase() *PullRequestStackBase { return p.Base } +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetID() int64 { + if p == nil || p.ID == nil { + return 0 + } + return *p.ID +} + +// GetNumber returns the Number field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetNumber() int { + if p == nil || p.Number == nil { + return 0 + } + return *p.Number +} + +// GetPosition returns the Position field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetPosition() int { + if p == nil || p.Position == nil { + return 0 + } + return *p.Position +} + +// GetSize returns the Size field if it's non-nil, zero value otherwise. +func (p *PullRequestStack) GetSize() int { + if p == nil || p.Size == nil { + return 0 + } + return *p.Size +} + +// GetRef returns the Ref field. +func (p *PullRequestStackBase) GetRef() string { + if p == nil { + return "" + } + return p.Ref +} + +// GetSHA returns the SHA field. +func (p *PullRequestStackBase) GetSHA() string { + if p == nil { + return "" + } + return p.SHA +} + +// GetBase returns the Base field. +func (p *PullRequestStackDetails) GetBase() *PullRequestStackBase { + if p == nil { + return nil + } + return p.Base +} + // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetCreatedAt() Timestamp { +func (p *PullRequestStackDetails) GetCreatedAt() Timestamp { if p == nil || p.CreatedAt == nil { return Timestamp{} } @@ -32039,7 +32095,7 @@ func (p *PullRequestStack) GetCreatedAt() Timestamp { } // GetID returns the ID field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetID() int64 { +func (p *PullRequestStackDetails) GetID() int64 { if p == nil || p.ID == nil { return 0 } @@ -32047,7 +32103,7 @@ func (p *PullRequestStack) GetID() int64 { } // GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetNodeID() string { +func (p *PullRequestStackDetails) GetNodeID() string { if p == nil || p.NodeID == nil { return "" } @@ -32055,7 +32111,7 @@ func (p *PullRequestStack) GetNodeID() string { } // GetNumber returns the Number field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetNumber() int { +func (p *PullRequestStackDetails) GetNumber() int { if p == nil || p.Number == nil { return 0 } @@ -32063,61 +32119,29 @@ func (p *PullRequestStack) GetNumber() int { } // GetOpen returns the Open field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetOpen() bool { +func (p *PullRequestStackDetails) GetOpen() bool { if p == nil || p.Open == nil { return false } return *p.Open } -// GetPosition returns the Position field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetPosition() int { - if p == nil || p.Position == nil { - return 0 - } - return *p.Position -} - // GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. -func (p *PullRequestStack) GetPullRequests() []*PullRequest { +func (p *PullRequestStackDetails) GetPullRequests() []*PullRequest { if p == nil || p.PullRequests == nil { return nil } return p.PullRequests } -// GetSize returns the Size field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetSize() int { - if p == nil || p.Size == nil { - return 0 - } - return *p.Size -} - // GetURL returns the URL field if it's non-nil, zero value otherwise. -func (p *PullRequestStack) GetURL() string { +func (p *PullRequestStackDetails) GetURL() string { if p == nil || p.URL == nil { return "" } return *p.URL } -// GetRef returns the Ref field. -func (p *PullRequestStackBase) GetRef() string { - if p == nil { - return "" - } - return p.Ref -} - -// GetSHA returns the SHA field. -func (p *PullRequestStackBase) GetSHA() string { - if p == nil { - return "" - } - return p.SHA -} - // GetBody returns the Body field if it's non-nil, zero value otherwise. func (p *PullRequestSubmitReviewRequest) GetBody() string { if p == nil || p.Body == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 7a9fdd7fe5b..027f22d0b07 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -40176,17 +40176,6 @@ func TestPullRequestStack_GetBase(tt *testing.T) { p.GetBase() } -func TestPullRequestStack_GetCreatedAt(tt *testing.T) { - tt.Parallel() - var zeroValue Timestamp - p := &PullRequestStack{CreatedAt: &zeroValue} - p.GetCreatedAt() - p = &PullRequestStack{} - p.GetCreatedAt() - p = nil - p.GetCreatedAt() -} - func TestPullRequestStack_GetID(tt *testing.T) { tt.Parallel() var zeroValue int64 @@ -40198,17 +40187,6 @@ func TestPullRequestStack_GetID(tt *testing.T) { p.GetID() } -func TestPullRequestStack_GetNodeID(tt *testing.T) { - tt.Parallel() - var zeroValue string - p := &PullRequestStack{NodeID: &zeroValue} - p.GetNodeID() - p = &PullRequestStack{} - p.GetNodeID() - p = nil - p.GetNodeID() -} - func TestPullRequestStack_GetNumber(tt *testing.T) { tt.Parallel() var zeroValue int @@ -40220,17 +40198,6 @@ func TestPullRequestStack_GetNumber(tt *testing.T) { p.GetNumber() } -func TestPullRequestStack_GetOpen(tt *testing.T) { - tt.Parallel() - var zeroValue bool - p := &PullRequestStack{Open: &zeroValue} - p.GetOpen() - p = &PullRequestStack{} - p.GetOpen() - p = nil - p.GetOpen() -} - func TestPullRequestStack_GetPosition(tt *testing.T) { tt.Parallel() var zeroValue int @@ -40242,17 +40209,6 @@ func TestPullRequestStack_GetPosition(tt *testing.T) { p.GetPosition() } -func TestPullRequestStack_GetPullRequests(tt *testing.T) { - tt.Parallel() - zeroValue := []*PullRequest{} - p := &PullRequestStack{PullRequests: zeroValue} - p.GetPullRequests() - p = &PullRequestStack{} - p.GetPullRequests() - p = nil - p.GetPullRequests() -} - func TestPullRequestStack_GetSize(tt *testing.T) { tt.Parallel() var zeroValue int @@ -40264,17 +40220,6 @@ func TestPullRequestStack_GetSize(tt *testing.T) { p.GetSize() } -func TestPullRequestStack_GetURL(tt *testing.T) { - tt.Parallel() - var zeroValue string - p := &PullRequestStack{URL: &zeroValue} - p.GetURL() - p = &PullRequestStack{} - p.GetURL() - p = nil - p.GetURL() -} - func TestPullRequestStackBase_GetRef(tt *testing.T) { tt.Parallel() p := &PullRequestStackBase{} @@ -40291,6 +40236,91 @@ func TestPullRequestStackBase_GetSHA(tt *testing.T) { p.GetSHA() } +func TestPullRequestStackDetails_GetBase(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackDetails{} + p.GetBase() + p = nil + p.GetBase() +} + +func TestPullRequestStackDetails_GetCreatedAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + p := &PullRequestStackDetails{CreatedAt: &zeroValue} + p.GetCreatedAt() + p = &PullRequestStackDetails{} + p.GetCreatedAt() + p = nil + p.GetCreatedAt() +} + +func TestPullRequestStackDetails_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + p := &PullRequestStackDetails{ID: &zeroValue} + p.GetID() + p = &PullRequestStackDetails{} + p.GetID() + p = nil + p.GetID() +} + +func TestPullRequestStackDetails_GetNodeID(tt *testing.T) { + tt.Parallel() + var zeroValue string + p := &PullRequestStackDetails{NodeID: &zeroValue} + p.GetNodeID() + p = &PullRequestStackDetails{} + p.GetNodeID() + p = nil + p.GetNodeID() +} + +func TestPullRequestStackDetails_GetNumber(tt *testing.T) { + tt.Parallel() + var zeroValue int + p := &PullRequestStackDetails{Number: &zeroValue} + p.GetNumber() + p = &PullRequestStackDetails{} + p.GetNumber() + p = nil + p.GetNumber() +} + +func TestPullRequestStackDetails_GetOpen(tt *testing.T) { + tt.Parallel() + var zeroValue bool + p := &PullRequestStackDetails{Open: &zeroValue} + p.GetOpen() + p = &PullRequestStackDetails{} + p.GetOpen() + p = nil + p.GetOpen() +} + +func TestPullRequestStackDetails_GetPullRequests(tt *testing.T) { + tt.Parallel() + zeroValue := []*PullRequest{} + p := &PullRequestStackDetails{PullRequests: zeroValue} + p.GetPullRequests() + p = &PullRequestStackDetails{} + p.GetPullRequests() + p = nil + p.GetPullRequests() +} + +func TestPullRequestStackDetails_GetURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + p := &PullRequestStackDetails{URL: &zeroValue} + p.GetURL() + p = &PullRequestStackDetails{} + p.GetURL() + p = nil + p.GetURL() +} + func TestPullRequestSubmitReviewRequest_GetBody(tt *testing.T) { tt.Parallel() var zeroValue string diff --git a/github/github-iterators.go b/github/github-iterators.go index ed78aa55ba3..11692fbfebe 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -5356,8 +5356,8 @@ func (s *PullRequestsService) ListReviewsIter(ctx context.Context, owner string, } // ListStacksIter returns an iterator that paginates through all results of ListStacks. -func (s *PullRequestsService) ListStacksIter(ctx context.Context, owner string, repo string, opts *PullRequestListStacksOptions) iter.Seq2[*PullRequestStack, error] { - return func(yield func(*PullRequestStack, error) bool) { +func (s *PullRequestsService) ListStacksIter(ctx context.Context, owner string, repo string, opts *PullRequestListStacksOptions) iter.Seq2[*PullRequestStackDetails, error] { + return func(yield func(*PullRequestStackDetails, error) bool) { // Create a copy of opts to avoid mutating the caller's struct if opts == nil { opts = &PullRequestListStacksOptions{} diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index 7928777e627..23ac48f33e8 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -11883,7 +11883,7 @@ func TestPullRequestsService_ListStacksIter(t *testing.T) { iter = client.PullRequests.ListStacksIter(t.Context(), "", "", nil) gotItems = 0 - iter(func(item *PullRequestStack, err error) bool { + iter(func(item *PullRequestStackDetails, err error) bool { gotItems++ if err != nil { t.Errorf("Unexpected error: %v", err) diff --git a/github/pulls.go b/github/pulls.go index b35ccc720e7..81bc9f89535 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -124,10 +124,10 @@ type PullRequestBranch struct { User *User `json:"user,omitempty"` } -// PullRequestStack represents a stack of pull requests. When embedded in a -// PullRequest, Base reports the branch the entire stack ultimately targets, -// which can differ from the pull request's own Base branch (the branch below it -// in the stack), and Position reports that pull request's place in the stack. +// PullRequestStack represents the stack a pull request belongs to, in +// repositories that use stacked pull requests. Base reports the branch the +// entire stack ultimately targets, which can differ from the pull request's own +// Base branch (the branch below it in the stack). type PullRequestStack struct { // Base is the base of the stack: the branch the entire stack ultimately targets. Base *PullRequestStackBase `json:"base"` @@ -136,20 +136,10 @@ type PullRequestStack struct { // Position is the one-based position of this pull request within the stack, // where 1 is the bottom of the stack. Position *int `json:"position,omitempty"` - // ID is the ID of the stack. + // ID is the ID of the stack that this pull request belongs to. ID *int64 `json:"id,omitempty"` - // Number is the number of the stack. + // Number is the number of the stack that this pull request belongs to. Number *int `json:"number,omitempty"` - // NodeID is the global node ID of the stack. - NodeID *string `json:"node_id,omitempty"` - // URL is the API URL of the stack. - URL *string `json:"url,omitempty"` - // Open reports whether the stack contains any open pull requests. - Open *bool `json:"open,omitempty"` - // CreatedAt is the time the stack was created. - CreatedAt *Timestamp `json:"created_at,omitempty"` - // PullRequests contains the pull requests in the stack, from bottom to top. - PullRequests []*PullRequest `json:"pull_requests,omitempty"` } // PullRequestStackBase represents the base of a stacked pull request's stack: diff --git a/github/pulls_stacks.go b/github/pulls_stacks.go index 09a7d668e2b..3cdd8ccac56 100644 --- a/github/pulls_stacks.go +++ b/github/pulls_stacks.go @@ -31,12 +31,33 @@ type AddPullRequestsToStackRequest struct { PullRequests []int `json:"pull_requests"` } +// PullRequestStackDetails represents a pull request stack returned by the +// stacked pull request endpoints. +type PullRequestStackDetails struct { + // ID is the ID of the stack. + ID *int64 `json:"id,omitempty"` + // Number is the number of the stack. + Number *int `json:"number,omitempty"` + // NodeID is the global node ID of the stack. + NodeID *string `json:"node_id,omitempty"` + // URL is the API URL of the stack. + URL *string `json:"url,omitempty"` + // Base is the branch the entire stack ultimately targets. + Base *PullRequestStackBase `json:"base"` + // Open reports whether the stack contains any open pull requests. + Open *bool `json:"open,omitempty"` + // CreatedAt is the time the stack was created. + CreatedAt *Timestamp `json:"created_at,omitempty"` + // PullRequests contains the pull requests in the stack, from bottom to top. + PullRequests []*PullRequest `json:"pull_requests,omitempty"` +} + // ListStacks lists pull request stacks in a repository. // // GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#list-pull-request-stacks // //meta:operation GET /repos/{owner}/{repo}/stacks -func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string, opts *PullRequestListStacksOptions) ([]*PullRequestStack, *Response, error) { +func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string, opts *PullRequestListStacksOptions) ([]*PullRequestStackDetails, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stacks", owner, repo) u, err := addOptions(u, opts) if err != nil { @@ -48,7 +69,7 @@ func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string return nil, nil, err } - var stacks []*PullRequestStack + var stacks []*PullRequestStackDetails resp, err := s.client.Do(req, &stacks) if err != nil { return nil, resp, err @@ -62,14 +83,14 @@ func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string // GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#create-a-pull-request-stack // //meta:operation POST /repos/{owner}/{repo}/stacks -func (s *PullRequestsService) CreateStack(ctx context.Context, owner, repo string, body CreatePullRequestStackRequest) (*PullRequestStack, *Response, error) { +func (s *PullRequestsService) CreateStack(ctx context.Context, owner, repo string, body CreatePullRequestStackRequest) (*PullRequestStackDetails, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stacks", owner, repo) req, err := s.client.NewRequest(ctx, "POST", u, body) if err != nil { return nil, nil, err } - var stack *PullRequestStack + var stack *PullRequestStackDetails resp, err := s.client.Do(req, &stack) if err != nil { return nil, resp, err @@ -83,14 +104,14 @@ func (s *PullRequestsService) CreateStack(ctx context.Context, owner, repo strin // GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#get-a-pull-request-stack // //meta:operation GET /repos/{owner}/{repo}/stacks/{stack_number} -func (s *PullRequestsService) GetStack(ctx context.Context, owner, repo string, stackNumber int) (*PullRequestStack, *Response, error) { +func (s *PullRequestsService) GetStack(ctx context.Context, owner, repo string, stackNumber int) (*PullRequestStackDetails, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stacks/%v", owner, repo, stackNumber) req, err := s.client.NewRequest(ctx, "GET", u, nil) if err != nil { return nil, nil, err } - var stack *PullRequestStack + var stack *PullRequestStackDetails resp, err := s.client.Do(req, &stack) if err != nil { return nil, resp, err @@ -104,14 +125,14 @@ func (s *PullRequestsService) GetStack(ctx context.Context, owner, repo string, // GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#add-pull-requests-to-a-pull-request-stack // //meta:operation POST /repos/{owner}/{repo}/stacks/{stack_number}/add -func (s *PullRequestsService) AddToStack(ctx context.Context, owner, repo string, stackNumber int, body AddPullRequestsToStackRequest) (*PullRequestStack, *Response, error) { +func (s *PullRequestsService) AddToStack(ctx context.Context, owner, repo string, stackNumber int, body AddPullRequestsToStackRequest) (*PullRequestStackDetails, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stacks/%v/add", owner, repo, stackNumber) req, err := s.client.NewRequest(ctx, "POST", u, body) if err != nil { return nil, nil, err } - var stack *PullRequestStack + var stack *PullRequestStackDetails resp, err := s.client.Do(req, &stack) if err != nil { return nil, resp, err @@ -126,14 +147,14 @@ func (s *PullRequestsService) AddToStack(ctx context.Context, owner, repo string // GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#remove-pull-requests-from-a-pull-request-stack // //meta:operation POST /repos/{owner}/{repo}/stacks/{stack_number}/unstack -func (s *PullRequestsService) Unstack(ctx context.Context, owner, repo string, stackNumber int) (*PullRequestStack, *Response, error) { +func (s *PullRequestsService) Unstack(ctx context.Context, owner, repo string, stackNumber int) (*PullRequestStackDetails, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stacks/%v/unstack", owner, repo, stackNumber) req, err := s.client.NewRequest(ctx, "POST", u, nil) if err != nil { return nil, nil, err } - var stack *PullRequestStack + var stack *PullRequestStackDetails resp, err := s.client.Do(req, &stack) if err != nil { return nil, resp, err diff --git a/github/pulls_stacks_test.go b/github/pulls_stacks_test.go index d4f0358374f..c7fa0dce476 100644 --- a/github/pulls_stacks_test.go +++ b/github/pulls_stacks_test.go @@ -32,8 +32,8 @@ func testPullRequestStackResponse() string { }` } -func testPullRequestStack() *PullRequestStack { - return &PullRequestStack{ +func testPullRequestStackDetails() *PullRequestStackDetails { + return &PullRequestStackDetails{ ID: Ptr(int64(1)), Number: Ptr(42), NodeID: Ptr("S_kwDOABCDEF4AAAAA"), @@ -64,7 +64,7 @@ func TestPullRequestsService_ListStacks(t *testing.T) { "page": "2", "per_page": "50", }) - fmt.Fprintf(w, "[%s]", testPullRequestStackResponse()) + fmt.Fprintf(w, "[%v]", testPullRequestStackResponse()) }) opts := &PullRequestListStacksOptions{ @@ -77,7 +77,7 @@ func TestPullRequestsService_ListStacks(t *testing.T) { t.Errorf("PullRequests.ListStacks returned error: %v", err) } - want := []*PullRequestStack{testPullRequestStack()} + want := []*PullRequestStackDetails{testPullRequestStackDetails()} if !cmp.Equal(stacks, want) { t.Errorf("PullRequests.ListStacks returned %+v, want %+v", stacks, want) } @@ -122,7 +122,7 @@ func TestPullRequestsService_CreateStack(t *testing.T) { if err != nil { t.Errorf("PullRequests.CreateStack returned error: %v", err) } - if want := testPullRequestStack(); !cmp.Equal(stack, want) { + if want := testPullRequestStackDetails(); !cmp.Equal(stack, want) { t.Errorf("PullRequests.CreateStack returned %+v, want %+v", stack, want) } @@ -163,7 +163,7 @@ func TestPullRequestsService_GetStack(t *testing.T) { if err != nil { t.Errorf("PullRequests.GetStack returned error: %v", err) } - if want := testPullRequestStack(); !cmp.Equal(stack, want) { + if want := testPullRequestStackDetails(); !cmp.Equal(stack, want) { t.Errorf("PullRequests.GetStack returned %+v, want %+v", stack, want) } @@ -206,7 +206,7 @@ func TestPullRequestsService_AddToStack(t *testing.T) { if err != nil { t.Errorf("PullRequests.AddToStack returned error: %v", err) } - if want := testPullRequestStack(); !cmp.Equal(stack, want) { + if want := testPullRequestStackDetails(); !cmp.Equal(stack, want) { t.Errorf("PullRequests.AddToStack returned %+v, want %+v", stack, want) } @@ -248,7 +248,7 @@ func TestPullRequestsService_Unstack(t *testing.T) { if err != nil { t.Errorf("PullRequests.Unstack returned error: %v", err) } - if want := testPullRequestStack(); !cmp.Equal(stack, want) { + if want := testPullRequestStackDetails(); !cmp.Equal(stack, want) { t.Errorf("PullRequests.Unstack returned %+v, want %+v", stack, want) } }) @@ -297,18 +297,3 @@ func TestPullRequestsService_Unstack_invalidOwner(t *testing.T) { _, _, err := client.PullRequests.Unstack(t.Context(), "%", "%", 42) testURLParseError(t, err) } - -func TestPullRequestStack_unmarshal(t *testing.T) { - t.Parallel() - testJSONUnmarshalOnly(t, testPullRequestStack(), testPullRequestStackResponse()) -} - -func TestCreatePullRequestStackRequest_marshal(t *testing.T) { - t.Parallel() - testJSONMarshal(t, &CreatePullRequestStackRequest{PullRequests: []int{101, 102}}, `{"pull_requests":[101,102]}`) -} - -func TestAddPullRequestsToStackRequest_marshal(t *testing.T) { - t.Parallel() - testJSONMarshal(t, &AddPullRequestsToStackRequest{PullRequests: []int{103}}, `{"pull_requests":[103]}`) -} From 5ad53ca179b77e2b8eafe4fa25f3f900b35842d0 Mon Sep 17 00:00:00 2001 From: Bortlesboat <169967362+Bortlesboat@users.noreply.github.com> Date: Sat, 8 Aug 2026 03:17:27 -0400 Subject: [PATCH 3/4] Align stack response types with response schemas --- github/github-accessors.go | 312 ++++++++++++++++++++++++++++++-- github/github-accessors_test.go | 311 ++++++++++++++++++++++++++++--- github/github-iterators.go | 4 +- github/github-iterators_test.go | 2 +- github/pulls_stacks.go | 130 +++++++++++-- github/pulls_stacks_test.go | 99 ++++++++-- 6 files changed, 782 insertions(+), 76 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 786c25af31a..4fb1ef3beb4 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -32078,68 +32078,340 @@ func (p *PullRequestStackBase) GetSHA() string { return p.SHA } +// GetRef returns the Ref field. +func (p *PullRequestStackBranch) GetRef() string { + if p == nil { + return "" + } + return p.Ref +} + +// GetRepo returns the Repo field. +func (p *PullRequestStackBranch) GetRepo() *PullRequestStackRepository { + if p == nil { + return nil + } + return p.Repo +} + +// GetSHA returns the SHA field. +func (p *PullRequestStackBranch) GetSHA() string { + if p == nil { + return "" + } + return p.SHA +} + // GetBase returns the Base field. -func (p *PullRequestStackDetails) GetBase() *PullRequestStackBase { +func (p *PullRequestStackDetails) GetBase() *PullRequestStackRef { if p == nil { return nil } return p.Base } -// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. +// GetCreatedAt returns the CreatedAt field. func (p *PullRequestStackDetails) GetCreatedAt() Timestamp { - if p == nil || p.CreatedAt == nil { + if p == nil { return Timestamp{} } - return *p.CreatedAt + return p.CreatedAt } -// GetID returns the ID field if it's non-nil, zero value otherwise. +// GetID returns the ID field. func (p *PullRequestStackDetails) GetID() int64 { - if p == nil || p.ID == nil { + if p == nil { return 0 } - return *p.ID + return p.ID } -// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +// GetNodeID returns the NodeID field. func (p *PullRequestStackDetails) GetNodeID() string { - if p == nil || p.NodeID == nil { + if p == nil { return "" } - return *p.NodeID + return p.NodeID } -// GetNumber returns the Number field if it's non-nil, zero value otherwise. +// GetNumber returns the Number field. func (p *PullRequestStackDetails) GetNumber() int { - if p == nil || p.Number == nil { + if p == nil { return 0 } - return *p.Number + return p.Number } -// GetOpen returns the Open field if it's non-nil, zero value otherwise. +// GetOpen returns the Open field. func (p *PullRequestStackDetails) GetOpen() bool { - if p == nil || p.Open == nil { + if p == nil { return false } - return *p.Open + return p.Open } // GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. -func (p *PullRequestStackDetails) GetPullRequests() []*PullRequest { +func (p *PullRequestStackDetails) GetPullRequests() []*PullRequestStackPullRequest { if p == nil || p.PullRequests == nil { return nil } return p.PullRequests } -// GetURL returns the URL field if it's non-nil, zero value otherwise. +// GetURL returns the URL field. func (p *PullRequestStackDetails) GetURL() string { - if p == nil || p.URL == nil { + if p == nil { return "" } - return *p.URL + return p.URL +} + +// GetBase returns the Base field. +func (p *PullRequestStackMinimal) GetBase() *PullRequestStackRef { + if p == nil { + return nil + } + return p.Base +} + +// GetCreatedAt returns the CreatedAt field. +func (p *PullRequestStackMinimal) GetCreatedAt() Timestamp { + if p == nil { + return Timestamp{} + } + return p.CreatedAt +} + +// GetID returns the ID field. +func (p *PullRequestStackMinimal) GetID() int64 { + if p == nil { + return 0 + } + return p.ID +} + +// GetNodeID returns the NodeID field. +func (p *PullRequestStackMinimal) GetNodeID() string { + if p == nil { + return "" + } + return p.NodeID +} + +// GetNumber returns the Number field. +func (p *PullRequestStackMinimal) GetNumber() int { + if p == nil { + return 0 + } + return p.Number +} + +// GetOpen returns the Open field. +func (p *PullRequestStackMinimal) GetOpen() bool { + if p == nil { + return false + } + return p.Open +} + +// GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. +func (p *PullRequestStackMinimal) GetPullRequests() []*PullRequestStackMinimalPullRequest { + if p == nil || p.PullRequests == nil { + return nil + } + return p.PullRequests +} + +// GetURL returns the URL field. +func (p *PullRequestStackMinimal) GetURL() string { + if p == nil { + return "" + } + return p.URL +} + +// GetRef returns the Ref field. +func (p *PullRequestStackMinimalBranch) GetRef() string { + if p == nil { + return "" + } + return p.Ref +} + +// GetSHA returns the SHA field. +func (p *PullRequestStackMinimalBranch) GetSHA() string { + if p == nil { + return "" + } + return p.SHA +} + +// GetDraft returns the Draft field. +func (p *PullRequestStackMinimalPullRequest) GetDraft() bool { + if p == nil { + return false + } + return p.Draft +} + +// GetHead returns the Head field. +func (p *PullRequestStackMinimalPullRequest) GetHead() *PullRequestStackMinimalBranch { + if p == nil { + return nil + } + return p.Head +} + +// GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise. +func (p *PullRequestStackMinimalPullRequest) GetMergedAt() Timestamp { + if p == nil || p.MergedAt == nil { + return Timestamp{} + } + return *p.MergedAt +} + +// GetNumber returns the Number field. +func (p *PullRequestStackMinimalPullRequest) GetNumber() int { + if p == nil { + return 0 + } + return p.Number +} + +// GetState returns the State field. +func (p *PullRequestStackMinimalPullRequest) GetState() string { + if p == nil { + return "" + } + return p.State +} + +// GetBase returns the Base field. +func (p *PullRequestStackPullRequest) GetBase() *PullRequestStackBranch { + if p == nil { + return nil + } + return p.Base +} + +// GetDraft returns the Draft field. +func (p *PullRequestStackPullRequest) GetDraft() bool { + if p == nil { + return false + } + return p.Draft +} + +// GetHead returns the Head field. +func (p *PullRequestStackPullRequest) GetHead() *PullRequestStackBranch { + if p == nil { + return nil + } + return p.Head +} + +// GetHTMLURL returns the HTMLURL field. +func (p *PullRequestStackPullRequest) GetHTMLURL() string { + if p == nil { + return "" + } + return p.HTMLURL +} + +// GetID returns the ID field. +func (p *PullRequestStackPullRequest) GetID() int64 { + if p == nil { + return 0 + } + return p.ID +} + +// GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise. +func (p *PullRequestStackPullRequest) GetMergedAt() Timestamp { + if p == nil || p.MergedAt == nil { + return Timestamp{} + } + return *p.MergedAt +} + +// GetNodeID returns the NodeID field. +func (p *PullRequestStackPullRequest) GetNodeID() string { + if p == nil { + return "" + } + return p.NodeID +} + +// GetNumber returns the Number field. +func (p *PullRequestStackPullRequest) GetNumber() int { + if p == nil { + return 0 + } + return p.Number +} + +// GetState returns the State field. +func (p *PullRequestStackPullRequest) GetState() string { + if p == nil { + return "" + } + return p.State +} + +// GetTitle returns the Title field. +func (p *PullRequestStackPullRequest) GetTitle() string { + if p == nil { + return "" + } + return p.Title +} + +// GetURL returns the URL field. +func (p *PullRequestStackPullRequest) GetURL() string { + if p == nil { + return "" + } + return p.URL +} + +// GetUser returns the User field. +func (p *PullRequestStackPullRequest) GetUser() *User { + if p == nil { + return nil + } + return p.User +} + +// GetRef returns the Ref field. +func (p *PullRequestStackRef) GetRef() string { + if p == nil { + return "" + } + return p.Ref +} + +// GetID returns the ID field. +func (p *PullRequestStackRepository) GetID() int64 { + if p == nil { + return 0 + } + return p.ID +} + +// GetName returns the Name field. +func (p *PullRequestStackRepository) GetName() string { + if p == nil { + return "" + } + return p.Name +} + +// GetURL returns the URL field. +func (p *PullRequestStackRepository) GetURL() string { + if p == nil { + return "" + } + return p.URL } // GetBody returns the Body field if it's non-nil, zero value otherwise. diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 027f22d0b07..8a734b46344 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -40236,6 +40236,30 @@ func TestPullRequestStackBase_GetSHA(tt *testing.T) { p.GetSHA() } +func TestPullRequestStackBranch_GetRef(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackBranch{} + p.GetRef() + p = nil + p.GetRef() +} + +func TestPullRequestStackBranch_GetRepo(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackBranch{} + p.GetRepo() + p = nil + p.GetRepo() +} + +func TestPullRequestStackBranch_GetSHA(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackBranch{} + p.GetSHA() + p = nil + p.GetSHA() +} + func TestPullRequestStackDetails_GetBase(tt *testing.T) { tt.Parallel() p := &PullRequestStackDetails{} @@ -40246,10 +40270,7 @@ func TestPullRequestStackDetails_GetBase(tt *testing.T) { func TestPullRequestStackDetails_GetCreatedAt(tt *testing.T) { tt.Parallel() - var zeroValue Timestamp - p := &PullRequestStackDetails{CreatedAt: &zeroValue} - p.GetCreatedAt() - p = &PullRequestStackDetails{} + p := &PullRequestStackDetails{} p.GetCreatedAt() p = nil p.GetCreatedAt() @@ -40257,10 +40278,7 @@ func TestPullRequestStackDetails_GetCreatedAt(tt *testing.T) { func TestPullRequestStackDetails_GetID(tt *testing.T) { tt.Parallel() - var zeroValue int64 - p := &PullRequestStackDetails{ID: &zeroValue} - p.GetID() - p = &PullRequestStackDetails{} + p := &PullRequestStackDetails{} p.GetID() p = nil p.GetID() @@ -40268,10 +40286,7 @@ func TestPullRequestStackDetails_GetID(tt *testing.T) { func TestPullRequestStackDetails_GetNodeID(tt *testing.T) { tt.Parallel() - var zeroValue string - p := &PullRequestStackDetails{NodeID: &zeroValue} - p.GetNodeID() - p = &PullRequestStackDetails{} + p := &PullRequestStackDetails{} p.GetNodeID() p = nil p.GetNodeID() @@ -40279,10 +40294,7 @@ func TestPullRequestStackDetails_GetNodeID(tt *testing.T) { func TestPullRequestStackDetails_GetNumber(tt *testing.T) { tt.Parallel() - var zeroValue int - p := &PullRequestStackDetails{Number: &zeroValue} - p.GetNumber() - p = &PullRequestStackDetails{} + p := &PullRequestStackDetails{} p.GetNumber() p = nil p.GetNumber() @@ -40290,10 +40302,7 @@ func TestPullRequestStackDetails_GetNumber(tt *testing.T) { func TestPullRequestStackDetails_GetOpen(tt *testing.T) { tt.Parallel() - var zeroValue bool - p := &PullRequestStackDetails{Open: &zeroValue} - p.GetOpen() - p = &PullRequestStackDetails{} + p := &PullRequestStackDetails{} p.GetOpen() p = nil p.GetOpen() @@ -40301,7 +40310,7 @@ func TestPullRequestStackDetails_GetOpen(tt *testing.T) { func TestPullRequestStackDetails_GetPullRequests(tt *testing.T) { tt.Parallel() - zeroValue := []*PullRequest{} + zeroValue := []*PullRequestStackPullRequest{} p := &PullRequestStackDetails{PullRequests: zeroValue} p.GetPullRequests() p = &PullRequestStackDetails{} @@ -40312,10 +40321,264 @@ func TestPullRequestStackDetails_GetPullRequests(tt *testing.T) { func TestPullRequestStackDetails_GetURL(tt *testing.T) { tt.Parallel() - var zeroValue string - p := &PullRequestStackDetails{URL: &zeroValue} + p := &PullRequestStackDetails{} p.GetURL() - p = &PullRequestStackDetails{} + p = nil + p.GetURL() +} + +func TestPullRequestStackMinimal_GetBase(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimal{} + p.GetBase() + p = nil + p.GetBase() +} + +func TestPullRequestStackMinimal_GetCreatedAt(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimal{} + p.GetCreatedAt() + p = nil + p.GetCreatedAt() +} + +func TestPullRequestStackMinimal_GetID(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimal{} + p.GetID() + p = nil + p.GetID() +} + +func TestPullRequestStackMinimal_GetNodeID(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimal{} + p.GetNodeID() + p = nil + p.GetNodeID() +} + +func TestPullRequestStackMinimal_GetNumber(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimal{} + p.GetNumber() + p = nil + p.GetNumber() +} + +func TestPullRequestStackMinimal_GetOpen(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimal{} + p.GetOpen() + p = nil + p.GetOpen() +} + +func TestPullRequestStackMinimal_GetPullRequests(tt *testing.T) { + tt.Parallel() + zeroValue := []*PullRequestStackMinimalPullRequest{} + p := &PullRequestStackMinimal{PullRequests: zeroValue} + p.GetPullRequests() + p = &PullRequestStackMinimal{} + p.GetPullRequests() + p = nil + p.GetPullRequests() +} + +func TestPullRequestStackMinimal_GetURL(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimal{} + p.GetURL() + p = nil + p.GetURL() +} + +func TestPullRequestStackMinimalBranch_GetRef(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimalBranch{} + p.GetRef() + p = nil + p.GetRef() +} + +func TestPullRequestStackMinimalBranch_GetSHA(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimalBranch{} + p.GetSHA() + p = nil + p.GetSHA() +} + +func TestPullRequestStackMinimalPullRequest_GetDraft(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimalPullRequest{} + p.GetDraft() + p = nil + p.GetDraft() +} + +func TestPullRequestStackMinimalPullRequest_GetHead(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimalPullRequest{} + p.GetHead() + p = nil + p.GetHead() +} + +func TestPullRequestStackMinimalPullRequest_GetMergedAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + p := &PullRequestStackMinimalPullRequest{MergedAt: &zeroValue} + p.GetMergedAt() + p = &PullRequestStackMinimalPullRequest{} + p.GetMergedAt() + p = nil + p.GetMergedAt() +} + +func TestPullRequestStackMinimalPullRequest_GetNumber(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimalPullRequest{} + p.GetNumber() + p = nil + p.GetNumber() +} + +func TestPullRequestStackMinimalPullRequest_GetState(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackMinimalPullRequest{} + p.GetState() + p = nil + p.GetState() +} + +func TestPullRequestStackPullRequest_GetBase(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetBase() + p = nil + p.GetBase() +} + +func TestPullRequestStackPullRequest_GetDraft(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetDraft() + p = nil + p.GetDraft() +} + +func TestPullRequestStackPullRequest_GetHead(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetHead() + p = nil + p.GetHead() +} + +func TestPullRequestStackPullRequest_GetHTMLURL(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetHTMLURL() + p = nil + p.GetHTMLURL() +} + +func TestPullRequestStackPullRequest_GetID(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetID() + p = nil + p.GetID() +} + +func TestPullRequestStackPullRequest_GetMergedAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + p := &PullRequestStackPullRequest{MergedAt: &zeroValue} + p.GetMergedAt() + p = &PullRequestStackPullRequest{} + p.GetMergedAt() + p = nil + p.GetMergedAt() +} + +func TestPullRequestStackPullRequest_GetNodeID(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetNodeID() + p = nil + p.GetNodeID() +} + +func TestPullRequestStackPullRequest_GetNumber(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetNumber() + p = nil + p.GetNumber() +} + +func TestPullRequestStackPullRequest_GetState(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetState() + p = nil + p.GetState() +} + +func TestPullRequestStackPullRequest_GetTitle(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetTitle() + p = nil + p.GetTitle() +} + +func TestPullRequestStackPullRequest_GetURL(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetURL() + p = nil + p.GetURL() +} + +func TestPullRequestStackPullRequest_GetUser(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackPullRequest{} + p.GetUser() + p = nil + p.GetUser() +} + +func TestPullRequestStackRef_GetRef(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackRef{} + p.GetRef() + p = nil + p.GetRef() +} + +func TestPullRequestStackRepository_GetID(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackRepository{} + p.GetID() + p = nil + p.GetID() +} + +func TestPullRequestStackRepository_GetName(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackRepository{} + p.GetName() + p = nil + p.GetName() +} + +func TestPullRequestStackRepository_GetURL(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackRepository{} p.GetURL() p = nil p.GetURL() diff --git a/github/github-iterators.go b/github/github-iterators.go index 11692fbfebe..fc421373bdd 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -5356,8 +5356,8 @@ func (s *PullRequestsService) ListReviewsIter(ctx context.Context, owner string, } // ListStacksIter returns an iterator that paginates through all results of ListStacks. -func (s *PullRequestsService) ListStacksIter(ctx context.Context, owner string, repo string, opts *PullRequestListStacksOptions) iter.Seq2[*PullRequestStackDetails, error] { - return func(yield func(*PullRequestStackDetails, error) bool) { +func (s *PullRequestsService) ListStacksIter(ctx context.Context, owner string, repo string, opts *PullRequestListStacksOptions) iter.Seq2[*PullRequestStackMinimal, error] { + return func(yield func(*PullRequestStackMinimal, error) bool) { // Create a copy of opts to avoid mutating the caller's struct if opts == nil { opts = &PullRequestListStacksOptions{} diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index 23ac48f33e8..9a85375cb09 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -11883,7 +11883,7 @@ func TestPullRequestsService_ListStacksIter(t *testing.T) { iter = client.PullRequests.ListStacksIter(t.Context(), "", "", nil) gotItems = 0 - iter(func(item *PullRequestStackDetails, err error) bool { + iter(func(item *PullRequestStackMinimal, err error) bool { gotItems++ if err != nil { t.Errorf("Unexpected error: %v", err) diff --git a/github/pulls_stacks.go b/github/pulls_stacks.go index 3cdd8ccac56..55330c93901 100644 --- a/github/pulls_stacks.go +++ b/github/pulls_stacks.go @@ -31,25 +31,131 @@ type AddPullRequestsToStackRequest struct { PullRequests []int `json:"pull_requests"` } -// PullRequestStackDetails represents a pull request stack returned by the -// stacked pull request endpoints. +// PullRequestStackRef represents the branch a pull request stack ultimately +// targets. The stacked pull request endpoints return the ref alone, unlike +// PullRequestStackBase, which the pull request endpoints return with a SHA. +type PullRequestStackRef struct { + // Ref is the name of the branch the entire stack ultimately targets. + Ref string `json:"ref"` +} + +// PullRequestStackDetails represents a pull request stack returned by +// PullRequestsService.CreateStack, GetStack, AddToStack, and Unstack. type PullRequestStackDetails struct { // ID is the ID of the stack. - ID *int64 `json:"id,omitempty"` + ID int64 `json:"id"` + // Number is the number of the stack. + Number int `json:"number"` + // NodeID is the global node ID of the stack. + NodeID string `json:"node_id"` + // URL is the API URL of the stack. + URL string `json:"url"` + // Base is the branch the entire stack ultimately targets. + Base *PullRequestStackRef `json:"base"` + // Open reports whether the stack contains any open pull requests. + Open bool `json:"open"` + // CreatedAt is the time the stack was created. + CreatedAt Timestamp `json:"created_at"` + // PullRequests contains the pull requests in the stack, from bottom to top. + PullRequests []*PullRequestStackPullRequest `json:"pull_requests"` +} + +// PullRequestStackPullRequest represents a pull request in a stack returned by +// PullRequestsService.CreateStack, GetStack, AddToStack, and Unstack. +type PullRequestStackPullRequest struct { + // ID is the ID of the pull request. + ID int64 `json:"id"` + // Number is the number of the pull request. + Number int `json:"number"` + // NodeID is the global node ID of the pull request. + NodeID string `json:"node_id"` + // URL is the API URL of the pull request. + URL string `json:"url"` + // HTMLURL is the web URL of the pull request. + HTMLURL string `json:"html_url"` + // Title is the title of the pull request. + Title string `json:"title"` + // State is the state of the pull request. Possible values are: "open" and "closed". + State string `json:"state"` + // Draft reports whether the pull request is a draft. + Draft bool `json:"draft"` + // MergedAt is the time the pull request was merged, or nil if it is unmerged. + MergedAt *Timestamp `json:"merged_at"` + // User is the author of the pull request. + User *User `json:"user"` + // Head is the branch the pull request merges from. + Head *PullRequestStackBranch `json:"head"` + // Base is the branch the pull request merges into, which is the pull + // request below it in the stack. + Base *PullRequestStackBranch `json:"base"` +} + +// PullRequestStackBranch represents the head or base branch of a pull request +// returned by the stacked pull request endpoints. +type PullRequestStackBranch struct { + // Ref is the name of the branch. + Ref string `json:"ref"` + // SHA is the SHA of the most recent commit on the branch. + SHA string `json:"sha"` + // Repo is the repository the branch belongs to. + Repo *PullRequestStackRepository `json:"repo"` +} + +// PullRequestStackRepository represents the repository a stacked pull +// request's branch belongs to. +type PullRequestStackRepository struct { + // ID is the ID of the repository. + ID int64 `json:"id"` + // URL is the API URL of the repository. + URL string `json:"url"` + // Name is the name of the repository. + Name string `json:"name"` +} + +// PullRequestStackMinimal represents a pull request stack returned by +// PullRequestsService.ListStacks. This endpoint returns less detail about each +// pull request in the stack than PullRequestStackDetails carries. +type PullRequestStackMinimal struct { + // ID is the ID of the stack. + ID int64 `json:"id"` // Number is the number of the stack. - Number *int `json:"number,omitempty"` + Number int `json:"number"` // NodeID is the global node ID of the stack. - NodeID *string `json:"node_id,omitempty"` + NodeID string `json:"node_id"` // URL is the API URL of the stack. - URL *string `json:"url,omitempty"` + URL string `json:"url"` // Base is the branch the entire stack ultimately targets. - Base *PullRequestStackBase `json:"base"` + Base *PullRequestStackRef `json:"base"` // Open reports whether the stack contains any open pull requests. - Open *bool `json:"open,omitempty"` + Open bool `json:"open"` // CreatedAt is the time the stack was created. - CreatedAt *Timestamp `json:"created_at,omitempty"` + CreatedAt Timestamp `json:"created_at"` // PullRequests contains the pull requests in the stack, from bottom to top. - PullRequests []*PullRequest `json:"pull_requests,omitempty"` + PullRequests []*PullRequestStackMinimalPullRequest `json:"pull_requests"` +} + +// PullRequestStackMinimalPullRequest represents a pull request in a stack +// returned by PullRequestsService.ListStacks. +type PullRequestStackMinimalPullRequest struct { + // Number is the number of the pull request. + Number int `json:"number"` + // State is the state of the pull request. Possible values are: "open" and "closed". + State string `json:"state"` + // Draft reports whether the pull request is a draft. + Draft bool `json:"draft"` + // MergedAt is the time the pull request was merged, or nil if it is unmerged. + MergedAt *Timestamp `json:"merged_at"` + // Head is the branch the pull request merges from. + Head *PullRequestStackMinimalBranch `json:"head"` +} + +// PullRequestStackMinimalBranch represents the head branch of a pull request +// returned by PullRequestsService.ListStacks. +type PullRequestStackMinimalBranch struct { + // Ref is the name of the branch. + Ref string `json:"ref"` + // SHA is the SHA of the most recent commit on the branch. + SHA string `json:"sha"` } // ListStacks lists pull request stacks in a repository. @@ -57,7 +163,7 @@ type PullRequestStackDetails struct { // GitHub API docs: https://docs.github.com/rest/pulls/stacks?apiVersion=2022-11-28#list-pull-request-stacks // //meta:operation GET /repos/{owner}/{repo}/stacks -func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string, opts *PullRequestListStacksOptions) ([]*PullRequestStackDetails, *Response, error) { +func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string, opts *PullRequestListStacksOptions) ([]*PullRequestStackMinimal, *Response, error) { u := fmt.Sprintf("repos/%v/%v/stacks", owner, repo) u, err := addOptions(u, opts) if err != nil { @@ -69,7 +175,7 @@ func (s *PullRequestsService) ListStacks(ctx context.Context, owner, repo string return nil, nil, err } - var stacks []*PullRequestStackDetails + var stacks []*PullRequestStackMinimal resp, err := s.client.Do(req, &stacks) if err != nil { return nil, resp, err diff --git a/github/pulls_stacks_test.go b/github/pulls_stacks_test.go index c7fa0dce476..b2493ac1c4b 100644 --- a/github/pulls_stacks_test.go +++ b/github/pulls_stacks_test.go @@ -23,31 +23,96 @@ func testPullRequestStackResponse() string { "open":true, "created_at":` + referenceTimeStr + `, "pull_requests":[{ + "id":1001, "number":101, + "node_id":"PR_kwDOABCDEF4AAAAA", + "url":"https://api.github.com/repos/o/r/pulls/101", + "html_url":"https://github.com/o/r/pull/101", + "title":"Add a feature", "state":"open", "draft":false, "merged_at":null, - "head":{"ref":"feature","sha":"abc123"} + "user":{"login":"octocat"}, + "head":{"ref":"feature","sha":"abc123","repo":{"id":2001,"url":"https://api.github.com/repos/o/r","name":"r"}}, + "base":{"ref":"main","sha":"def456","repo":{"id":2001,"url":"https://api.github.com/repos/o/r","name":"r"}} }] }` } func testPullRequestStackDetails() *PullRequestStackDetails { + repo := &PullRequestStackRepository{ + ID: 2001, + URL: "https://api.github.com/repos/o/r", + Name: "r", + } + return &PullRequestStackDetails{ - ID: Ptr(int64(1)), - Number: Ptr(42), - NodeID: Ptr("S_kwDOABCDEF4AAAAA"), - URL: Ptr("https://api.github.com/repos/o/r/stacks/42"), - Base: &PullRequestStackBase{Ref: "main"}, - Open: Ptr(true), - CreatedAt: &referenceTimestamp, - PullRequests: []*PullRequest{{ - Number: Ptr(101), - State: Ptr("open"), - Draft: Ptr(false), - Head: &PullRequestBranch{ - Ref: Ptr("feature"), - SHA: Ptr("abc123"), + ID: 1, + Number: 42, + NodeID: "S_kwDOABCDEF4AAAAA", + URL: "https://api.github.com/repos/o/r/stacks/42", + Base: &PullRequestStackRef{Ref: "main"}, + Open: true, + CreatedAt: referenceTimestamp, + PullRequests: []*PullRequestStackPullRequest{{ + ID: 1001, + Number: 101, + NodeID: "PR_kwDOABCDEF4AAAAA", + URL: "https://api.github.com/repos/o/r/pulls/101", + HTMLURL: "https://github.com/o/r/pull/101", + Title: "Add a feature", + State: "open", + Draft: false, + User: &User{Login: Ptr("octocat")}, + Head: &PullRequestStackBranch{ + Ref: "feature", + SHA: "abc123", + Repo: repo, + }, + Base: &PullRequestStackBranch{ + Ref: "main", + SHA: "def456", + Repo: repo, + }, + }}, + } +} + +func testPullRequestStackMinimalResponse() string { + return `{ + "id":1, + "number":42, + "node_id":"S_kwDOABCDEF4AAAAA", + "url":"https://api.github.com/repos/o/r/stacks/42", + "base":{"ref":"main"}, + "open":true, + "created_at":` + referenceTimeStr + `, + "pull_requests":[{ + "number":101, + "state":"open", + "draft":false, + "merged_at":null, + "head":{"ref":"feature","sha":"abc123"} + }] + }` +} + +func testPullRequestStackMinimal() *PullRequestStackMinimal { + return &PullRequestStackMinimal{ + ID: 1, + Number: 42, + NodeID: "S_kwDOABCDEF4AAAAA", + URL: "https://api.github.com/repos/o/r/stacks/42", + Base: &PullRequestStackRef{Ref: "main"}, + Open: true, + CreatedAt: referenceTimestamp, + PullRequests: []*PullRequestStackMinimalPullRequest{{ + Number: 101, + State: "open", + Draft: false, + Head: &PullRequestStackMinimalBranch{ + Ref: "feature", + SHA: "abc123", }, }}, } @@ -64,7 +129,7 @@ func TestPullRequestsService_ListStacks(t *testing.T) { "page": "2", "per_page": "50", }) - fmt.Fprintf(w, "[%v]", testPullRequestStackResponse()) + fmt.Fprintf(w, "[%v]", testPullRequestStackMinimalResponse()) }) opts := &PullRequestListStacksOptions{ @@ -77,7 +142,7 @@ func TestPullRequestsService_ListStacks(t *testing.T) { t.Errorf("PullRequests.ListStacks returned error: %v", err) } - want := []*PullRequestStackDetails{testPullRequestStackDetails()} + want := []*PullRequestStackMinimal{testPullRequestStackMinimal()} if !cmp.Equal(stacks, want) { t.Errorf("PullRequests.ListStacks returned %+v, want %+v", stacks, want) } From 7b58560a322697773177e08e2e0e82b1dac137b0 Mon Sep 17 00:00:00 2001 From: Bortlesboat <169967362+Bortlesboat@users.noreply.github.com> Date: Sat, 8 Aug 2026 11:46:48 -0400 Subject: [PATCH 4/4] Rename stack pull request types to avoid stutter --- github/github-accessors.go | 184 +++++++++++++------------- github/github-accessors_test.go | 220 ++++++++++++++++---------------- github/pulls_stacks.go | 18 +-- github/pulls_stacks_test.go | 6 +- 4 files changed, 214 insertions(+), 214 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 4fb1ef3beb4..1811a37dd21 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -32151,7 +32151,7 @@ func (p *PullRequestStackDetails) GetOpen() bool { } // GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. -func (p *PullRequestStackDetails) GetPullRequests() []*PullRequestStackPullRequest { +func (p *PullRequestStackDetails) GetPullRequests() []*PullRequestStackEntry { if p == nil || p.PullRequests == nil { return nil } @@ -32167,31 +32167,55 @@ func (p *PullRequestStackDetails) GetURL() string { } // GetBase returns the Base field. -func (p *PullRequestStackMinimal) GetBase() *PullRequestStackRef { +func (p *PullRequestStackEntry) GetBase() *PullRequestStackBranch { if p == nil { return nil } return p.Base } -// GetCreatedAt returns the CreatedAt field. -func (p *PullRequestStackMinimal) GetCreatedAt() Timestamp { +// GetDraft returns the Draft field. +func (p *PullRequestStackEntry) GetDraft() bool { if p == nil { - return Timestamp{} + return false } - return p.CreatedAt + return p.Draft +} + +// GetHead returns the Head field. +func (p *PullRequestStackEntry) GetHead() *PullRequestStackBranch { + if p == nil { + return nil + } + return p.Head +} + +// GetHTMLURL returns the HTMLURL field. +func (p *PullRequestStackEntry) GetHTMLURL() string { + if p == nil { + return "" + } + return p.HTMLURL } // GetID returns the ID field. -func (p *PullRequestStackMinimal) GetID() int64 { +func (p *PullRequestStackEntry) GetID() int64 { if p == nil { return 0 } return p.ID } +// GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise. +func (p *PullRequestStackEntry) GetMergedAt() Timestamp { + if p == nil || p.MergedAt == nil { + return Timestamp{} + } + return *p.MergedAt +} + // GetNodeID returns the NodeID field. -func (p *PullRequestStackMinimal) GetNodeID() string { +func (p *PullRequestStackEntry) GetNodeID() string { if p == nil { return "" } @@ -32199,103 +32223,111 @@ func (p *PullRequestStackMinimal) GetNodeID() string { } // GetNumber returns the Number field. -func (p *PullRequestStackMinimal) GetNumber() int { +func (p *PullRequestStackEntry) GetNumber() int { if p == nil { return 0 } return p.Number } -// GetOpen returns the Open field. -func (p *PullRequestStackMinimal) GetOpen() bool { +// GetState returns the State field. +func (p *PullRequestStackEntry) GetState() string { if p == nil { - return false + return "" } - return p.Open + return p.State } -// GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. -func (p *PullRequestStackMinimal) GetPullRequests() []*PullRequestStackMinimalPullRequest { - if p == nil || p.PullRequests == nil { - return nil +// GetTitle returns the Title field. +func (p *PullRequestStackEntry) GetTitle() string { + if p == nil { + return "" } - return p.PullRequests + return p.Title } // GetURL returns the URL field. -func (p *PullRequestStackMinimal) GetURL() string { +func (p *PullRequestStackEntry) GetURL() string { if p == nil { return "" } return p.URL } -// GetRef returns the Ref field. -func (p *PullRequestStackMinimalBranch) GetRef() string { +// GetUser returns the User field. +func (p *PullRequestStackEntry) GetUser() *User { if p == nil { - return "" + return nil } - return p.Ref + return p.User } -// GetSHA returns the SHA field. -func (p *PullRequestStackMinimalBranch) GetSHA() string { +// GetBase returns the Base field. +func (p *PullRequestStackMinimal) GetBase() *PullRequestStackRef { if p == nil { - return "" + return nil } - return p.SHA + return p.Base } -// GetDraft returns the Draft field. -func (p *PullRequestStackMinimalPullRequest) GetDraft() bool { +// GetCreatedAt returns the CreatedAt field. +func (p *PullRequestStackMinimal) GetCreatedAt() Timestamp { if p == nil { - return false + return Timestamp{} } - return p.Draft + return p.CreatedAt } -// GetHead returns the Head field. -func (p *PullRequestStackMinimalPullRequest) GetHead() *PullRequestStackMinimalBranch { +// GetID returns the ID field. +func (p *PullRequestStackMinimal) GetID() int64 { if p == nil { - return nil + return 0 } - return p.Head + return p.ID } -// GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise. -func (p *PullRequestStackMinimalPullRequest) GetMergedAt() Timestamp { - if p == nil || p.MergedAt == nil { - return Timestamp{} +// GetNodeID returns the NodeID field. +func (p *PullRequestStackMinimal) GetNodeID() string { + if p == nil { + return "" } - return *p.MergedAt + return p.NodeID } // GetNumber returns the Number field. -func (p *PullRequestStackMinimalPullRequest) GetNumber() int { +func (p *PullRequestStackMinimal) GetNumber() int { if p == nil { return 0 } return p.Number } -// GetState returns the State field. -func (p *PullRequestStackMinimalPullRequest) GetState() string { +// GetOpen returns the Open field. +func (p *PullRequestStackMinimal) GetOpen() bool { if p == nil { - return "" + return false } - return p.State + return p.Open } -// GetBase returns the Base field. -func (p *PullRequestStackPullRequest) GetBase() *PullRequestStackBranch { - if p == nil { +// GetPullRequests returns the PullRequests slice if it's non-nil, nil otherwise. +func (p *PullRequestStackMinimal) GetPullRequests() []*PullRequestStackMinimalEntry { + if p == nil || p.PullRequests == nil { return nil } - return p.Base + return p.PullRequests +} + +// GetURL returns the URL field. +func (p *PullRequestStackMinimal) GetURL() string { + if p == nil { + return "" + } + return p.URL } // GetDraft returns the Draft field. -func (p *PullRequestStackPullRequest) GetDraft() bool { +func (p *PullRequestStackMinimalEntry) GetDraft() bool { if p == nil { return false } @@ -32303,47 +32335,23 @@ func (p *PullRequestStackPullRequest) GetDraft() bool { } // GetHead returns the Head field. -func (p *PullRequestStackPullRequest) GetHead() *PullRequestStackBranch { +func (p *PullRequestStackMinimalEntry) GetHead() *PullRequestStackMinimalHead { if p == nil { return nil } return p.Head } -// GetHTMLURL returns the HTMLURL field. -func (p *PullRequestStackPullRequest) GetHTMLURL() string { - if p == nil { - return "" - } - return p.HTMLURL -} - -// GetID returns the ID field. -func (p *PullRequestStackPullRequest) GetID() int64 { - if p == nil { - return 0 - } - return p.ID -} - // GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise. -func (p *PullRequestStackPullRequest) GetMergedAt() Timestamp { +func (p *PullRequestStackMinimalEntry) GetMergedAt() Timestamp { if p == nil || p.MergedAt == nil { return Timestamp{} } return *p.MergedAt } -// GetNodeID returns the NodeID field. -func (p *PullRequestStackPullRequest) GetNodeID() string { - if p == nil { - return "" - } - return p.NodeID -} - // GetNumber returns the Number field. -func (p *PullRequestStackPullRequest) GetNumber() int { +func (p *PullRequestStackMinimalEntry) GetNumber() int { if p == nil { return 0 } @@ -32351,35 +32359,27 @@ func (p *PullRequestStackPullRequest) GetNumber() int { } // GetState returns the State field. -func (p *PullRequestStackPullRequest) GetState() string { +func (p *PullRequestStackMinimalEntry) GetState() string { if p == nil { return "" } return p.State } -// GetTitle returns the Title field. -func (p *PullRequestStackPullRequest) GetTitle() string { +// GetRef returns the Ref field. +func (p *PullRequestStackMinimalHead) GetRef() string { if p == nil { return "" } - return p.Title + return p.Ref } -// GetURL returns the URL field. -func (p *PullRequestStackPullRequest) GetURL() string { +// GetSHA returns the SHA field. +func (p *PullRequestStackMinimalHead) GetSHA() string { if p == nil { return "" } - return p.URL -} - -// GetUser returns the User field. -func (p *PullRequestStackPullRequest) GetUser() *User { - if p == nil { - return nil - } - return p.User + return p.SHA } // GetRef returns the Ref field. diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 8a734b46344..3ad94da87bc 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -40310,7 +40310,7 @@ func TestPullRequestStackDetails_GetOpen(tt *testing.T) { func TestPullRequestStackDetails_GetPullRequests(tt *testing.T) { tt.Parallel() - zeroValue := []*PullRequestStackPullRequest{} + zeroValue := []*PullRequestStackEntry{} p := &PullRequestStackDetails{PullRequests: zeroValue} p.GetPullRequests() p = &PullRequestStackDetails{} @@ -40327,229 +40327,229 @@ func TestPullRequestStackDetails_GetURL(tt *testing.T) { p.GetURL() } -func TestPullRequestStackMinimal_GetBase(tt *testing.T) { +func TestPullRequestStackEntry_GetBase(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimal{} + p := &PullRequestStackEntry{} p.GetBase() p = nil p.GetBase() } -func TestPullRequestStackMinimal_GetCreatedAt(tt *testing.T) { +func TestPullRequestStackEntry_GetDraft(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimal{} - p.GetCreatedAt() + p := &PullRequestStackEntry{} + p.GetDraft() p = nil - p.GetCreatedAt() + p.GetDraft() } -func TestPullRequestStackMinimal_GetID(tt *testing.T) { +func TestPullRequestStackEntry_GetHead(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimal{} + p := &PullRequestStackEntry{} + p.GetHead() + p = nil + p.GetHead() +} + +func TestPullRequestStackEntry_GetHTMLURL(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackEntry{} + p.GetHTMLURL() + p = nil + p.GetHTMLURL() +} + +func TestPullRequestStackEntry_GetID(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackEntry{} p.GetID() p = nil p.GetID() } -func TestPullRequestStackMinimal_GetNodeID(tt *testing.T) { +func TestPullRequestStackEntry_GetMergedAt(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimal{} + var zeroValue Timestamp + p := &PullRequestStackEntry{MergedAt: &zeroValue} + p.GetMergedAt() + p = &PullRequestStackEntry{} + p.GetMergedAt() + p = nil + p.GetMergedAt() +} + +func TestPullRequestStackEntry_GetNodeID(tt *testing.T) { + tt.Parallel() + p := &PullRequestStackEntry{} p.GetNodeID() p = nil p.GetNodeID() } -func TestPullRequestStackMinimal_GetNumber(tt *testing.T) { +func TestPullRequestStackEntry_GetNumber(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimal{} + p := &PullRequestStackEntry{} p.GetNumber() p = nil p.GetNumber() } -func TestPullRequestStackMinimal_GetOpen(tt *testing.T) { +func TestPullRequestStackEntry_GetState(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimal{} - p.GetOpen() + p := &PullRequestStackEntry{} + p.GetState() p = nil - p.GetOpen() + p.GetState() } -func TestPullRequestStackMinimal_GetPullRequests(tt *testing.T) { +func TestPullRequestStackEntry_GetTitle(tt *testing.T) { tt.Parallel() - zeroValue := []*PullRequestStackMinimalPullRequest{} - p := &PullRequestStackMinimal{PullRequests: zeroValue} - p.GetPullRequests() - p = &PullRequestStackMinimal{} - p.GetPullRequests() + p := &PullRequestStackEntry{} + p.GetTitle() p = nil - p.GetPullRequests() + p.GetTitle() } -func TestPullRequestStackMinimal_GetURL(tt *testing.T) { +func TestPullRequestStackEntry_GetURL(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimal{} + p := &PullRequestStackEntry{} p.GetURL() p = nil p.GetURL() } -func TestPullRequestStackMinimalBranch_GetRef(tt *testing.T) { +func TestPullRequestStackEntry_GetUser(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimalBranch{} - p.GetRef() + p := &PullRequestStackEntry{} + p.GetUser() p = nil - p.GetRef() + p.GetUser() } -func TestPullRequestStackMinimalBranch_GetSHA(tt *testing.T) { +func TestPullRequestStackMinimal_GetBase(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimalBranch{} - p.GetSHA() + p := &PullRequestStackMinimal{} + p.GetBase() p = nil - p.GetSHA() + p.GetBase() } -func TestPullRequestStackMinimalPullRequest_GetDraft(tt *testing.T) { +func TestPullRequestStackMinimal_GetCreatedAt(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimalPullRequest{} - p.GetDraft() + p := &PullRequestStackMinimal{} + p.GetCreatedAt() p = nil - p.GetDraft() + p.GetCreatedAt() } -func TestPullRequestStackMinimalPullRequest_GetHead(tt *testing.T) { +func TestPullRequestStackMinimal_GetID(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimalPullRequest{} - p.GetHead() + p := &PullRequestStackMinimal{} + p.GetID() p = nil - p.GetHead() + p.GetID() } -func TestPullRequestStackMinimalPullRequest_GetMergedAt(tt *testing.T) { +func TestPullRequestStackMinimal_GetNodeID(tt *testing.T) { tt.Parallel() - var zeroValue Timestamp - p := &PullRequestStackMinimalPullRequest{MergedAt: &zeroValue} - p.GetMergedAt() - p = &PullRequestStackMinimalPullRequest{} - p.GetMergedAt() + p := &PullRequestStackMinimal{} + p.GetNodeID() p = nil - p.GetMergedAt() + p.GetNodeID() } -func TestPullRequestStackMinimalPullRequest_GetNumber(tt *testing.T) { +func TestPullRequestStackMinimal_GetNumber(tt *testing.T) { tt.Parallel() - p := &PullRequestStackMinimalPullRequest{} + p := &PullRequestStackMinimal{} p.GetNumber() p = nil p.GetNumber() } -func TestPullRequestStackMinimalPullRequest_GetState(tt *testing.T) { - tt.Parallel() - p := &PullRequestStackMinimalPullRequest{} - p.GetState() - p = nil - p.GetState() -} - -func TestPullRequestStackPullRequest_GetBase(tt *testing.T) { +func TestPullRequestStackMinimal_GetOpen(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetBase() + p := &PullRequestStackMinimal{} + p.GetOpen() p = nil - p.GetBase() + p.GetOpen() } -func TestPullRequestStackPullRequest_GetDraft(tt *testing.T) { +func TestPullRequestStackMinimal_GetPullRequests(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetDraft() + zeroValue := []*PullRequestStackMinimalEntry{} + p := &PullRequestStackMinimal{PullRequests: zeroValue} + p.GetPullRequests() + p = &PullRequestStackMinimal{} + p.GetPullRequests() p = nil - p.GetDraft() + p.GetPullRequests() } -func TestPullRequestStackPullRequest_GetHead(tt *testing.T) { +func TestPullRequestStackMinimal_GetURL(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetHead() + p := &PullRequestStackMinimal{} + p.GetURL() p = nil - p.GetHead() + p.GetURL() } -func TestPullRequestStackPullRequest_GetHTMLURL(tt *testing.T) { +func TestPullRequestStackMinimalEntry_GetDraft(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetHTMLURL() + p := &PullRequestStackMinimalEntry{} + p.GetDraft() p = nil - p.GetHTMLURL() + p.GetDraft() } -func TestPullRequestStackPullRequest_GetID(tt *testing.T) { +func TestPullRequestStackMinimalEntry_GetHead(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetID() + p := &PullRequestStackMinimalEntry{} + p.GetHead() p = nil - p.GetID() + p.GetHead() } -func TestPullRequestStackPullRequest_GetMergedAt(tt *testing.T) { +func TestPullRequestStackMinimalEntry_GetMergedAt(tt *testing.T) { tt.Parallel() var zeroValue Timestamp - p := &PullRequestStackPullRequest{MergedAt: &zeroValue} + p := &PullRequestStackMinimalEntry{MergedAt: &zeroValue} p.GetMergedAt() - p = &PullRequestStackPullRequest{} + p = &PullRequestStackMinimalEntry{} p.GetMergedAt() p = nil p.GetMergedAt() } -func TestPullRequestStackPullRequest_GetNodeID(tt *testing.T) { - tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetNodeID() - p = nil - p.GetNodeID() -} - -func TestPullRequestStackPullRequest_GetNumber(tt *testing.T) { +func TestPullRequestStackMinimalEntry_GetNumber(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} + p := &PullRequestStackMinimalEntry{} p.GetNumber() p = nil p.GetNumber() } -func TestPullRequestStackPullRequest_GetState(tt *testing.T) { +func TestPullRequestStackMinimalEntry_GetState(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} + p := &PullRequestStackMinimalEntry{} p.GetState() p = nil p.GetState() } -func TestPullRequestStackPullRequest_GetTitle(tt *testing.T) { - tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetTitle() - p = nil - p.GetTitle() -} - -func TestPullRequestStackPullRequest_GetURL(tt *testing.T) { +func TestPullRequestStackMinimalHead_GetRef(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetURL() + p := &PullRequestStackMinimalHead{} + p.GetRef() p = nil - p.GetURL() + p.GetRef() } -func TestPullRequestStackPullRequest_GetUser(tt *testing.T) { +func TestPullRequestStackMinimalHead_GetSHA(tt *testing.T) { tt.Parallel() - p := &PullRequestStackPullRequest{} - p.GetUser() + p := &PullRequestStackMinimalHead{} + p.GetSHA() p = nil - p.GetUser() + p.GetSHA() } func TestPullRequestStackRef_GetRef(tt *testing.T) { diff --git a/github/pulls_stacks.go b/github/pulls_stacks.go index 55330c93901..39377a711a3 100644 --- a/github/pulls_stacks.go +++ b/github/pulls_stacks.go @@ -57,12 +57,12 @@ type PullRequestStackDetails struct { // CreatedAt is the time the stack was created. CreatedAt Timestamp `json:"created_at"` // PullRequests contains the pull requests in the stack, from bottom to top. - PullRequests []*PullRequestStackPullRequest `json:"pull_requests"` + PullRequests []*PullRequestStackEntry `json:"pull_requests"` } -// PullRequestStackPullRequest represents a pull request in a stack returned by +// PullRequestStackEntry represents a pull request in a stack returned by // PullRequestsService.CreateStack, GetStack, AddToStack, and Unstack. -type PullRequestStackPullRequest struct { +type PullRequestStackEntry struct { // ID is the ID of the pull request. ID int64 `json:"id"` // Number is the number of the pull request. @@ -131,12 +131,12 @@ type PullRequestStackMinimal struct { // CreatedAt is the time the stack was created. CreatedAt Timestamp `json:"created_at"` // PullRequests contains the pull requests in the stack, from bottom to top. - PullRequests []*PullRequestStackMinimalPullRequest `json:"pull_requests"` + PullRequests []*PullRequestStackMinimalEntry `json:"pull_requests"` } -// PullRequestStackMinimalPullRequest represents a pull request in a stack +// PullRequestStackMinimalEntry represents a pull request in a stack // returned by PullRequestsService.ListStacks. -type PullRequestStackMinimalPullRequest struct { +type PullRequestStackMinimalEntry struct { // Number is the number of the pull request. Number int `json:"number"` // State is the state of the pull request. Possible values are: "open" and "closed". @@ -146,12 +146,12 @@ type PullRequestStackMinimalPullRequest struct { // MergedAt is the time the pull request was merged, or nil if it is unmerged. MergedAt *Timestamp `json:"merged_at"` // Head is the branch the pull request merges from. - Head *PullRequestStackMinimalBranch `json:"head"` + Head *PullRequestStackMinimalHead `json:"head"` } -// PullRequestStackMinimalBranch represents the head branch of a pull request +// PullRequestStackMinimalHead represents the head branch of a pull request // returned by PullRequestsService.ListStacks. -type PullRequestStackMinimalBranch struct { +type PullRequestStackMinimalHead struct { // Ref is the name of the branch. Ref string `json:"ref"` // SHA is the SHA of the most recent commit on the branch. diff --git a/github/pulls_stacks_test.go b/github/pulls_stacks_test.go index b2493ac1c4b..42d0c5b959c 100644 --- a/github/pulls_stacks_test.go +++ b/github/pulls_stacks_test.go @@ -54,7 +54,7 @@ func testPullRequestStackDetails() *PullRequestStackDetails { Base: &PullRequestStackRef{Ref: "main"}, Open: true, CreatedAt: referenceTimestamp, - PullRequests: []*PullRequestStackPullRequest{{ + PullRequests: []*PullRequestStackEntry{{ ID: 1001, Number: 101, NodeID: "PR_kwDOABCDEF4AAAAA", @@ -106,11 +106,11 @@ func testPullRequestStackMinimal() *PullRequestStackMinimal { Base: &PullRequestStackRef{Ref: "main"}, Open: true, CreatedAt: referenceTimestamp, - PullRequests: []*PullRequestStackMinimalPullRequest{{ + PullRequests: []*PullRequestStackMinimalEntry{{ Number: 101, State: "open", Draft: false, - Head: &PullRequestStackMinimalBranch{ + Head: &PullRequestStackMinimalHead{ Ref: "feature", SHA: "abc123", },