From d19b8e1a09858c0580f6b7a8939c5c59114ff7a0 Mon Sep 17 00:00:00 2001 From: Amine Hilaly Date: Mon, 5 Aug 2019 23:27:08 +0200 Subject: [PATCH 1/2] bridge/github: fix name case sensitivity in retrieving and creating labels using github graphql api --- bridge/github/export.go | 58 ++++++++++++++++++++++++++--------- bridge/github/import_query.go | 14 +++++++++ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/bridge/github/export.go b/bridge/github/export.go index 976c5a05aecf8fd058bef545d1481dcce5945f4a..b239eff9093dad08327e8f7e5ca8060b507dca71 100644 --- a/bridge/github/export.go +++ b/bridge/github/export.go @@ -7,6 +7,7 @@ import ( "fmt" "io/ioutil" "net/http" + "strings" "time" "github.com/pkg/errors" @@ -100,6 +101,17 @@ func (ge *githubExporter) ExportAll(ctx context.Context, repo *cache.RepoCache, return nil, err } + client, err := ge.getIdentityClient(user.Id()) + if err != nil { + return nil, err + } + + // query all labels + err = ge.cacheGithubLabels(ctx, client) + if err != nil { + return nil, err + } + go func() { defer close(out) @@ -433,28 +445,46 @@ func markOperationAsExported(b *cache.BugCache, target entity.Id, githubID, gith return err } -// get label from github -func (ge *githubExporter) getGithubLabelID(ctx context.Context, gc *githubv4.Client, label string) (string, error) { - q := &labelQuery{} +func (ge *githubExporter) cacheGithubLabels(ctx context.Context, gc *githubv4.Client) error { variables := map[string]interface{}{ - "label": githubv4.String(label), "owner": githubv4.String(ge.conf[keyOwner]), "name": githubv4.String(ge.conf[keyProject]), + "first": githubv4.Int(10), + "after": (*githubv4.String)(nil), } - ctx, cancel := context.WithTimeout(ctx, defaultTimeout) - defer cancel() + q := labelsQuery{} - if err := gc.Query(ctx, q, variables); err != nil { - return "", err + hasNextPage := true + for hasNextPage { + // create a new timeout context at each iteration + ctx, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + if err := gc.Query(ctx, &q, variables); err != nil { + return err + } + + for _, label := range q.Repository.Labels.Nodes { + ge.cachedLabels[label.Name] = label.ID + } + + hasNextPage = q.Repository.Labels.PageInfo.HasNextPage + variables["after"] = q.Repository.Labels.PageInfo.EndCursor } - // if label id is empty, it means there is no such label in this Github repository - if q.Repository.Label.ID == "" { - return "", fmt.Errorf("label not found") + return nil +} + +func (ge *githubExporter) getLabelID(gc *githubv4.Client, label string) (string, error) { + label = strings.ToLower(label) + for cachedLabel, ID := range ge.cachedLabels { + if label == strings.ToLower(cachedLabel) { + return ID, nil + } } - return q.Repository.Label.ID, nil + return "", fmt.Errorf("didn't find label id in cache") } // create a new label and return it github id @@ -539,8 +569,8 @@ func (ge *githubExporter) createGithubLabelV4(gc *githubv4.Client, label, labelC */ func (ge *githubExporter) getOrCreateGithubLabelID(ctx context.Context, gc *githubv4.Client, repositoryID string, label bug.Label) (string, error) { - // try to get label id - labelID, err := ge.getGithubLabelID(ctx, gc, string(label)) + // try to get label id from cache + labelID, err := ge.getLabelID(gc, string(label)) if err == nil { return labelID, nil } diff --git a/bridge/github/import_query.go b/bridge/github/import_query.go index 89d7859d0c460669de5495cc75fedd14b917f7a1..62d3227bdfdb036b87d9dcb997aa23a51ebe0d41 100644 --- a/bridge/github/import_query.go +++ b/bridge/github/import_query.go @@ -175,3 +175,17 @@ type labelQuery struct { } `graphql:"label(name: $label)"` } `graphql:"repository(owner: $owner, name: $name)"` } + +type labelsQuery struct { + Repository struct { + Labels struct { + Nodes []struct { + ID string `graphql:"id"` + Name string `graphql:"name"` + Color string `graphql:"color"` + Description string `graphql:"description"` + } + PageInfo pageInfo + } `graphql:"labels(first: $first, after: $after)"` + } `graphql:"repository(owner: $owner, name: $name)"` +} From 4a4e238d1f01eefb527bf2c3f4685863477d9eaa Mon Sep 17 00:00:00 2001 From: Amine Hilaly Date: Mon, 5 Aug 2019 23:27:32 +0200 Subject: [PATCH 2/2] bridge/github: add exporter test cases for label change bug --- bridge/github/export_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bridge/github/export_test.go b/bridge/github/export_test.go index a0be7cff75612abe89e54d12e8601e4536e5a78a..e39ace013813054c1d0a81070a8c1063d52f0b57 100644 --- a/bridge/github/export_test.go +++ b/bridge/github/export_test.go @@ -55,6 +55,12 @@ func testCases(t *testing.T, repo *cache.RepoCache, identity *cache.IdentityCach _, _, err = bugLabelChange.ChangeLabels(nil, []string{"bug"}) require.NoError(t, err) + _, _, err = bugLabelChange.ChangeLabels([]string{"InVaLiD"}, nil) + require.NoError(t, err) + + _, _, err = bugLabelChange.ChangeLabels([]string{"bUG"}, nil) + require.NoError(t, err) + // bug with comments editions bugWithCommentEditions, createOp, err := repo.NewBug("bug with comments editions", "new bug") require.NoError(t, err) @@ -99,7 +105,7 @@ func testCases(t *testing.T, repo *cache.RepoCache, identity *cache.IdentityCach &testCase{ name: "bug label change", bug: bugLabelChange, - numOrOp: 4, + numOrOp: 6, }, &testCase{ name: "bug with comment editions",