Skip to content

feat(pr create): add --json and --jq output#12622

Closed
LouisLau-art wants to merge 1 commit into
cli:trunkfrom
LouisLau-art:feat/pr-create-json-output
Closed

feat(pr create): add --json and --jq output#12622
LouisLau-art wants to merge 1 commit into
cli:trunkfrom
LouisLau-art:feat/pr-create-json-output

Conversation

@LouisLau-art

Copy link
Copy Markdown

Fixes #11247.

Summary

  • Add --json and --jq support to gh pr create via a new cmdutil.AddJSONAndJQFlags helper (no JSON --template flag).
  • Make JSON flag validation aware of commands that do not use JSON templating.
  • Keep gh pr create --template <file> independent from JSON output mode.
  • Reject --dry-run together with --json for gh pr create.
  • Include number in the CreatePullRequest mutation response so --json number works.

Test

  • go test ./pkg/cmdutil ./pkg/cmd/pr/create ./api

@LouisLau-art LouisLau-art requested a review from a team as a code owner February 6, 2026 02:28
@LouisLau-art LouisLau-art requested a review from babakks February 6, 2026 02:28
@cliAutomation cliAutomation added the external pull request originating outside of the CLI core team label Feb 6, 2026
@LouisLau-art LouisLau-art force-pushed the feat/pr-create-json-output branch from 509440e to 42ed61f Compare March 3, 2026 08:45
@LouisLau-art

Copy link
Copy Markdown
Author

Rebased this branch onto the latest trunk and force-pushed a clean branch with just the feature commit.

This should address the stale govulncheck/old-base CI issue caused by the previous 121-commit drift from trunk.

Local verification run:

  • go test ./pkg/cmd/pr/create ./pkg/cmdutil ./api
  • all passed

@babakks babakks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, @LouisLau-art, and sorry for the late review! 🙏

I haven't yet tried it to create a real PR, but the PR looks very good so that I'm mostly confident the changes are in the right direction. It just needs a few changes.

Once you update the branch, I'll go over the changes again and do proper end-to-end tests.

Comment thread api/queries_pr.go
Comment on lines +560 to +565
createPullRequest(input: $input) {
pullRequest {
id
number
url
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remote the extra tab:

Suggested change
createPullRequest(input: $input) {
pullRequest {
id
number
url
}
createPullRequest(input: $input) {
pullRequest {
id
number
url
}

opts.Body = "my body"
opts.HeadBranch = "feature"
exporter := cmdutil.NewJSONExporter()
exporter.SetFields([]string{"id", "url", "number"})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the inline slice, it's better to use the createOutputFields variable in here, to make sure we're covering all fields here.

Suggested change
exporter.SetFields([]string{"id", "url", "number"})
exporter.SetFields(createOutputFields)

Exporter cmdutil.Exporter
}

var createOutputFields = []string{"id", "url", "number"}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a test for this, similar to:

func TestJSONFields(t *testing.T) {
jsonfieldstest.ExpectCommandToSupportJSONFields(t, NewCmdView, []string{
"additions",
"assignees",
"author",
"autoMergeRequest",
"baseRefName",
"baseRefOid",
"body",
"changedFiles",
"closed",
"closedAt",
"closingIssuesReferences",
"comments",
"commits",
"createdAt",
"deletions",
"files",
"fullDatabaseId",
"headRefName",
"headRefOid",
"headRepository",
"headRepositoryOwner",
"id",
"isCrossRepository",
"isDraft",
"labels",
"latestReviews",
"maintainerCanModify",
"mergeCommit",
"mergeStateStatus",
"mergeable",
"mergedAt",
"mergedBy",
"milestone",
"number",
"potentialMergeCommit",
"projectCards",
"projectItems",
"reactionGroups",
"reviewDecision",
"reviewRequests",
"reviews",
"state",
"statusCheckRollup",
"title",
"updatedAt",
"url",
})
}

Comment on lines -366 to +376
{ "data": { "createPullRequest": { "pullRequest": {
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`,
{ "data": { "createPullRequest": { "pullRequest": {
"ID": "PR_kwDOA",
"Number": 12,
"URL": "https://github.com/OWNER/REPO/pull/12"
} } } }`,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to also update all other test cases (lots of them, not just in this test function), to include the newly added number field. The correct notation should be number, but since we've used Pascal casing for ID and URL (I don't know why 🤷), I recommended keeping it (i.e. adding Number instead of number).

Comment thread pkg/cmdutil/json_flags.go
setupJsonFlags(cmd, exportTarget, fields, true)
}

func AddJSONAndJQFlags(cmd *cobra.Command, exportTarget *Exporter, fields []string) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a godoc above this to avoid future confusion/questions:

Suggested change
func AddJSONAndJQFlags(cmd *cobra.Command, exportTarget *Exporter, fields []string) {
// AddJSONAndJQFlags adds --json and --jq flags, but not --template. Shorthands are also omitted.
//
// Meant to be used in cases where --template (or -t) is already taken.
func AddJSONAndJQFlags(cmd *cobra.Command, exportTarget *Exporter, fields []string) {

Comment thread pkg/cmdutil/json_flags.go
Comment on lines +135 to +144
var tplFlag *pflag.Flag
if withTemplateFlag {
tplFlag = f.Lookup("template")
}

templateValue := ""
if tplFlag != nil {
templateValue = tplFlag.Value.String()
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's simplify this:

Suggested change
var tplFlag *pflag.Flag
if withTemplateFlag {
tplFlag = f.Lookup("template")
}
templateValue := ""
if tplFlag != nil {
templateValue = tplFlag.Value.String()
}
var tplFlag *pflag.Flag
var templateValue string
if withTemplateFlag {
tplFlag = f.Lookup("template")
templateValue = tplFlag.Value.String()
}

name string
fields []string
args []string
withTplFlag bool

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe name this field templateFlagTaken with a short comment on the intent:

Suggested change
withTplFlag bool
// templateFlagTaken indicates that the host command already has a --template flag for a different purpose (e.g. pr create).
templateFlagTaken bool

@babakks

babakks commented May 13, 2026

Copy link
Copy Markdown
Member

I'm closing this PR in favour of #13348 as seems to be stale now.

@babakks babakks closed this May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external pull request originating outside of the CLI core team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add --json and --jq to gh pr create

3 participants