fix(pr create): use login-based assignee mutation on github.com
When ActorAssignees is true (github.com), pass assignee logins directly to the ReplaceActorsForAssignable mutation instead of resolving logins to node IDs. This eliminates the need to bulk fetch all assignable users/actors and fixes a bug where providing assignees via CLI flag and then interactively adding metadata would fail with 'not found' because the cached MetadataResult had no assignee data. Changes: - Set state.ActorAssignees = true in pr create (was missing) - AddMetadataToIssueParams: pass assigneeLogins when ActorAssignees is true, skip fetch and ID resolution entirely - CreatePullRequest/IssueCreate: call ReplaceActorsForAssignableByLogin after creation to assign via logins - Consolidate replaceActorsForAssignable mutation into api/ package (ReplaceActorsForAssignableByLogin + ReplaceActorsForAssignableByID) - Remove duplicate replaceActorAssigneesForEditable from editable_http.go - Add TODO replaceActorsByLoginCleanup markers on edit paths Fixes cli/cli#13000 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
8723e3bb52
commit
e6d9019bc9
8 changed files with 165 additions and 87 deletions
|
|
@ -289,7 +289,8 @@ func IssueCreate(client *Client, repo *Repository, params map[string]interface{}
|
|||
switch key {
|
||||
case "assigneeIds", "body", "issueTemplate", "labelIds", "milestoneId", "projectIds", "repositoryId", "title":
|
||||
inputParams[key] = val
|
||||
case "projectV2Ids":
|
||||
case "projectV2Ids", "assigneeLogins":
|
||||
// handled after issue creation
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid IssueCreate mutation parameter %s", key)
|
||||
}
|
||||
|
|
@ -310,6 +311,14 @@ func IssueCreate(client *Client, repo *Repository, params map[string]interface{}
|
|||
}
|
||||
issue := &result.CreateIssue.Issue
|
||||
|
||||
// Assign users using login-based mutation when ActorAssignees is true (github.com).
|
||||
if assigneeLogins, ok := params["assigneeLogins"].([]string); ok && len(assigneeLogins) > 0 {
|
||||
err := ReplaceActorsForAssignableByLogin(client, repo, issue.ID, assigneeLogins)
|
||||
if err != nil {
|
||||
return issue, err
|
||||
}
|
||||
}
|
||||
|
||||
// projectV2 parameters aren't supported in the `createIssue` mutation,
|
||||
// so add them after the issue has been created.
|
||||
projectV2Ids, ok := params["projectV2Ids"].([]string)
|
||||
|
|
|
|||
|
|
@ -524,6 +524,14 @@ func CreatePullRequest(client *Client, repo *Repository, params map[string]inter
|
|||
}
|
||||
}
|
||||
|
||||
// Assign users using login-based mutation when ActorAssignees is true (github.com).
|
||||
if assigneeLogins, ok := params["assigneeLogins"].([]string); ok && len(assigneeLogins) > 0 {
|
||||
err := ReplaceActorsForAssignableByLogin(client, repo, pr.ID, assigneeLogins)
|
||||
if err != nil {
|
||||
return pr, err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO requestReviewsByLoginCleanup
|
||||
// Request reviewers using either login-based (github.com) or ID-based (GHES) mutation.
|
||||
// The ID-based path can be removed once GHES supports requestReviewsByLogin.
|
||||
|
|
@ -581,6 +589,62 @@ func CreatePullRequest(client *Client, repo *Repository, params map[string]inter
|
|||
return pr, nil
|
||||
}
|
||||
|
||||
// ReplaceActorsForAssignableByLogin calls the replaceActorsForAssignable mutation
|
||||
// using actor logins. This avoids the need to resolve logins to node IDs.
|
||||
func ReplaceActorsForAssignableByLogin(client *Client, repo ghrepo.Interface, assignableID string, logins []string) error {
|
||||
type ReplaceActorsForAssignableInput struct {
|
||||
AssignableID githubv4.ID `json:"assignableId"`
|
||||
ActorLogins []githubv4.String `json:"actorLogins"`
|
||||
}
|
||||
|
||||
actorLogins := make([]githubv4.String, len(logins))
|
||||
for i, l := range logins {
|
||||
actorLogins[i] = githubv4.String(l)
|
||||
}
|
||||
|
||||
variables := map[string]interface{}{
|
||||
"input": ReplaceActorsForAssignableInput{
|
||||
AssignableID: githubv4.ID(assignableID),
|
||||
ActorLogins: actorLogins,
|
||||
},
|
||||
}
|
||||
|
||||
return replaceActorsForAssignable(client, repo, variables)
|
||||
}
|
||||
|
||||
// ReplaceActorsForAssignableByID calls the replaceActorsForAssignable mutation
|
||||
// using actor node IDs. Used for GHES and edit flows that resolve IDs from search results.
|
||||
func ReplaceActorsForAssignableByID(client *Client, repo ghrepo.Interface, assignableID string, actorIDs []string) error {
|
||||
type ReplaceActorsForAssignableInput struct {
|
||||
AssignableID githubv4.ID `json:"assignableId"`
|
||||
ActorIDs []githubv4.ID `json:"actorIds"`
|
||||
}
|
||||
|
||||
ids := make([]githubv4.ID, len(actorIDs))
|
||||
for i, id := range actorIDs {
|
||||
ids[i] = githubv4.ID(id)
|
||||
}
|
||||
|
||||
variables := map[string]interface{}{
|
||||
"input": ReplaceActorsForAssignableInput{
|
||||
AssignableID: githubv4.ID(assignableID),
|
||||
ActorIDs: ids,
|
||||
},
|
||||
}
|
||||
|
||||
return replaceActorsForAssignable(client, repo, variables)
|
||||
}
|
||||
|
||||
func replaceActorsForAssignable(client *Client, repo ghrepo.Interface, variables map[string]interface{}) error {
|
||||
var mutation struct {
|
||||
ReplaceActorsForAssignable struct {
|
||||
TypeName string `graphql:"__typename"`
|
||||
} `graphql:"replaceActorsForAssignable(input: $input)"`
|
||||
}
|
||||
|
||||
return client.Mutate(repo.RepoHost(), "ReplaceActorsForAssignable", &mutation, variables)
|
||||
}
|
||||
|
||||
// SuggestedAssignableActors fetches up to 10 suggested actors for a specific assignable
|
||||
// (Issue or PullRequest) node ID. `assignableID` is the GraphQL node ID for the Issue/PR.
|
||||
// Returns the actors, the total count of available assignees in the repo, and an error.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue