X Tutup
Skip to content

Commit bb0ab3a

Browse files
committed
Ensure efficient resolving of issue/pr create metadata to GraphQL IDs
For metadata types chosen in interactive flow, we fetch all records from the API in order to be able to display a multi-select interface. For metadata defined via command-line flags, we resolve records that can be looked up directly, avoiding fetching the entirety of expensive datasets (e.g. all members of an organization) if we can. The new approach ensures efficient fetching when interactive flow is combined with values from flags.
1 parent 1b234d0 commit bb0ab3a

File tree

3 files changed

+86
-37
lines changed

3 files changed

+86
-37
lines changed

api/queries_repo.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,28 @@ func (m *RepoMetadataResult) MilestoneToID(title string) (string, error) {
464464
return "", errors.New("not found")
465465
}
466466

467+
func (m *RepoMetadataResult) Merge(m2 *RepoMetadataResult) {
468+
if len(m2.AssignableUsers) > 0 || len(m.AssignableUsers) == 0 {
469+
m.AssignableUsers = m2.AssignableUsers
470+
}
471+
472+
if len(m2.Teams) > 0 || len(m.Teams) == 0 {
473+
m.Teams = m2.Teams
474+
}
475+
476+
if len(m2.Labels) > 0 || len(m.Labels) == 0 {
477+
m.Labels = m2.Labels
478+
}
479+
480+
if len(m2.Projects) > 0 || len(m.Projects) == 0 {
481+
m.Projects = m2.Projects
482+
}
483+
484+
if len(m2.Milestones) > 0 || len(m.Milestones) == 0 {
485+
m.Milestones = m2.Milestones
486+
}
487+
}
488+
467489
type RepoMetadataInput struct {
468490
Assignees bool
469491
Reviewers bool

pkg/cmd/pr/shared/params.go

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,53 @@ func WithPrAndIssueQueryParams(baseURL string, state IssueMetadataState) (string
3737
return u.String(), nil
3838
}
3939

40+
// Ensure that tb.MetadataResult object exists and contains enough pre-fetched API data to be able
41+
// to resolve all object listed in tb to GraphQL IDs.
42+
func fillMetadata(client *api.Client, baseRepo ghrepo.Interface, tb *IssueMetadataState) error {
43+
resolveInput := api.RepoResolveInput{}
44+
45+
if len(tb.Assignees) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.AssignableUsers) == 0) {
46+
resolveInput.Assignees = tb.Assignees
47+
}
48+
49+
if len(tb.Reviewers) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.AssignableUsers) == 0) {
50+
resolveInput.Reviewers = tb.Reviewers
51+
}
52+
53+
if len(tb.Labels) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.Labels) == 0) {
54+
resolveInput.Labels = tb.Labels
55+
}
56+
57+
if len(tb.Projects) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.Projects) == 0) {
58+
resolveInput.Projects = tb.Projects
59+
}
60+
61+
if len(tb.Milestones) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.Milestones) == 0) {
62+
resolveInput.Milestones = tb.Milestones
63+
}
64+
65+
metadataResult, err := api.RepoResolveMetadataIDs(client, baseRepo, resolveInput)
66+
if err != nil {
67+
return err
68+
}
69+
70+
if tb.MetadataResult == nil {
71+
tb.MetadataResult = metadataResult
72+
} else {
73+
tb.MetadataResult.Merge(metadataResult)
74+
}
75+
76+
return nil
77+
}
78+
4079
func AddMetadataToIssueParams(client *api.Client, baseRepo ghrepo.Interface, params map[string]interface{}, tb *IssueMetadataState) error {
4180
if !tb.HasMetadata() {
4281
return nil
4382
}
4483

45-
if tb.MetadataResult == nil {
46-
resolveInput := api.RepoResolveInput{
47-
Reviewers: tb.Reviewers,
48-
Assignees: tb.Assignees,
49-
Labels: tb.Labels,
50-
Projects: tb.Projects,
51-
Milestones: tb.Milestones,
52-
}
53-
54-
var err error
55-
tb.MetadataResult, err = api.RepoResolveMetadataIDs(client, baseRepo, resolveInput)
56-
if err != nil {
57-
return err
58-
}
84+
err := fillMetadata(client, baseRepo, tb)
85+
if err != nil {
86+
return err
5987
}
6088

6189
assigneeIDs, err := tb.MetadataResult.MembersToIDs(tb.Assignees)

pkg/cmd/pr/shared/survey.go

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,6 @@ func MetadataSurvey(io *iostreams.IOStreams, client *api.Client, baseRepo ghrepo
263263
milestones = append(milestones, m.Title)
264264
}
265265

266-
type metadataValues struct {
267-
Reviewers []string
268-
Assignees []string
269-
Labels []string
270-
Projects []string
271-
Milestone string
272-
}
273266
var mqs []*survey.Question
274267
if isChosen("Reviewers") {
275268
if len(users) > 0 || len(teams) > 0 {
@@ -346,33 +339,39 @@ func MetadataSurvey(io *iostreams.IOStreams, client *api.Client, baseRepo ghrepo
346339
}
347340
}
348341

349-
if len(mqs) > 0 {
350-
values := metadataValues{
351-
Reviewers: state.Reviewers,
352-
Assignees: state.Assignees,
353-
Labels: state.Labels,
354-
Projects: state.Projects,
355-
}
356-
if len(state.Milestones) > 0 {
357-
values.Milestone = state.Milestones[0]
358-
}
342+
values := struct {
343+
Reviewers []string
344+
Assignees []string
345+
Labels []string
346+
Projects []string
347+
Milestone string
348+
}{}
359349

360-
err = prompt.SurveyAsk(mqs, &values, survey.WithKeepFilter(true))
361-
if err != nil {
362-
return fmt.Errorf("could not prompt: %w", err)
363-
}
350+
err = prompt.SurveyAsk(mqs, &values, survey.WithKeepFilter(true))
351+
if err != nil {
352+
return fmt.Errorf("could not prompt: %w", err)
353+
}
364354

355+
if isChosen("Reviewers") {
365356
state.Reviewers = values.Reviewers
357+
}
358+
if isChosen("Assignees") {
366359
state.Assignees = values.Assignees
360+
}
361+
if isChosen("Labels") {
367362
state.Labels = values.Labels
363+
}
364+
if isChosen("Projects") {
368365
state.Projects = values.Projects
366+
}
367+
if isChosen("Milestone") {
369368
if values.Milestone != "" && values.Milestone != noMilestone {
370369
state.Milestones = []string{values.Milestone}
370+
} else {
371+
state.Milestones = []string{}
371372
}
372373
}
373374

374-
state.MetadataResult = nil
375-
376375
return nil
377376
}
378377

0 commit comments

Comments
 (0)
X Tutup