mirror of
https://github.com/github/gh-stack.git
synced 2026-09-14 20:26:28 +08:00
a82dc3ef1d
* Add stack Number field to local model and schema
The new Stacks REST API exposes a human-facing stack number (shown in the
github.com UI) alongside the internal stack id. Add a Number field to the
stack.Stack model and document it in schema.json so it can be persisted in
the .git/gh-stack file. Purely additive; behavior is unchanged until callers
populate it.
Copilot-Session: 03673c26-a245-42da-93ed-dfcebc92a740
* Cut over stack operations to the public Stacks REST API
Replace the private cli_internal stack endpoints with the new public
Stacks REST API (/repos/{owner}/{repo}/stacks):
- ListStacks / FindStackForPR (?pull_request= filter) / GetStack for reads
- CreateStack, which now returns the created stack including its number
- AddToStack for delta-only appends (there is no full-replace endpoint)
- Unstack for server-driven removal (204 dissolved / 200 partial / 422)
Migrate all callers (checkout, submit, link, sync, unstack, utils) and
drop the client-side unstack eligibility pre-check — the server now
decides which PRs can be unstacked. checkout discovers stacks via the
pull_request filter; submit/link express updates as append-only deltas;
unstack adopts partial-unstack semantics, keeping local tracking when
PRs remain stacked on GitHub.
RemoteStack now carries the stack number, and stack updates resolve a
stack's number from its internal id for stack files that predate the
Number field.
Copilot-Session: 03673c26-a245-42da-93ed-dfcebc92a740
* Remove the personal access token (PAT) limitation
The new Stacks REST API is public, so any user authenticated with the
GitHub CLI (including via a PAT with repo scope) can perform stack
operations once the feature is enabled for their repository. Remove the
PAT detection and the private-preview gating:
- Delete Config.WarnIfPAT / IsPersonalAccessToken and the TokenForHostFn
test hook (internal/config/auth.go is no longer needed).
- Drop the submit pre-flight that aborted on a PAT.
- Rename warnStacksUnavailableOrPAT to warnStacksUnavailable and simplify
it to the "stacked PRs not enabled" message.
Copilot-Session: 03673c26-a245-42da-93ed-dfcebc92a740
* address review comments
115 lines
3.2 KiB
Go
115 lines
3.2 KiB
Go
package github
|
|
|
|
// MockClient is a test double for GitHub API operations.
|
|
// Each field is an optional function that, when set, handles the corresponding
|
|
// ClientOps method call. When nil, a reasonable default is returned.
|
|
type MockClient struct {
|
|
FindPRForBranchFn func(string) (*PullRequest, error)
|
|
FindPRByNumberFn func(int) (*PullRequest, error)
|
|
FindPRDetailsForBranchFn func(string) (*PRDetails, error)
|
|
CreatePRFn func(string, string, string, string, bool) (*PullRequest, error)
|
|
UpdatePRBaseFn func(int, string) error
|
|
MarkPRReadyForReviewFn func(string) error
|
|
DisableAutoMergeFn func(string) error
|
|
ListStacksFn func() ([]RemoteStack, error)
|
|
FindStackForPRFn func(int) (*RemoteStack, error)
|
|
GetStackFn func(int) (*RemoteStack, error)
|
|
CreateStackFn func([]int) (*RemoteStack, error)
|
|
AddToStackFn func(int, []int) (*RemoteStack, error)
|
|
UnstackFn func(int) (*RemoteStack, bool, error)
|
|
}
|
|
|
|
// Compile-time check that MockClient satisfies ClientOps.
|
|
var _ ClientOps = (*MockClient)(nil)
|
|
|
|
func (m *MockClient) FindPRForBranch(branch string) (*PullRequest, error) {
|
|
if m.FindPRForBranchFn != nil {
|
|
return m.FindPRForBranchFn(branch)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *MockClient) FindPRByNumber(number int) (*PullRequest, error) {
|
|
if m.FindPRByNumberFn != nil {
|
|
return m.FindPRByNumberFn(number)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *MockClient) FindPRDetailsForBranch(branch string) (*PRDetails, error) {
|
|
if m.FindPRDetailsForBranchFn != nil {
|
|
return m.FindPRDetailsForBranchFn(branch)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *MockClient) CreatePR(base, head, title, body string, draft bool) (*PullRequest, error) {
|
|
if m.CreatePRFn != nil {
|
|
return m.CreatePRFn(base, head, title, body, draft)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *MockClient) UpdatePRBase(number int, base string) error {
|
|
if m.UpdatePRBaseFn != nil {
|
|
return m.UpdatePRBaseFn(number, base)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *MockClient) MarkPRReadyForReview(prID string) error {
|
|
if m.MarkPRReadyForReviewFn != nil {
|
|
return m.MarkPRReadyForReviewFn(prID)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *MockClient) DisableAutoMerge(prID string) error {
|
|
if m.DisableAutoMergeFn != nil {
|
|
return m.DisableAutoMergeFn(prID)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *MockClient) ListStacks() ([]RemoteStack, error) {
|
|
if m.ListStacksFn != nil {
|
|
return m.ListStacksFn()
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *MockClient) FindStackForPR(prNumber int) (*RemoteStack, error) {
|
|
if m.FindStackForPRFn != nil {
|
|
return m.FindStackForPRFn(prNumber)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *MockClient) GetStack(stackNumber int) (*RemoteStack, error) {
|
|
if m.GetStackFn != nil {
|
|
return m.GetStackFn(stackNumber)
|
|
}
|
|
return &RemoteStack{}, nil
|
|
}
|
|
|
|
func (m *MockClient) CreateStack(prNumbers []int) (*RemoteStack, error) {
|
|
if m.CreateStackFn != nil {
|
|
return m.CreateStackFn(prNumbers)
|
|
}
|
|
return &RemoteStack{}, nil
|
|
}
|
|
|
|
func (m *MockClient) AddToStack(stackNumber int, prNumbers []int) (*RemoteStack, error) {
|
|
if m.AddToStackFn != nil {
|
|
return m.AddToStackFn(stackNumber, prNumbers)
|
|
}
|
|
return &RemoteStack{}, nil
|
|
}
|
|
|
|
func (m *MockClient) Unstack(stackNumber int) (*RemoteStack, bool, error) {
|
|
if m.UnstackFn != nil {
|
|
return m.UnstackFn(stackNumber)
|
|
}
|
|
return nil, false, nil
|
|
}
|