From 32ce39e1f46db792423340b5277e791f6a1eaee5 Mon Sep 17 00:00:00 2001 From: "Stephen Lewis (Burrows)" Date: Thu, 21 Dec 2023 10:41:04 -0800 Subject: [PATCH] Added service team review request support (#9681) * Initial work to support requesting service team reviews * Initial implementation of PR requests for service teams * Added test team * Added issue labeler dependency * Fixed build errors * Cleanup * Added request-service-reviewers to generate-diffs * Added unit tests * Removed test team * Tweaked variable name to be more explicit * Fixed ordering expectations in tests * Clarified which variables are sets --- .ci/gcb-generate-diffs-new.yml | 8 + .ci/magician/cmd/interfaces.go | 1 + .ci/magician/cmd/mock_github_test.go | 6 + .ci/magician/cmd/request_service_reviewers.go | 149 ++++++++++++++++++ .../cmd/request_service_reviewers_test.go | 147 +++++++++++++++++ .ci/magician/github/get.go | 11 ++ .ci/magician/go.mod | 11 +- .ci/magician/go.sum | 13 ++ tools/issue-labeler/labeler/labels.go | 4 +- 9 files changed, 347 insertions(+), 3 deletions(-) create mode 100644 .ci/magician/cmd/request_service_reviewers.go create mode 100644 .ci/magician/cmd/request_service_reviewers_test.go diff --git a/.ci/gcb-generate-diffs-new.yml b/.ci/gcb-generate-diffs-new.yml index 57aa9241c48a..24888c5c76c0 100644 --- a/.ci/gcb-generate-diffs-new.yml +++ b/.ci/gcb-generate-diffs-new.yml @@ -273,6 +273,14 @@ steps: - $PROJECT_ID - "22" # Build step + - name: 'gcr.io/graphite-docker-images/go-plus' + entrypoint: '/workspace/.ci/scripts/go-plus/magician/exec.sh' + secretEnv: ["GITHUB_TOKEN"] + waitFor: ["diff"] + args: + - 'request-service-reviewers' + - $_PR_NUMBER + # Long timeout to enable waiting on VCR test timeout: 20000s options: diff --git a/.ci/magician/cmd/interfaces.go b/.ci/magician/cmd/interfaces.go index 5c374972e4b3..b9b6c34ff1cb 100644 --- a/.ci/magician/cmd/interfaces.go +++ b/.ci/magician/cmd/interfaces.go @@ -24,6 +24,7 @@ type GithubClient interface { GetPullRequestRequestedReviewers(prNumber string) ([]github.User, error) GetPullRequestPreviousReviewers(prNumber string) ([]github.User, error) GetUserType(user string) github.UserType + GetTeamMembers(organization, team string) ([]github.User, error) PostBuildStatus(prNumber, title, state, targetURL, commitSha string) error PostComment(prNumber, comment string) error RequestPullRequestReviewer(prNumber, assignee string) error diff --git a/.ci/magician/cmd/mock_github_test.go b/.ci/magician/cmd/mock_github_test.go index aea11ff1a677..9b2e7e261a52 100644 --- a/.ci/magician/cmd/mock_github_test.go +++ b/.ci/magician/cmd/mock_github_test.go @@ -22,6 +22,7 @@ type mockGithub struct { userType github.UserType requestedReviewers []github.User previousReviewers []github.User + teamMembers map[string][]github.User calledMethods map[string][][]any } @@ -45,6 +46,11 @@ func (m *mockGithub) GetPullRequestPreviousReviewers(prNumber string) ([]github. return m.previousReviewers, nil } +func (m *mockGithub) GetTeamMembers(organization, team string) ([]github.User, error) { + m.calledMethods["GetTeamMembers"] = append(m.calledMethods["GetTeamMembers"], []any{organization, team}) + return m.teamMembers[team], nil +} + func (m *mockGithub) RequestPullRequestReviewer(prNumber string, reviewer string) error { m.calledMethods["RequestPullRequestReviewer"] = append(m.calledMethods["RequestPullRequestReviewer"], []any{prNumber, reviewer}) return nil diff --git a/.ci/magician/cmd/request_service_reviewers.go b/.ci/magician/cmd/request_service_reviewers.go new file mode 100644 index 000000000000..35e0abe549e7 --- /dev/null +++ b/.ci/magician/cmd/request_service_reviewers.go @@ -0,0 +1,149 @@ +/* +* Copyright 2023 Google LLC. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ +package cmd + +import ( + "fmt" + "magician/github" + "math/rand" + "os" + "strings" + + "github.com/GoogleCloudPlatform/magic-modules/tools/issue-labeler/labeler" + "github.com/spf13/cobra" + "gopkg.in/yaml.v2" +) + +// requestServiceReviewersCmd represents the requestServiceReviewers command +var requestServiceReviewersCmd = &cobra.Command{ + Use: "request-service-reviewers PR_NUMBER", + Short: "Assigns reviewers based on the PR's service labels.", + Long: `This command requests (or re-requests) review based on the PR's service labels. + + If a PR has more than 3 service labels, the command will not do anything. + `, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + prNumber := args[0] + fmt.Println("PR Number: ", prNumber) + + gh := github.NewClient() + execRequestServiceReviewers(prNumber, gh, labeler.EnrolledTeamsYaml) + }, +} + +func execRequestServiceReviewers(prNumber string, gh GithubClient, enrolledTeamsYaml []byte) { + pullRequest, err := gh.GetPullRequest(prNumber) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + enrolledTeams := make(map[string]labeler.LabelData) + if err := yaml.Unmarshal(enrolledTeamsYaml, &enrolledTeams); err != nil { + fmt.Printf("Error unmarshalling enrolled teams yaml: %s", err) + os.Exit(1) + } + + requestedReviewers, err := gh.GetPullRequestRequestedReviewers(prNumber) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + previousReviewers, err := gh.GetPullRequestPreviousReviewers(prNumber) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // If more than three service labels are impacted, don't request reviews. + // Only request reviews from unique service teams. + githubTeamsSet := make(map[string]struct{}) + teamCount := 0 + for _, label := range pullRequest.Labels { + if !strings.HasPrefix(label.Name, "service/") || label.Name == "service/terraform" { + continue + } + teamCount += 1 + if labelData, ok := enrolledTeams[label.Name]; ok { + githubTeamsSet[labelData.Team] = struct{}{} + } + } + + if teamCount > 3 { + fmt.Println("Provider-wide change (>3 services impacted); not requesting service team reviews") + return + } + + // For each service team, check if one of the team members is already a reviewer. Rerequest + // review if there is and choose a random reviewer from the list if there isn't. + reviewersToRequest := []string{} + requestedReviewersSet := make(map[string]struct{}) + for _, reviewer := range requestedReviewers { + requestedReviewersSet[reviewer.Login] = struct{}{} + } + + previousReviewersSet := make(map[string]struct{}) + for _, reviewer := range previousReviewers { + previousReviewersSet[reviewer.Login] = struct{}{} + } + + exitCode := 0 + for githubTeam, _ := range githubTeamsSet { + members, err := gh.GetTeamMembers("GoogleCloudPlatform", githubTeam) + if err != nil { + fmt.Printf("Error fetching members for GoogleCloudPlatform/%s: %s", githubTeam, err) + exitCode = 1 + continue + } + hasReviewer := false + reviewerPool := []string{} + for _, member := range members { + // Exclude PR author + if member.Login != pullRequest.User.Login { + reviewerPool = append(reviewerPool, member.Login) + } + // Don't re-request review if there's an active review request + if _, ok := requestedReviewersSet[member.Login]; ok { + hasReviewer = true + } + if _, ok := previousReviewersSet[member.Login]; ok { + hasReviewer = true + reviewersToRequest = append(reviewersToRequest, member.Login) + } + } + + if !hasReviewer && len(reviewerPool) > 0 { + reviewersToRequest = append(reviewersToRequest, reviewerPool[rand.Intn(len(reviewerPool))]) + } + } + + for _, reviewer := range reviewersToRequest { + err = gh.RequestPullRequestReviewer(prNumber, reviewer) + if err != nil { + fmt.Println(err) + exitCode = 1 + } + } + if exitCode != 0 { + os.Exit(1) + } +} + +func init() { + rootCmd.AddCommand(requestServiceReviewersCmd) +} diff --git a/.ci/magician/cmd/request_service_reviewers_test.go b/.ci/magician/cmd/request_service_reviewers_test.go new file mode 100644 index 000000000000..e32d2263728f --- /dev/null +++ b/.ci/magician/cmd/request_service_reviewers_test.go @@ -0,0 +1,147 @@ +package cmd + +import ( + "github.com/stretchr/testify/assert" + "magician/github" + "testing" +) + +var enrolledTeamsYaml = []byte(` +service/google-x: + team: google-x + resources: + - google_x_resource +service/google-y: + team: google-y + resources: + - google_y_resource +service/google-z: + resources: + - google_z_resource +`) + +func TestExecRequestServiceReviewersMembershipChecker(t *testing.T) { + cases := map[string]struct { + pullRequest github.PullRequest + requestedReviewers []string + previousReviewers []string + teamMembers map[string][]string + expectSpecificReviewers []string + }{ + "no service labels means no service team reviewers": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + }, + expectSpecificReviewers: []string{}, + }, + "unregistered service labels will not trigger review": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + Labels: []github.Label{{Name: "service/google-a"}}, + }, + expectSpecificReviewers: []string{}, + }, + "no configured team means no reviewers": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + Labels: []github.Label{{Name: "service/google-z"}}, + }, + expectSpecificReviewers: []string{}, + }, + "no previous reviewers means all reviews will be requested": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + Labels: []github.Label{{Name: "service/google-x"}}, + }, + teamMembers: map[string][]string{"google-x": []string{"googler_team_member"}}, + expectSpecificReviewers: []string{"googler_team_member"}, + }, + "previous reviewers will be re-requested": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + Labels: []github.Label{{Name: "service/google-x"}}, + }, + previousReviewers: []string{"googler_team_member"}, + teamMembers: map[string][]string{"google-x": []string{"googler_team_member", "googler_team_member_2", "googler_team_member_3", "googler_team_member_4", "googler_team_member_5"}}, + expectSpecificReviewers: []string{"googler_team_member"}, + }, + "active reviewers will not be re-requested": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + Labels: []github.Label{{Name: "service/google-x"}}, + }, + requestedReviewers: []string{"googler_team_member"}, + teamMembers: map[string][]string{"google-x": []string{"googler_team_member"}}, + expectSpecificReviewers: []string{}, + }, + "authors will not be requested on their own PRs": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_team_member"}, + Labels: []github.Label{{Name: "service/google-x"}}, + }, + teamMembers: map[string][]string{"google-x": []string{"googler_team_member"}}, + expectSpecificReviewers: []string{}, + }, + "other team members be requested even if the author is excluded": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_team_member"}, + Labels: []github.Label{{Name: "service/google-x"}}, + }, + teamMembers: map[string][]string{"google-x": []string{"googler_team_member", "googler_team_member_2"}}, + expectSpecificReviewers: []string{"googler_team_member_2"}, + }, + "multiple teams can be requested at once": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + Labels: []github.Label{{Name: "service/google-x"}, {Name: "service/google-y"}, {Name: "service/google-z"}}, + }, + teamMembers: map[string][]string{"google-x": []string{"googler_team_member"}, "google-y": []string{"googler_y_team_member"}}, + expectSpecificReviewers: []string{"googler_team_member", "googler_y_team_member"}, + }, + ">3 service teams will not be requested": { + pullRequest: github.PullRequest{ + User: github.User{Login: "googler_author"}, + Labels: []github.Label{{Name: "service/google-x"}, {Name: "service/google-y"}, {Name: "service/google-z"}, {Name: "service/google-a"}}, + }, + teamMembers: map[string][]string{"google-x": []string{"googler_team_member"}, "google-y": []string{"googler_y_team_member"}}, + expectSpecificReviewers: []string{}, + }, + } + for tn, tc := range cases { + t.Run(tn, func(t *testing.T) { + requestedReviewers := []github.User{} + for _, login := range tc.requestedReviewers { + requestedReviewers = append(requestedReviewers, github.User{Login: login}) + } + previousReviewers := []github.User{} + for _, login := range tc.previousReviewers { + previousReviewers = append(previousReviewers, github.User{Login: login}) + } + teamMembers := map[string][]github.User{} + for team, logins := range tc.teamMembers { + teamMembers[team] = []github.User{} + for _, login := range logins { + teamMembers[team] = append(teamMembers[team], github.User{Login: login}) + } + } + gh := &mockGithub{ + pullRequest: tc.pullRequest, + requestedReviewers: requestedReviewers, + previousReviewers: previousReviewers, + teamMembers: teamMembers, + calledMethods: make(map[string][][]any), + } + + execRequestServiceReviewers("1", gh, enrolledTeamsYaml) + + actualReviewers := []string{} + for _, args := range gh.calledMethods["RequestPullRequestReviewer"] { + actualReviewers = append(actualReviewers, args[1].(string)) + } + + if tc.expectSpecificReviewers != nil { + assert.ElementsMatch(t, tc.expectSpecificReviewers, actualReviewers) + } + }) + } +} diff --git a/.ci/magician/github/get.go b/.ci/magician/github/get.go index 14fe557b9749..65fb30f8a893 100644 --- a/.ci/magician/github/get.go +++ b/.ci/magician/github/get.go @@ -85,3 +85,14 @@ func (gh *Client) GetPullRequestPreviousReviewers(prNumber string) ([]User, erro return result, nil } + +func (gh *Client) GetTeamMembers(organization, team string) ([]User, error) { + url := fmt.Sprintf("https://api.github.com/orgs/%s/teams/%s/members", organization, team) + + var members []User + _, err := utils.RequestCall(url, "GET", gh.token, &members, nil) + if err != nil { + return nil, err + } + return members, nil +} diff --git a/.ci/magician/go.mod b/.ci/magician/go.mod index 7816d11ecd61..95f0b951ab1c 100644 --- a/.ci/magician/go.mod +++ b/.ci/magician/go.mod @@ -2,11 +2,14 @@ module magician go 1.20 +replace github.com/GoogleCloudPlatform/magic-modules/tools/issue-labeler => ../../tools/issue-labeler + require ( + github.com/GoogleCloudPlatform/magic-modules/tools/issue-labeler v0.0.0-00010101000000-000000000000 github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/exp v0.0.0-20230314191032-db074128a8ec + golang.org/x/exp v0.0.0-20230810033253-352e893a4cad google.golang.org/api v0.112.0 ) @@ -15,11 +18,15 @@ require github.com/otiai10/copy v1.12.0 require ( cloud.google.com/go/compute v1.18.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/glog v1.1.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/net v0.15.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect @@ -29,4 +36,6 @@ require ( google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488 // indirect google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/.ci/magician/go.sum b/.ci/magician/go.sum index a7ac8b6878b0..cc6550f565aa 100644 --- a/.ci/magician/go.sum +++ b/.ci/magician/go.sum @@ -6,17 +6,22 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/GoogleCloudPlatform/magic-modules/tools/issue-labeler v0.0.0-20231219215713-49252d7a95dc h1:EhpDpfqwRHmrIgDJQkdNOMhm374ylpVuR1sN7EdgVr4= +github.com/GoogleCloudPlatform/magic-modules/tools/issue-labeler v0.0.0-20231219215713-49252d7a95dc/go.mod h1:mqTMlyCznI9dA2Mf8oVdRuCArfCwfHE+5vpe3wEQ7qI= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= +github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -54,6 +59,7 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/otiai10/copy v1.12.0 h1:cLMgSQnXBs1eehF0Wy/FAGsgDTDmAqFR7rQylBb1nDY= github.com/otiai10/copy v1.12.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -67,6 +73,8 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -74,6 +82,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230314191032-db074128a8ec h1:pAv+d8BM2JNnNctsLJ6nnZ6NqXT8N4+eauvZSb3P0I0= golang.org/x/exp v0.0.0-20230314191032-db074128a8ec/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230810033253-352e893a4cad h1:g0bG7Z4uG+OgH2QDODnjp6ggkk1bJDsINcuWmJN1iJU= +golang.org/x/exp v0.0.0-20230810033253-352e893a4cad/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -141,7 +151,10 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tools/issue-labeler/labeler/labels.go b/tools/issue-labeler/labeler/labels.go index 697bdb6f132f..6fa5e10e1810 100644 --- a/tools/issue-labeler/labeler/labels.go +++ b/tools/issue-labeler/labeler/labels.go @@ -20,7 +20,7 @@ var ( EnrolledTeamsYaml []byte ) -type labelData struct { +type LabelData struct { Team string `yaml:"team,omitempty"` Resources []string `yaml:"resources"` } @@ -31,7 +31,7 @@ type RegexpLabel struct { } func BuildRegexLabels(teamsYaml []byte) ([]RegexpLabel, error) { - enrolledTeams := make(map[string]labelData) + enrolledTeams := make(map[string]LabelData) regexpLabels := []RegexpLabel{} if err := yaml.Unmarshal(teamsYaml, &enrolledTeams); err != nil { return regexpLabels, fmt.Errorf("Error unmarshalling enrolled teams yaml: %w", err)