Skip to content

Conversation

@kerobbi
Copy link
Contributor

@kerobbi kerobbi commented Sep 10, 2025

This PR adds support for a state_reason parameter to the update_issue tool, enabling users to specify the reason when changing an issue's state (particularly when closing issues).

Valid values are: completed, not_planned, duplicate

When closing an issue as duplicate, the current implementation mandates the presence of duplicate_of (new parameter), specifying which issue the target issue is a duplicate of, replicating the user experience for duplicate management in the UI.

Status

  • The REST API allows closing an issue as duplicate, but does not give the ability to specify the issue the target issue is a duplicate of.
  • The GraphQL API offers the above functionality; however, the underlying shurcooL/githubv4 library does not fully align with what the API offers.

Chosen approach

  • REST API for base functionality, GraphQL API to close as duplicate.
  • Limitation: The underlying githubv4 library does not fully align with what the GraphQL API offers, custom structs need to be created to get this working.

Alternatives considered

REST API + automatic closing comment
  • Automatically post a comment (i.e., "Duplicate of X") before closing the issue.

  • Discarded because this introduces complexity for a feature that could be manually replicated using the add_issue_comment tool.

Contribute to shurcooL/githubv4
  • It is possible to open a PR in shurcooL/githubv4 and make the necessary changes for this work (i.e., update CloseIssue and CloseIssueInput structs).
  • Although a better approach, I've discarded this mainly due to the repo activity - it honestly seems like contributions have not been considered by the maintainer in a while

Future improvements

  • If and when up-to-date support for closing issues as duplicates is added in shurcooL/githubv4, we could remove the custom structs created for this PR.

Closes: #949

@kerobbi kerobbi requested a review from a team as a code owner September 10, 2025 09:36
Copilot AI review requested due to automatic review settings September 10, 2025 09:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for specifying reasons when changing issue states in the update_issue tool, with special handling for duplicate issues using the GraphQL API.

  • Adds state_reason parameter supporting values: completed, not_planned, duplicate, reopened
  • Adds duplicate_of parameter for specifying the target issue when marking as duplicate
  • Implements dual API approach: REST for basic state changes, GraphQL for duplicate handling

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/github/tools.go Updates UpdateIssue function signature to include GraphQL client
pkg/github/issues.go Adds state reason functionality with custom GraphQL structs and dual API logic
pkg/github/issues_test.go Adds comprehensive test coverage for new state reason functionality
pkg/github/toolsnaps/update_issue.snap Updates tool schema to include new state_reason and duplicate_of parameters
README.md Documents the new parameters in the tool reference

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@tonytrg tonytrg left a comment

Choose a reason for hiding this comment

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

Sorry couldn't do a full review today.

Thanks for tackling this complicate case 💯 , it is probably owed due to limitations of apis, but we are introducing a hefty amount of conditional branches. Can this maybe be simplified?

From what I am understanding from the pr description only state_reason duplicate require the graphql api. Can the graphql client relevant code be more isolated from the rest client code - for example any state change is solely handled by the graphql, if that is possible.

Copy link
Contributor

@LuluBeatson LuluBeatson left a comment

Choose a reason for hiding this comment

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

Great work! I've tried out the tool with all state changes

Only thing I'd suggest is reducing the complexity of the tool handler. Added some light suggestions of places, but feel free to think of your own ways.

if resp.StatusCode != http.StatusOK {
body, err := io.ReadAll(resp.Body)
// Handle GraphQL API updates (state_reason = "duplicate")
if gqlUpdateNeeded {
Copy link
Contributor

Choose a reason for hiding this comment

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

You could consider extracting into 2 separate functions for the REST and GraphQL updaters, which could make unit testing a bit easier.

It also seems like the GraphQL capabilities are a superset of the REST API, so could we use only GraphQL?

Copy link
Contributor Author

@kerobbi kerobbi Sep 11, 2025

Choose a reason for hiding this comment

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

Looked better into this and we could indeed use only GQL (i.e., updateIssue / updateIssueInput). However, I believe the current hybrid approach is actually more optimal, mainly due to the amount of ID resolution overhead that would be needed if we go full GQL. I did refactor everything for better readability/separation of concerns, but more than happy to review this further if needed.

Copy link
Contributor

@tonytrg tonytrg left a comment

Choose a reason for hiding this comment

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

Thank you, this looks great!

@tonytrg tonytrg merged commit b6486a3 into main Sep 12, 2025
16 checks passed
@tonytrg tonytrg deleted the kerobbi/add-state-change-reason branch September 12, 2025 14:04
nickytonline pushed a commit to nickytonline/github-mcp-http that referenced this pull request Oct 4, 2025
* add state_reason param

* add close as duplicate functionality

* refactor and improve tests

* fix state reason validation logic and update tests

* move state and state reason handling to gql

* fix marshal failures

* address latest feedback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ability to specify reason why issue is being closed, when closing issue

4 participants