refactor(featuredetection): rename ActorIsAssignable to ApiActorsSupported

Aligns the feature detector field name with the downstream
ApiActorsSupported flag introduced in the previous commit, so the
signal has one consistent name from detection through to consumption.

Also consolidates leftover TODO tags (actorIsAssignableCleanup,
requestReviewsByLoginCleanup) under the single // TODO ApiActorsSupported
tag so there's exactly one thing to grep for.

Pure rename with no logic changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Kynan Ware 2026-03-24 21:09:04 -06:00
parent 3c00ffdade
commit ae5e857c2e
9 changed files with 29 additions and 23 deletions

View file

@ -532,7 +532,7 @@ func CreatePullRequest(client *Client, repo *Repository, params map[string]inter
}
}
// TODO requestReviewsByLoginCleanup
// TODO ApiActorsSupported
// Request reviewers using either login-based (github.com) or ID-based (GHES) mutation.
// The ID-based path can be removed once GHES supports requestReviewsByLogin.
userLogins, hasUserLogins := params["userReviewerLogins"].([]string)

View file

@ -23,11 +23,17 @@ type Detector interface {
}
type IssueFeatures struct {
ActorIsAssignable bool
// TODO ApiActorsSupported
// ApiActorsSupported indicates the host supports actor-based APIs
// (replaceActorsForAssignable, requestReviewsByLogin, suggestedAssignableActors, etc.).
// True for github.com and ghe.com. False for GHES.
// Remove this flag once GHES supports these mutations, then collapse all
// // TODO ApiActorsSupported sites to the actor-only path.
ApiActorsSupported bool
}
var allIssueFeatures = IssueFeatures{
ActorIsAssignable: true,
ApiActorsSupported: true,
}
type PullRequestFeatures struct {
@ -136,7 +142,7 @@ func (d *detector) IssueFeatures() (IssueFeatures, error) {
}
return IssueFeatures{
ActorIsAssignable: false, // replaceActorsForAssignable GraphQL mutation unavailable on GHES
ApiActorsSupported: false, // TODO ApiActorsSupported — actor-based mutations unavailable on GHES
}, nil
}

View file

@ -23,7 +23,7 @@ func TestIssueFeatures(t *testing.T) {
name: "github.com",
hostname: "github.com",
wantFeatures: IssueFeatures{
ActorIsAssignable: true,
ApiActorsSupported: true,
},
wantErr: false,
},
@ -31,7 +31,7 @@ func TestIssueFeatures(t *testing.T) {
name: "ghec data residency (ghe.com)",
hostname: "stampname.ghe.com",
wantFeatures: IssueFeatures{
ActorIsAssignable: true,
ApiActorsSupported: true,
},
wantErr: false,
},
@ -39,7 +39,7 @@ func TestIssueFeatures(t *testing.T) {
name: "GHE",
hostname: "git.my.org",
wantFeatures: IssueFeatures{
ActorIsAssignable: false,
ApiActorsSupported: false,
},
wantErr: false,
},

View file

@ -179,7 +179,7 @@ func createRun(opts *CreateOptions) (err error) {
// Replace special values in assignees
// For web mode, @copilot should be replaced by name; otherwise, login.
assigneeReplacer := prShared.NewSpecialAssigneeReplacer(apiClient, baseRepo.RepoHost(), issueFeatures.ActorIsAssignable, !opts.WebMode)
assigneeReplacer := prShared.NewSpecialAssigneeReplacer(apiClient, baseRepo.RepoHost(), issueFeatures.ApiActorsSupported, !opts.WebMode)
assignees, err := assigneeReplacer.ReplaceSlice(opts.Assignees)
if err != nil {
return err
@ -189,7 +189,7 @@ func createRun(opts *CreateOptions) (err error) {
tb := prShared.IssueMetadataState{
Type: prShared.IssueMetadata,
ApiActorsSupported: issueFeatures.ActorIsAssignable, // TODO ApiActorsSupported
ApiActorsSupported: issueFeatures.ApiActorsSupported, // TODO ApiActorsSupported
Assignees: assigneeSet.ToSlice(),
Labels: opts.Labels,
ProjectTitles: opts.Projects,
@ -309,7 +309,7 @@ func createRun(opts *CreateOptions) (err error) {
State: &tb,
}
var assigneeSearchFunc func(string) prompter.MultiSelectSearchResult
if issueFeatures.ActorIsAssignable {
if issueFeatures.ApiActorsSupported {
assigneeSearchFunc = prShared.RepoAssigneeSearchFunc(apiClient, baseRepo)
}
err = prShared.MetadataSurvey(opts.Prompter, opts.IO, baseRepo, fetcher, &tb, projectsV1Support, nil, assigneeSearchFunc)

View file

@ -216,7 +216,7 @@ func editRun(opts *EditOptions) error {
lookupFields := []string{"id", "number", "title", "body", "url"}
if editable.Assignees.Edited {
// TODO ApiActorsSupported
if issueFeatures.ActorIsAssignable {
if issueFeatures.ApiActorsSupported {
editable.ApiActorsSupported = true
lookupFields = append(lookupFields, "assignedActors")
} else {
@ -249,9 +249,9 @@ func editRun(opts *EditOptions) error {
// Fetch editable shared fields once for all issues.
apiClient := api.NewClientFromHTTP(httpClient)
// Wire up search function for assignees when ActorIsAssignable is available.
// Wire up search function for assignees when ApiActorsSupported is available.
// Interactive mode only supports a single issue, so we use its ID for the search query.
if issueFeatures.ActorIsAssignable && opts.Interactive && len(issues) == 1 {
if issueFeatures.ApiActorsSupported && opts.Interactive && len(issues) == 1 {
editable.AssigneeSearchFunc = prShared.AssigneeSearchFunc(apiClient, baseRepo, issues[0].ID)
}

View file

@ -935,7 +935,7 @@ func mockProjectV2ItemUpdate(t *testing.T, reg *httpmock.Registry) {
)
}
func TestActorIsAssignable(t *testing.T) {
func TestApiActorsSupported(t *testing.T) {
t.Run("when actors are assignable, query includes assignedActors", func(t *testing.T) {
ios, _, _, _ := iostreams.Test()

View file

@ -399,7 +399,7 @@ func createRun(opts *CreateOptions) error {
client := ctx.Client
// Detect ActorIsAssignable feature to determine if we can use search-based
// Detect ApiActorsSupported feature to determine if we can use search-based
// reviewer selection (github.com) or need to use legacy ID-based selection (GHES)
issueFeatures, err := opts.Detector.IssueFeatures()
if err != nil {
@ -407,7 +407,7 @@ func createRun(opts *CreateOptions) error {
}
var reviewerSearchFunc func(string) prompter.MultiSelectSearchResult
var assigneeSearchFunc func(string) prompter.MultiSelectSearchResult
if issueFeatures.ActorIsAssignable {
if issueFeatures.ApiActorsSupported {
reviewerSearchFunc = func(query string) prompter.MultiSelectSearchResult {
candidates, moreResults, err := api.SuggestedReviewerActorsForRepo(client, ctx.PRRefs.BaseRepo(), query)
if err != nil {
@ -430,7 +430,7 @@ func createRun(opts *CreateOptions) error {
}
// TODO ApiActorsSupported
if issueFeatures.ActorIsAssignable {
if issueFeatures.ApiActorsSupported {
state.ApiActorsSupported = true
}

View file

@ -270,8 +270,8 @@ func editRun(opts *EditOptions) error {
return err
}
// TODO actorIsAssignableCleanup
if issueFeatures.ActorIsAssignable {
// TODO ApiActorsSupported
if issueFeatures.ApiActorsSupported {
findOptions.Fields = append(findOptions.Fields, "assignedActors")
} else {
findOptions.Fields = append(findOptions.Fields, "assignees")
@ -290,7 +290,7 @@ func editRun(opts *EditOptions) error {
editable.Reviewers.Default = pr.ReviewRequests.DisplayNames()
editable.Reviewers.DefaultLogins = pr.ReviewRequests.Logins()
// TODO ApiActorsSupported
if issueFeatures.ActorIsAssignable {
if issueFeatures.ApiActorsSupported {
editable.ApiActorsSupported = true
editable.Assignees.Default = pr.AssignedActors.DisplayNames()
editable.Assignees.DefaultLogins = pr.AssignedActors.Logins()
@ -320,8 +320,8 @@ func editRun(opts *EditOptions) error {
// Wire up search functions for assignees and reviewers.
// When these aren't wired up, it triggers a downstream fallback
// to legacy reviewer/assignee fetching.
// TODO actorIsAssignableCleanup
if issueFeatures.ActorIsAssignable {
// TODO ApiActorsSupported
if issueFeatures.ApiActorsSupported {
editable.AssigneeSearchFunc = shared.AssigneeSearchFunc(apiClient, repo, pr.ID)
editable.ReviewerSearchFunc = reviewerSearchFunc(apiClient, repo, &editable, pr.ID)
}

View file

@ -275,7 +275,7 @@ func MetadataSurvey(p Prompt, io *iostreams.IOStreams, baseRepo ghrepo.Interface
}
values.Reviewers = selectedReviewers
} else if len(reviewers) > 0 {
// TODO requestReviewsByLoginCleanup
// TODO ApiActorsSupported
// The static MultiSelect path can be removed once GHES supports
// requestReviewsByLogin and search-based selection is always used.
selected, err := p.MultiSelect("Reviewers", state.Reviewers, reviewers)