Files
github__gh-stack/internal/stack/schema.json
T
Sameen Karim a82dc3ef1d Migrate to new Stacks REST API (#177)
* 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
2026-07-15 12:07:44 -04:00

105 lines
3.4 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "gh-stack file",
"description": "Schema for the .git/gh-stack file that stores the state of all stacks in a repository.",
"type": "object",
"required": ["schemaVersion", "stacks"],
"properties": {
"schemaVersion": {
"type": "integer",
"const": 1,
"description": "Schema version for forward compatibility."
},
"repository": {
"type": "string",
"description": "The host:owner/name of the repository (e.g. 'github.com:github/gh-stack')."
},
"stacks": {
"type": "array",
"description": "All stacks tracked in this repository.",
"items": { "$ref": "#/$defs/stack" }
}
},
"$defs": {
"stack": {
"type": "object",
"description": "A single stack of branches.",
"required": ["trunk", "branches"],
"properties": {
"id": {
"type": "string",
"description": "Global identifier for this stack, populated from the API when available."
},
"number": {
"type": "integer",
"description": "Repo-scoped number identifying this stack, displayed in the GitHub UI. Used as the primary way to reference a stack."
},
"prefix": {
"type": "string",
"description": "Branch name prefix for the stack (e.g. 'myfeature')."
},
"numbered": {
"type": "boolean",
"description": "Whether to use auto-incrementing numbered branch names."
},
"trunk": {
"$ref": "#/$defs/branchRef",
"description": "The trunk (base) branch of the stack."
},
"branches": {
"type": "array",
"description": "Ordered list of branches in the stack, from bottom to top.",
"items": { "$ref": "#/$defs/branchRef" }
}
}
},
"branchRef": {
"type": "object",
"description": "A reference to a branch and its associated commit hash. For the trunk, 'head' stores the HEAD commit. For stacked branches, 'base' stores the parent branch's HEAD SHA at the time of last sync/rebase.",
"required": ["branch"],
"properties": {
"branch": {
"type": "string",
"description": "The branch name."
},
"head": {
"type": "string",
"description": "The HEAD commit SHA of this branch. Used for the trunk branch."
},
"base": {
"type": "string",
"description": "The parent branch's HEAD SHA at the time of last sync/rebase. Used to identify which commits are unique to this branch."
},
"pullRequest": {
"$ref": "#/$defs/pullRequestRef",
"description": "Associated pull request information, if a PR exists for this branch."
}
}
},
"pullRequestRef": {
"type": "object",
"description": "A snapshot of pull request metadata.",
"required": ["number"],
"properties": {
"number": {
"type": "integer",
"description": "The PR number, scoped to the repository."
},
"id": {
"type": "string",
"description": "The PR global node ID."
},
"url": {
"type": "string",
"format": "uri",
"description": "Direct URL to the pull request."
},
"merged": {
"type": "boolean",
"description": "Whether the pull request has been merged."
}
}
}
}
}