Merge pull request #13009 from cli/fix/pr-create-assignee-metadata-13000
Use login-based assignee mutation on github.com
This commit is contained in:
commit
1df6f84d70
16 changed files with 390 additions and 271 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,35 @@ 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)
|
||||
}
|
||||
|
||||
var mutation struct {
|
||||
ReplaceActorsForAssignable struct {
|
||||
TypeName string `graphql:"__typename"`
|
||||
} `graphql:"replaceActorsForAssignable(input: $input)"`
|
||||
}
|
||||
|
||||
variables := map[string]interface{}{
|
||||
"input": ReplaceActorsForAssignableInput{
|
||||
AssignableID: githubv4.ID(assignableID),
|
||||
ActorLogins: actorLogins,
|
||||
},
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -1298,6 +1298,69 @@ func RepoAssignableActors(client *Client, repo ghrepo.Interface) ([]AssignableAc
|
|||
return actors, nil
|
||||
}
|
||||
|
||||
// SearchRepoAssignableActors searches assignable actors for a repository with an optional
|
||||
// query string. Unlike RepoAssignableActors which fetches all actors with pagination, this
|
||||
// returns up to 10 results matching the query, suitable for search-based selection.
|
||||
func SearchRepoAssignableActors(client *Client, repo ghrepo.Interface, query string) ([]AssignableActor, int, error) {
|
||||
type responseData struct {
|
||||
Repository struct {
|
||||
AssignableUsers struct {
|
||||
TotalCount int
|
||||
}
|
||||
SuggestedActors struct {
|
||||
Nodes []struct {
|
||||
User struct {
|
||||
ID string
|
||||
Login string
|
||||
Name string
|
||||
TypeName string `graphql:"__typename"`
|
||||
} `graphql:"... on User"`
|
||||
Bot struct {
|
||||
ID string
|
||||
Login string
|
||||
TypeName string `graphql:"__typename"`
|
||||
} `graphql:"... on Bot"`
|
||||
}
|
||||
} `graphql:"suggestedActors(first: 10, query: $query, capabilities: CAN_BE_ASSIGNED)"`
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
}
|
||||
|
||||
var q *githubv4.String
|
||||
if query != "" {
|
||||
v := githubv4.String(query)
|
||||
q = &v
|
||||
}
|
||||
|
||||
variables := map[string]interface{}{
|
||||
"owner": githubv4.String(repo.RepoOwner()),
|
||||
"name": githubv4.String(repo.RepoName()),
|
||||
"query": q,
|
||||
}
|
||||
|
||||
var result responseData
|
||||
if err := client.Query(repo.RepoHost(), "SearchRepoAssignableActors", &result, variables); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var actors []AssignableActor
|
||||
for _, node := range result.Repository.SuggestedActors.Nodes {
|
||||
if node.User.TypeName == "User" {
|
||||
actors = append(actors, AssignableUser{
|
||||
id: node.User.ID,
|
||||
login: node.User.Login,
|
||||
name: node.User.Name,
|
||||
})
|
||||
} else if node.Bot.TypeName == "Bot" {
|
||||
actors = append(actors, AssignableBot{
|
||||
id: node.Bot.ID,
|
||||
login: node.Bot.Login,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return actors, result.Repository.AssignableUsers.TotalCount, nil
|
||||
}
|
||||
|
||||
type RepoLabel struct {
|
||||
ID string
|
||||
Name string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue