KEMBAR78
Inconsistent use of template flags between `gh pr create --template` and `gh issue create --template` · Issue #10202 · cli/cli · GitHub
Skip to content

Inconsistent use of template flags between gh pr create --template and gh issue create --template #10202

@andyfeller

Description

@andyfeller

Describe the bug

There are different, inconsistent behaviors using templates for creating issues versus pull requests along with incorrect documentation on the feature.

Both gh pr create --template and gh issue create --template say they use remote template file names ...

cmd.Flags().StringVarP(&opts.Template, "template", "T", "", "Template `file` to use as starting body text")

fl.StringVarP(&opts.Template, "template", "T", "", "Template `file` to use as starting body text")

Underlying code shows that only pull request templates have filename retrieved whereas issue templates use template name ...

type issueTemplate struct {
Gname string `graphql:"name"`
Gbody string `graphql:"body"`
Gtitle string `graphql:"title"`
}
type pullRequestTemplate struct {
Gname string `graphql:"filename"`
Gbody string `graphql:"body"`
}
func (t *issueTemplate) Name() string {
return t.Gname
}

This leads to inconsistent feature behaviors when selecting a template based on user input

func (m *templateManager) Select(name string) (Template, error) {
if err := m.memoizedFetch(); err != nil {
return nil, err
}
if len(m.templates) == 0 {
return nil, errors.New("no templates found")
}
for _, t := range m.templates {
if t.Name() == name {
return t, nil
}
}
return nil, fmt.Errorf("template %q not found", name)
}

Steps to reproduce the behavior

  1. Create markdown-based issue template in repository

    • Use foo-issue.md for the template filename
    • Use "Foo Issue" for the template name

    NOTE: This should not be an issue form as those are not supported by API or GitHub CLI currently.

  2. Create pull request template in repository

    • Use foo-pr.md for the template filename
    • Use "Foo PR" for the template name
  3. Successfully create pull request using template's filename: gh pr create --template foo-pr.md

  4. Unsuccessfully create pull request using template's name: gh pr create --template "Foo PR"

  5. Unsuccessfully create issue using template's filename: gh issue create --template foo-issue.md

  6. Successfully create issue using template's filename: gh issue create --template "Foo Issue"

Expected vs actual behavior

I expect gh pr create --template and gh issue create --template experiences to be consistent; basically pick one:

  1. Check only template names
  2. Check only template filenames
  3. Check both template names and filenames

Logs

➜  planning git:(main) ✗  GH_DEBUG=api gh issue create --template "bug_report.md"
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2025-01-08 17:24:56.51639 +0100 CET m=+0.181550667
* Request to https://api.github.com/graphql
> POST /graphql HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: token ████████████████████
> Content-Length: 390
> Content-Type: application/json; charset=utf-8
> Graphql-Features: merge_queue
> Time-Zone: Europe/Berlin
> User-Agent: GitHub CLI 2.58.0

GraphQL query:
fragment repo on Repository {
    id
    name
    owner { login }
    viewerPermission
    defaultBranchRef {
      name
    }
    isPrivate
  }
  query RepositoryNetwork {
    viewer { login }
    
    repo_000: repository(owner: "nors-24", name: "planning") {
      ...repo
      parent {
        ...repo
      }
    }
    
  }
GraphQL variables: null

< HTTP/2.0 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
< Content-Security-Policy: default-src 'none'
< Content-Type: application/json; charset=utf-8
< Date: Wed, 08 Jan 2025 16:24:56 GMT
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: github.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept-Encoding, Accept, X-Requested-With
< X-Accepted-Oauth-Scopes: repo
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Media-Type: github.v4; param=merge-info-preview.nebula-preview; format=json
< X-Github-Request-Id: F0FD:EBDF7:1A0CBB:1A844F:677EA6D8
< X-Oauth-Client-Id: 178c6fc778ccc68e1d6a
< X-Oauth-Scopes: admin:public_key, codespace, gist, read:org, read:packages, repo, workflow
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 5000
< X-Ratelimit-Reset: 1736356418
< X-Ratelimit-Resource: graphql
< X-Ratelimit-Used: 99
< X-Xss-Protection: 0

{
  "data": {
    "viewer": {
      "login": "norascheuch"
    },
    "repo_000": {
      "id": "R_kgDONVDy7g",
      "name": "planning",
      "owner": {
        "login": "nors-24"
      },
      "viewerPermission": "ADMIN",
      "defaultBranchRef": {
        "name": "main"
      },
      "isPrivate": true,
      "parent": null
    }
  }
}

* Request took 369.033167ms

Creating issue in nors-24/planning

* Request at 2025-01-08 17:24:56.93244 +0100 CET m=+0.597596917
* Request to https://api.github.com/graphql
> POST /graphql HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: token ████████████████████
> Content-Length: 517
> Content-Type: application/json; charset=utf-8
> Graphql-Features: merge_queue
> Time-Zone: Europe/Berlin
> User-Agent: GitHub CLI 2.58.0

GraphQL query:
fragment repo on Repository {
    id
    name
    owner { login }
    hasIssuesEnabled
    description
    hasWikiEnabled
    viewerPermission
    defaultBranchRef {
      name
    }
  }

  query RepositoryInfo($owner: String!, $name: String!) {
    repository(owner: $owner, name: $name) {
      ...repo
      parent {
        ...repo
      }
      mergeCommitAllowed
      rebaseMergeAllowed
      squashMergeAllowed
    }
  }
GraphQL variables: {"name":"planning","owner":"nors-24"}

< HTTP/2.0 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
< Content-Security-Policy: default-src 'none'
< Content-Type: application/json; charset=utf-8
< Date: Wed, 08 Jan 2025 16:24:57 GMT
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: github.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept-Encoding, Accept, X-Requested-With
< X-Accepted-Oauth-Scopes: repo
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Media-Type: github.v4; param=merge-info-preview.nebula-preview; format=json
< X-Github-Request-Id: F0FD:EBDF7:1A0DD4:1A857F:677EA6D8
< X-Oauth-Client-Id: 178c6fc778ccc68e1d6a
< X-Oauth-Scopes: admin:public_key, codespace, gist, read:org, read:packages, repo, workflow
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 5000
< X-Ratelimit-Reset: 1736356418
< X-Ratelimit-Resource: graphql
< X-Ratelimit-Used: 100
< X-Xss-Protection: 0

{
  "data": {
    "repository": {
      "id": "R_kgDONVDy7g",
      "name": "planning",
      "owner": {
        "login": "nors-24"
      },
      "hasIssuesEnabled": true,
      "description": null,
      "hasWikiEnabled": false,
      "viewerPermission": "ADMIN",
      "defaultBranchRef": {
        "name": "main"
      },
      "parent": null,
      "mergeCommitAllowed": true,
      "rebaseMergeAllowed": true,
      "squashMergeAllowed": true
    }
  }
}

* Request took 344.753084ms
? Title title
* Request at 2025-01-08 17:26:03.396025 +0100 CET m=+67.060513626
* Request to https://api.github.com/graphql
> POST /graphql HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: token ████████████████████
> Content-Length: 185
> Content-Type: application/json
> Graphql-Features: merge_queue
> Time-Zone: Europe/Berlin
> User-Agent: GitHub CLI 2.58.0

GraphQL query:
query IssueTemplates($name:String!$owner:String!){repository(owner: $owner, name: $name){issueTemplates{name,body,title}}}
GraphQL variables: {"name":"planning","owner":"nors-24"}

< HTTP/2.0 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
< Content-Security-Policy: default-src 'none'
< Content-Type: application/json; charset=utf-8
< Date: Wed, 08 Jan 2025 16:26:03 GMT
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: github.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept-Encoding, Accept, X-Requested-With
< X-Accepted-Oauth-Scopes: repo
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Media-Type: github.v4; param=merge-info-preview.nebula-preview; format=json
< X-Github-Request-Id: F110:F3BC3:1C3B40:1CB774:677EA71B
< X-Oauth-Client-Id: 178c6fc778ccc68e1d6a
< X-Oauth-Scopes: admin:public_key, codespace, gist, read:org, read:packages, repo, workflow
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 5000
< X-Ratelimit-Reset: 1736356418
< X-Ratelimit-Resource: graphql
< X-Ratelimit-Used: 117
< X-Xss-Protection: 0

{
  "data": {
    "repository": {
      "issueTemplates": [
        {
          "name": "Bug report",
          "body": "**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n - Browser [e.g. chrome, safari]\n - Version [e.g. 22]\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. iPhone6]\n - OS: [e.g. iOS8.1]\n - Browser [e.g. stock browser, safari]\n - Version [e.g. 22]\n\n**Additional context**\nAdd any other context about the problem here.\n",
          "title": ""
        },
        {
          "name": "Task Issue",
          "body": "# Notes\n",
          "title": ""
        },
        {
          "name": "Tracking Issue",
          "body": "# Tracked Issue:\n - [ ] \n\n# Related PRs:\n - [ ] \n\n# Notes\n",
          "title": ""
        }
      ]
    }
  }
}

* Request took 449.228291ms
[git rev-parse --show-toplevel]

X operation failed. To restore: gh issue create --recover /var/folders/_p/rfdm0l5x105flclh25v17tpr0000gn/T/gh1852231467.json

template "bug_report.md" not found

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggh-issuerelating to the gh issue commandgh-prrelating to the gh pr commandneeds-triageneeds to be reviewed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions