Remove unnecessary StateReason and StateReasonDuplicate feature detection#12838
Remove unnecessary StateReason and StateReasonDuplicate feature detection#12838williammartin merged 2 commits intotrunkfrom
Conversation
The DUPLICATE enum variant for IssueClosedStateReason was added in GHES 3.16, which is older than the earliest supported GHES version. The feature detection check is therefore unnecessary. Addresses: #12811 (comment) Co-authored-by: Copilot <[email protected]>
The stateReason field was added in GHES ~3.4, which is far older than the earliest supported GHES version (3.14). The feature detection and conditional inclusion of stateReason is therefore unnecessary. This removes: - StateReason field from IssueFeatures struct - GHES introspection query in IssueFeatures() (only ActorIsAssignable remains, which is always false on GHES) - Conditional stateReason field inclusion in issue list - Feature detection guard in issue close - Feature detection guard in FindIssueOrPR Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
Removes IssueFeatures detection and conditional logic around Issue.stateReason / duplicate close reasons, based on the assumption these are now present on all supported GitHub hosts (including GHES), simplifying issue list/lookup queries and gh issue close behavior.
Changes:
- Simplifies
internal/featuredetection.IssueFeaturesto onlyActorIsAssignableand removes the GHES introspection query. - Always requests
stateReasonin issue list queries and stops stripping it in issue lookups. - Removes conditional fallback behavior (and related tests) for
--reason/--duplicate-ofon GHES.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/cmd/issue/shared/lookup.go | Removes conditional stripping of stateReason from issue/PR lookup GraphQL fields. |
| pkg/cmd/issue/list/list.go | Always includes stateReason in the default issue list field set. |
| pkg/cmd/issue/close/close.go | Removes feature-detection gating for close reasons and duplicate-of behavior. |
| pkg/cmd/issue/close/close_test.go | Deletes tests/mocks that asserted fallback behavior when close reasons/duplicate weren’t supported. |
| internal/featuredetection/feature_detection.go | Drops StateReason and StateReasonDuplicate from IssueFeatures and removes GHES schema introspection. |
| internal/featuredetection/feature_detection_test.go | Updates feature detection tests to match the simplified IssueFeatures. |
Comments suppressed due to low confidence (1)
pkg/cmd/issue/close/close.go:203
CloseIssueInputnow always includesstateReason/duplicateIssueIdwhen flags are used, without any compatibility fallback. If the CLI still supports GHES versions that predate theIssueClosedStateReasonvalues (andduplicateIssueIdsupport) or even thestateReasonfield (README says GHES 2.20+), this mutation will error on those instances. Consider either explicitly bumping the minimum supported GHES version in docs/release notes, or retaining a gated fallback that omits these inputs when unsupported.
switch reason {
case "":
// If no reason is specified do not set it.
case "not planned":
reason = "NOT_PLANNED"
case "duplicate":
reason = "DUPLICATE"
default:
reason = "COMPLETED"
}
var mutation struct {
CloseIssue struct {
Issue struct {
ID githubv4.ID
}
} `graphql:"closeIssue(input: $input)"`
}
variables := map[string]interface{}{
"input": CloseIssueInput{
IssueID: issue.ID,
StateReason: reason,
DuplicateIssueID: duplicateIssueID,
},
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func FindIssueOrPR(httpClient *http.Client, repo ghrepo.Interface, number int, fields []string) (*api.Issue, error) { | ||
| fieldSet := set.NewStringSet() | ||
| fieldSet.AddValues(fields) | ||
| if fieldSet.Contains("stateReason") { | ||
| cachedClient := api.NewCachedHTTPClient(httpClient, time.Hour*24) | ||
| detector := fd.NewDetector(cachedClient, repo.RepoHost()) | ||
| features, err := detector.IssueFeatures() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| // TODO stateReasonCleanup | ||
| if !features.StateReason { | ||
| fieldSet.Remove("stateReason") | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Feature detection for stateReason was removed here, so callers that include stateReason in fields will now always request it. If older GHES versions without Issue.stateReason are still within the supported range (README currently states GHES 2.20+), FindIssueOrPR will start failing with GraphQL schema errors. Either align/support-policy docs to guarantee stateReason availability, or reintroduce a compatibility gate before adding this field to the query.
| if opts.Detector == nil { | ||
| cachedClient := api.NewCachedHTTPClient(httpClient, time.Hour*24) | ||
| opts.Detector = fd.NewDetector(cachedClient, baseRepo.RepoHost()) | ||
| } | ||
| features, err := opts.Detector.IssueFeatures() | ||
| if err != nil { | ||
| return err | ||
| } | ||
| fields := defaultFields | ||
| // TODO stateReasonCleanup | ||
| if features.StateReason { | ||
| fields = append(defaultFields, "stateReason") | ||
| } | ||
| fields := append(defaultFields, "stateReason") | ||
|
|
There was a problem hiding this comment.
This change makes stateReason unconditional in the issue list GraphQL fragment. If GHES versions prior to when Issue.stateReason existed are still considered supported (the repo README currently claims GHES 2.20+), this will cause gh issue list to fail with a GraphQL schema error on those instances. Either update the documented minimum supported GHES version to a release where stateReason is guaranteed to exist, or keep a compatibility fallback (feature detection or version gating) before requesting this field.
Description
Remove
StateReasonandStateReasonDuplicatefromIssueFeaturesfeature detection. ThestateReasonfield was added in GHES ~3.4 and theDUPLICATEenum variant was added in GHES 3.16 — both available on all currently supported GHES versions, making the introspection queries and conditional logic unnecessary.Follows up on #12811 (comment).
Impact
IssueFeaturesstruct reduced to onlyActorIsAssignableIssueFeatures()removed entirely (was only checkingstateReason)stateReasonfield now always included in issue list queries--reasonflag ongh issue closeno longer conditionally stripped on GHES--duplicate-offlag ongh issue closeno longer conditionally erroring on GHES// TODO stateReasonCleanupmarkers across the codebaseNotes for reviewers
Two commits:
StateReasonDuplicate(the specific ask from the PR comment)StateReasonentirely (same rationale — available on all supported GHES)Manual tests
Tested on github.com and GHES 3.20.0:
gh issue close --reason completedgh issue close --reason "not planned"gh issue close --reason duplicategh issue close --duplicate-of <num>gh issue list --state closed --json stateReasongithub.com raw output
GHES 3.20.0 raw output