From 7bd1d44c398e26da4029c7579a73714e28357f1e Mon Sep 17 00:00:00 2001 From: Joel Jeske Date: Wed, 29 Jul 2026 14:00:36 -0500 Subject: [PATCH 1/4] feat(stacks) Add Stack field to PullRequest for stacked pull requests --- github/github-accessors.go | 48 ++++++++++++++++++++++++++ github/github-accessors_test.go | 60 +++++++++++++++++++++++++++++++++ github/github-stringify_test.go | 3 +- github/pulls.go | 13 +++++++ 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 710d26075ca..775d8bc76b1 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -30822,6 +30822,14 @@ func (p *PullRequest) GetReviewCommentURL() string { return *p.ReviewCommentURL } +// GetStack returns the Stack field. +func (p *PullRequest) GetStack() *PullRequestStack { + if p == nil { + return nil + } + return p.Stack +} + // GetState returns the State field if it's non-nil, zero value otherwise. func (p *PullRequest) GetState() string { if p == nil || p.State == nil { @@ -31982,6 +31990,46 @@ func (p *PullRequestRuleParameters) GetRequireLastPushApproval() bool { return p.RequireLastPushApproval } +// GetBase returns the Base field. +func (p *PullRequestStack) GetBase() *PullRequestBranch { + if p == nil { + return nil + } + 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 +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (p *PullRequestTargetEvent) GetAction() string { if p == nil || p.Action == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 5ae260f9ced..12852e360f9 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -38734,6 +38734,14 @@ func TestPullRequest_GetReviewCommentURL(tt *testing.T) { p.GetReviewCommentURL() } +func TestPullRequest_GetStack(tt *testing.T) { + tt.Parallel() + p := &PullRequest{} + p.GetStack() + p = nil + p.GetStack() +} + func TestPullRequest_GetState(tt *testing.T) { tt.Parallel() var zeroValue string @@ -40122,6 +40130,58 @@ func TestPullRequestRuleParameters_GetRequireLastPushApproval(tt *testing.T) { p.GetRequireLastPushApproval() } +func TestPullRequestStack_GetBase(tt *testing.T) { + tt.Parallel() + p := &PullRequestStack{} + p.GetBase() + p = nil + p.GetBase() +} + +func TestPullRequestStack_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + p := &PullRequestStack{ID: &zeroValue} + p.GetID() + p = &PullRequestStack{} + p.GetID() + p = nil + p.GetID() +} + +func TestPullRequestStack_GetNumber(tt *testing.T) { + tt.Parallel() + var zeroValue int + p := &PullRequestStack{Number: &zeroValue} + p.GetNumber() + p = &PullRequestStack{} + p.GetNumber() + p = nil + p.GetNumber() +} + +func TestPullRequestStack_GetPosition(tt *testing.T) { + tt.Parallel() + var zeroValue int + p := &PullRequestStack{Position: &zeroValue} + p.GetPosition() + p = &PullRequestStack{} + p.GetPosition() + p = nil + p.GetPosition() +} + +func TestPullRequestStack_GetSize(tt *testing.T) { + tt.Parallel() + var zeroValue int + p := &PullRequestStack{Size: &zeroValue} + p.GetSize() + p = &PullRequestStack{} + p.GetSize() + p = nil + p.GetSize() +} + func TestPullRequestTargetEvent_GetAction(tt *testing.T) { tt.Parallel() var zeroValue string diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index b45ec8fa3ab..cf6a7228ec6 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1661,9 +1661,10 @@ func TestPullRequest_String(t *testing.T) { Links: &PRLinks{}, Head: &PullRequestBranch{}, Base: &PullRequestBranch{}, + Stack: &PullRequestStack{}, ActiveLockReason: Ptr(""), } - want := `github.PullRequest{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, ClosedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, MergedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, User:github.User{}, Draft:false, URL:"", HTMLURL:"", IssueURL:"", StatusesURL:"", DiffURL:"", PatchURL:"", CommitsURL:"", CommentsURL:"", ReviewCommentsURL:"", ReviewCommentURL:"", Assignee:github.User{}, Milestone:github.Milestone{}, AuthorAssociation:"", NodeID:"", AutoMerge:github.PullRequestAutoMerge{}, Merged:false, Mergeable:false, MergeableState:"", Rebaseable:false, MergedBy:github.User{}, MergeCommitSHA:"", Comments:0, Commits:0, Additions:0, Deletions:0, ChangedFiles:0, MaintainerCanModify:false, ReviewComments:0, Links:github.PRLinks{}, Head:github.PullRequestBranch{}, Base:github.PullRequestBranch{}, ActiveLockReason:""}` + want := `github.PullRequest{ID:0, Number:0, State:"", Locked:false, Title:"", Body:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, ClosedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, MergedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, User:github.User{}, Draft:false, URL:"", HTMLURL:"", IssueURL:"", StatusesURL:"", DiffURL:"", PatchURL:"", CommitsURL:"", CommentsURL:"", ReviewCommentsURL:"", ReviewCommentURL:"", Assignee:github.User{}, Milestone:github.Milestone{}, AuthorAssociation:"", NodeID:"", AutoMerge:github.PullRequestAutoMerge{}, Merged:false, Mergeable:false, MergeableState:"", Rebaseable:false, MergedBy:github.User{}, MergeCommitSHA:"", Comments:0, Commits:0, Additions:0, Deletions:0, ChangedFiles:0, MaintainerCanModify:false, ReviewComments:0, Links:github.PRLinks{}, Head:github.PullRequestBranch{}, Base:github.PullRequestBranch{}, Stack:github.PullRequestStack{}, ActiveLockReason:""}` if got := v.String(); got != want { t.Errorf("PullRequest.String = %v, want %v", got, want) } diff --git a/github/pulls.go b/github/pulls.go index 27e3784876f..926684bca27 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -87,6 +87,7 @@ type PullRequest struct { Links *PRLinks `json:"_links,omitempty"` Head *PullRequestBranch `json:"head,omitempty"` Base *PullRequestBranch `json:"base,omitempty"` + Stack *PullRequestStack `json:"stack,omitempty"` // ActiveLockReason is populated only when LockReason is provided while locking the pull request. // Possible values are: "off-topic", "too heated", "resolved", and "spam". @@ -123,6 +124,18 @@ 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). +type PullRequestStack struct { + ID *int64 `json:"id,omitempty"` + Number *int `json:"number,omitempty"` + Base *PullRequestBranch `json:"base,omitempty"` + Size *int `json:"size,omitempty"` + Position *int `json:"position,omitempty"` +} + // PullRequestListOptions specifies the optional parameters to the // PullRequestsService.List method. type PullRequestListOptions struct { From 99ae1623688c2f9c5996c46c9382a4cb470b48c9 Mon Sep 17 00:00:00 2001 From: Joel Jeske Date: Wed, 29 Jul 2026 14:13:48 -0500 Subject: [PATCH 2/4] fix stack base ref, not a standard branch ref --- github/github-accessors.go | 18 +++++++++++++++++- github/github-accessors_test.go | 22 ++++++++++++++++++++++ github/pulls.go | 23 ++++++++++++++++++----- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 775d8bc76b1..b9819b51ccb 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -31991,7 +31991,7 @@ func (p *PullRequestRuleParameters) GetRequireLastPushApproval() bool { } // GetBase returns the Base field. -func (p *PullRequestStack) GetBase() *PullRequestBranch { +func (p *PullRequestStack) GetBase() *PullRequestStackBase { if p == nil { return nil } @@ -32030,6 +32030,22 @@ func (p *PullRequestStack) GetSize() int { return *p.Size } +// GetRef returns the Ref field if it's non-nil, zero value otherwise. +func (p *PullRequestStackBase) GetRef() string { + if p == nil || p.Ref == nil { + return "" + } + return *p.Ref +} + +// GetSHA returns the SHA field if it's non-nil, zero value otherwise. +func (p *PullRequestStackBase) GetSHA() string { + if p == nil || p.SHA == nil { + return "" + } + return *p.SHA +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (p *PullRequestTargetEvent) GetAction() string { if p == nil || p.Action == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 12852e360f9..109bed0b179 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -40182,6 +40182,28 @@ func TestPullRequestStack_GetSize(tt *testing.T) { p.GetSize() } +func TestPullRequestStackBase_GetRef(tt *testing.T) { + tt.Parallel() + var zeroValue string + p := &PullRequestStackBase{Ref: &zeroValue} + p.GetRef() + p = &PullRequestStackBase{} + p.GetRef() + p = nil + p.GetRef() +} + +func TestPullRequestStackBase_GetSHA(tt *testing.T) { + tt.Parallel() + var zeroValue string + p := &PullRequestStackBase{SHA: &zeroValue} + p.GetSHA() + p = &PullRequestStackBase{} + p.GetSHA() + p = nil + p.GetSHA() +} + func TestPullRequestTargetEvent_GetAction(tt *testing.T) { tt.Parallel() var zeroValue string diff --git a/github/pulls.go b/github/pulls.go index 926684bca27..c653b875d6a 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -129,11 +129,24 @@ type PullRequestBranch struct { // 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 { - ID *int64 `json:"id,omitempty"` - Number *int `json:"number,omitempty"` - Base *PullRequestBranch `json:"base,omitempty"` - Size *int `json:"size,omitempty"` - Position *int `json:"position,omitempty"` + // Base is the base of the stack: the branch the entire stack ultimately targets. + Base *PullRequestStackBase `json:"base,omitempty"` + // Size is the total number of pull requests in the stack. + Size *int `json:"size,omitempty"` + // 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 *int64 `json:"id,omitempty"` + // Number is the number of the stack that this pull request belongs to. + Number *int `json:"number,omitempty"` +} + +// PullRequestStackBase represents the base of a stacked pull request's stack: +// the branch the entire stack ultimately targets. +type PullRequestStackBase struct { + Ref *string `json:"ref,omitempty"` + SHA *string `json:"sha,omitempty"` } // PullRequestListOptions specifies the optional parameters to the From 01c551b255c2e4806c9bc8f1d40e4af19a12f22a Mon Sep 17 00:00:00 2001 From: Joel Jeske Date: Fri, 31 Jul 2026 07:51:18 -0500 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Dhananjay Mishra --- github/pulls.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/github/pulls.go b/github/pulls.go index c653b875d6a..81bc9f89535 100644 --- a/github/pulls.go +++ b/github/pulls.go @@ -130,7 +130,7 @@ type PullRequestBranch struct { // 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,omitempty"` + Base *PullRequestStackBase `json:"base"` // Size is the total number of pull requests in the stack. Size *int `json:"size,omitempty"` // Position is the one-based position of this pull request within the stack, @@ -145,8 +145,8 @@ type PullRequestStack struct { // PullRequestStackBase represents the base of a stacked pull request's stack: // the branch the entire stack ultimately targets. type PullRequestStackBase struct { - Ref *string `json:"ref,omitempty"` - SHA *string `json:"sha,omitempty"` + Ref string `json:"ref"` + SHA string `json:"sha"` } // PullRequestListOptions specifies the optional parameters to the From d2ff87e1d5ae20f861a89cd6bbb38dc5934c9990 Mon Sep 17 00:00:00 2001 From: Joel Jeske Date: Fri, 31 Jul 2026 07:59:44 -0500 Subject: [PATCH 4/4] regenerate --- github/github-accessors.go | 12 ++++++------ github/github-accessors_test.go | 10 ++-------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index b9819b51ccb..b28628a8be4 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -32030,20 +32030,20 @@ func (p *PullRequestStack) GetSize() int { return *p.Size } -// GetRef returns the Ref field if it's non-nil, zero value otherwise. +// GetRef returns the Ref field. func (p *PullRequestStackBase) GetRef() string { - if p == nil || p.Ref == nil { + if p == nil { return "" } - return *p.Ref + return p.Ref } -// GetSHA returns the SHA field if it's non-nil, zero value otherwise. +// GetSHA returns the SHA field. func (p *PullRequestStackBase) GetSHA() string { - if p == nil || p.SHA == nil { + if p == nil { return "" } - return *p.SHA + return p.SHA } // GetAction returns the Action field if it's non-nil, zero value otherwise. diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 109bed0b179..d0889dfa59c 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -40184,10 +40184,7 @@ func TestPullRequestStack_GetSize(tt *testing.T) { func TestPullRequestStackBase_GetRef(tt *testing.T) { tt.Parallel() - var zeroValue string - p := &PullRequestStackBase{Ref: &zeroValue} - p.GetRef() - p = &PullRequestStackBase{} + p := &PullRequestStackBase{} p.GetRef() p = nil p.GetRef() @@ -40195,10 +40192,7 @@ func TestPullRequestStackBase_GetRef(tt *testing.T) { func TestPullRequestStackBase_GetSHA(tt *testing.T) { tt.Parallel() - var zeroValue string - p := &PullRequestStackBase{SHA: &zeroValue} - p.GetSHA() - p = &PullRequestStackBase{} + p := &PullRequestStackBase{} p.GetSHA() p = nil p.GetSHA()