Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add certificate manager trust config resource #8623

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
70f3b35
feat: added resource and example file
DanielRieske Aug 11, 2023
344b793
feat: added labels field to tests
DanielRieske Aug 11, 2023
8fae111
chore: removed trailing whitespaces
DanielRieske Aug 14, 2023
14f538d
feat: marked certificates as sensitive
DanielRieske Aug 14, 2023
0d407aa
chore: removed trailing space
DanielRieske Aug 14, 2023
27f999b
Adds field bitbucket_server_config to Trigger.git_file_source and Tri…
mariomachado94 Aug 11, 2023
4fff75b
add scaling_config to google_dataproc_metastore_service resource in g…
vicenteg Aug 11, 2023
c85f04c
Switch rake test to be run in our build-environment (#8554)
ScottSuarez Aug 11, 2023
46c907d
Adding backupdr product with managementServer resource (#8612)
niharika-98 Aug 11, 2023
952522c
Move acc tests to service package (mmv1 + related handwritten) (#8378)
zli82016 Aug 11, 2023
2df59f8
Made reviewer assignment comment include detected reviewer type (#8585)
melinath Aug 11, 2023
21bc991
Don't run VCR tests if there is a build failure (#8508)
trodge Aug 11, 2023
47daeac
Update subnetwork descriptions and tests to use REGIONAL_MANAGED_PROX…
jlporter Aug 11, 2023
febf15c
Generate DCL tests to service packages (#8574)
zli82016 Aug 11, 2023
a2ba339
Added support for versionAliases field in google_secret_manager_secre…
abheda-crest Aug 11, 2023
b420463
Add case sensitivity diff suppression for enums. (#8626)
hankfreund Aug 14, 2023
f48c836
TeamCity : control branch under test via a configuration parameter (#…
SarahFrench Aug 14, 2023
eea3085
Made issue labeler support nested resources list (#8627)
melinath Aug 14, 2023
84f3001
Certificate manager update description for scope property certificate…
Hamzawy63 Aug 14, 2023
46a9782
Look for test files in service packages (#8643)
trodge Aug 14, 2023
780fedc
Add migration guide for google_firebaserules_release breaking changes…
rainshen49 Aug 14, 2023
b0000e6
Move gcp_sweeper_test.go to the sweeper package (#8217)
zli82016 Aug 14, 2023
d778b0c
Update .copywrite.hcl to ignore all test-fixtures regardless of packa…
SarahFrench Aug 15, 2023
6b66ae4
Updated 5.0.0 release guide about the change in enableEndpointIndepen…
shijeesh-ns Aug 15, 2023
1275321
feat: changed path of test-fixture
DanielRieske Aug 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Hello! I am a robot. It looks like you are a community contributor. @{{reviewer}}, a repository maintainer, has been assigned to review your changes. If you have not received review feedback within 2 business days, please leave a comment on this PR asking them to take a look.
Hello! I am a robot. It looks like you are a: {{if eq .authorUserType "Community Contributor"}}Community Contributor{{else}}~Community Contributor~{{end}} {{if eq .authorUserType "Googler"}}Googler{{else}}~Googler~{{end}} {{if eq .authorUserType "Core Contributor"}}Core Contributor{{else}}~Core Contributor~{{end}}. {{if .trusted}}Tests will run automatically.{{else}}Tests will require approval to run.{{end}}

@{{.reviewer}}, a repository maintainer, has been assigned to review your changes. If you have not received review feedback within 2 business days, please leave a comment on this PR asking them to take a look.

You can help make sure that review is quick by [doing a self-review](https://googlecloudplatform.github.io/magic-modules/contribute/review-pr/) and by [running impacted tests locally](https://googlecloudplatform.github.io/magic-modules/get-started/run-provider-tests/).
36 changes: 32 additions & 4 deletions .ci/containers/membership-checker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,43 @@ func main() {
os.Exit(1)
}

if target == "auto_run" {
err = requestReviewer(author, prNumber, GITHUB_TOKEN)
authorUserType := getUserType(author, GITHUB_TOKEN)
trusted := authorUserType == coreContributorUserType || authorUserType == googlerUserType

if target == "auto_run" && authorUserType != coreContributorUserType {
fmt.Println("Not core contributor - assigning reviewer")

firstRequestedReviewer, err := getPullRequestRequestedReviewer(prNumber, GITHUB_TOKEN)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}

trusted := isTrustedUser(author, GITHUB_TOKEN)
previouslyInvolvedReviewers, err := getPullRequestPreviousAssignedReviewers(prNumber, GITHUB_TOKEN)
if err != nil {
fmt.Println(err)
os.Exit(1)
}

reviewersToRequest, newPrimaryReviewer := chooseReviewers(firstRequestedReviewer, previouslyInvolvedReviewers)

for _, reviewer := range reviewersToRequest {
err = requestPullRequestReviewer(prNumber, reviewer, GITHUB_TOKEN)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}

if newPrimaryReviewer != "" {
comment := formatReviewerComment(newPrimaryReviewer, authorUserType, trusted)
err = postComment(prNumber, comment, GITHUB_TOKEN, authorUserType)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
}

// auto_run(contributor-membership-checker) will be run on every commit or /gcbrun:
// only triggers builds for trusted users
Expand Down
36 changes: 27 additions & 9 deletions .ci/containers/membership-checker/membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ var (
}
)

type userType int64

const (
communityUserType userType = iota
googlerUserType
coreContributorUserType
)

func (ut userType) String() string {
switch ut {
case googlerUserType:
return "Googler"
case coreContributorUserType:
return "Core Contributor"
default:
return "Community Contributor"
}
}

// Check if a user is team member to not request a random reviewer
func isTeamMember(author string) bool {
return slices.Contains(reviewerRotation, author) || slices.Contains(trustedContributors, author)
Expand All @@ -46,24 +65,23 @@ func isTeamReviewer(reviewer string) bool {
return slices.Contains(reviewerRotation, reviewer)
}

// Check if a user is safe to run tests automatically
func isTrustedUser(author, GITHUB_TOKEN string) bool {
if isTeamMember(author) {
func getUserType(user, GITHUB_TOKEN string) userType {
if isTeamMember(user) {
fmt.Println("User is a team member")
return true
return coreContributorUserType
}

if isOrgMember(author, "GoogleCloudPlatform", GITHUB_TOKEN) {
if isOrgMember(user, "GoogleCloudPlatform", GITHUB_TOKEN) {
fmt.Println("User is a GCP org member")
return true
return googlerUserType
}

if isOrgMember(author, "googlers", GITHUB_TOKEN) {
if isOrgMember(user, "googlers", GITHUB_TOKEN) {
fmt.Println("User is a googlers org member")
return true
return googlerUserType
}

return false
return communityUserType
}

func isOrgMember(author, org, GITHUB_TOKEN string) bool {
Expand Down
71 changes: 26 additions & 45 deletions .ci/containers/membership-checker/reviewer_assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
"strings"
"text/template"

_ "embed"
)
Expand All @@ -13,48 +14,30 @@ var (
reviewerAssignmentComment string
)

func requestReviewer(author, prNumber, GITHUB_TOKEN string) error {
if isTeamMember(author) {
fmt.Println("author is a team member, not assigning")
return nil
}

firstRequestedReviewer, err := getPullRequestRequestedReviewer(prNumber, GITHUB_TOKEN)
if err != nil {
return err
}

previouslyInvolvedReviewers, err := getPullRequestPreviousAssignedReviewers(prNumber, GITHUB_TOKEN)
if err != nil {
return err
}

foundTeamReviewer := false
// Returns a list of users to request review from, as well as a new primary reviewer if this is the first run.
func chooseReviewers(firstRequestedReviewer string, previouslyInvolvedReviewers []string) (reviewersToRequest []string, newPrimaryReviewer string) {
hasPrimaryReviewer := false
newPrimaryReviewer = ""

if firstRequestedReviewer != "" {
foundTeamReviewer = true
hasPrimaryReviewer = true
}

if previouslyInvolvedReviewers != nil {
for _, reviewer := range previouslyInvolvedReviewers {
if isTeamReviewer(reviewer) {
foundTeamReviewer = true
err = requestPullRequestReviewer(prNumber, reviewer, GITHUB_TOKEN)
if err != nil {
return err
}
hasPrimaryReviewer = true
reviewersToRequest = append(reviewersToRequest, reviewer)
}
}
}

if !foundTeamReviewer {
err = requestRandomReviewer(prNumber, GITHUB_TOKEN)
if err != nil {
return err
}
if !hasPrimaryReviewer {
newPrimaryReviewer = getRandomReviewer()
reviewersToRequest = append(reviewersToRequest, newPrimaryReviewer)
}

return nil
return reviewersToRequest, newPrimaryReviewer
}

func getPullRequestAuthor(prNumber, GITHUB_TOKEN string) (string, error) {
Expand Down Expand Up @@ -144,25 +127,23 @@ func requestPullRequestReviewer(prNumber, assignee, GITHUB_TOKEN string) error {
return nil
}

func requestRandomReviewer(prNumber, GITHUB_TOKEN string) error {
assignee := getRandomReviewer()
err := requestPullRequestReviewer(prNumber, assignee, GITHUB_TOKEN)
if err != nil {
return err
}
err = postComment(prNumber, assignee, GITHUB_TOKEN)
func formatReviewerComment(newPrimaryReviewer string, authorUserType userType, trusted bool) string {
tmpl, err := template.New("REVIEWER_ASSIGNMENT_COMMENT.md").Parse(reviewerAssignmentComment)
if err != nil {
return err
}
return nil

panic(fmt.Sprintf("Unable to parse REVIEWER_ASSIGNMENT_COMMENT.md: %s", err))
}
sb := new(strings.Builder)
tmpl.Execute(sb, map[string]interface{}{
"reviewer": newPrimaryReviewer,
"authorUserType": authorUserType.String(),
"trusted": trusted,
})
return sb.String()
}

func postComment(prNumber, reviewer, GITHUB_TOKEN string) error {
func postComment(prNumber, comment, GITHUB_TOKEN string, authorUserType userType) error {
url := fmt.Sprintf("https://api.github.com/repos/GoogleCloudPlatform/magic-modules/issues/%s/comments", prNumber)

comment := strings.Replace(reviewerAssignmentComment, "{{reviewer}}", reviewer, 1)

body := map[string]string{
"body": comment,
}
Expand All @@ -173,10 +154,10 @@ func postComment(prNumber, reviewer, GITHUB_TOKEN string) error {
}

if reqStatusCode != http.StatusCreated {
return fmt.Errorf("Error posting reviewer assignment comment for PR %s", prNumber)
return fmt.Errorf("Error posting comment for PR %s", prNumber)
}

fmt.Printf("Successfully posted reviewer assignment comment to pull request %s\n", prNumber)
fmt.Printf("Successfully posted comment to pull request %s\n", prNumber)

return nil
}
135 changes: 135 additions & 0 deletions .ci/containers/membership-checker/reviewer_assignment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package main

import (
"fmt"
"strings"
"testing"

"golang.org/x/exp/slices"
)

func TestChooseReviewers(t *testing.T) {
cases := map[string]struct {
FirstRequestedReviewer string
PreviouslyInvolvedReviewers []string
ExpectReviewersFromList, ExpectSpecificReviewers []string
ExpectPrimaryReviewer bool
}{
"no previous review requests assigns new reviewer from team": {
FirstRequestedReviewer: "",
PreviouslyInvolvedReviewers: []string{},
ExpectReviewersFromList: removes(reviewerRotation, onVacationReviewers),
ExpectPrimaryReviewer: true,
},
"first requested reviewer means that primary reviewer was already selected": {
FirstRequestedReviewer: "foobar",
PreviouslyInvolvedReviewers: []string{},
ExpectPrimaryReviewer: false,
},
"previously involved team member reviewers should have review requested and mean that primary reviewer was already selected": {
FirstRequestedReviewer: "",
PreviouslyInvolvedReviewers: []string{reviewerRotation[0]},
ExpectSpecificReviewers: []string{reviewerRotation[0]},
ExpectPrimaryReviewer: false,
},
"previously involved reviewers that are not team members are ignored": {
FirstRequestedReviewer: "",
PreviouslyInvolvedReviewers: []string{"foobar"},
ExpectReviewersFromList: removes(reviewerRotation, onVacationReviewers),
ExpectPrimaryReviewer: true,
},
"only previously involved team member reviewers will have review requested": {
FirstRequestedReviewer: "",
PreviouslyInvolvedReviewers: []string{reviewerRotation[0], "foobar", reviewerRotation[1]},
ExpectSpecificReviewers: []string{reviewerRotation[0], reviewerRotation[1]},
ExpectPrimaryReviewer: false,
},
"primary reviewer will not have review requested even if other team members previously reviewed": {
FirstRequestedReviewer: reviewerRotation[1],
PreviouslyInvolvedReviewers: []string{reviewerRotation[0]},
ExpectSpecificReviewers: []string{reviewerRotation[0]},
ExpectPrimaryReviewer: false,
},
}

for tn, tc := range cases {
tc := tc
t.Run(tn, func(t *testing.T) {
t.Parallel()
reviewers, primaryReviewer := chooseReviewers(tc.FirstRequestedReviewer, tc.PreviouslyInvolvedReviewers)
if tc.ExpectPrimaryReviewer && primaryReviewer == "" {
t.Error("wanted primary reviewer to be returned; got none")
}
if !tc.ExpectPrimaryReviewer && primaryReviewer != "" {
t.Errorf("wanted no primary reviewer; got %s", primaryReviewer)
}
if len(tc.ExpectReviewersFromList) > 0 {
for _, reviewer := range reviewers {
if !slices.Contains(tc.ExpectReviewersFromList, reviewer) {
t.Errorf("wanted reviewer %s to be in list %v but they were not", reviewer, tc.ExpectReviewersFromList)
}
}
}
if len(tc.ExpectSpecificReviewers) > 0 {
if !slices.Equal(reviewers, tc.ExpectSpecificReviewers) {
t.Errorf("wanted reviewers to be %v; instead got %v", tc.ExpectSpecificReviewers, reviewers)
}
}
})
}
}

func TestFormatReviewerComment(t *testing.T) {
cases := map[string]struct {
Reviewer string
AuthorUserType userType
Trusted bool
}{
"community contributor": {
Reviewer: "foobar",
AuthorUserType: communityUserType,
Trusted: false,
},
"googler": {
Reviewer: "foobar",
AuthorUserType: googlerUserType,
Trusted: true,
},
"core contributor": {
Reviewer: "foobar",
AuthorUserType: coreContributorUserType,
Trusted: true,
},
}

for tn, tc := range cases {
tc := tc
t.Run(tn, func(t *testing.T) {
t.Parallel()
comment := formatReviewerComment(tc.Reviewer, tc.AuthorUserType, tc.Trusted)
t.Log(comment)
if !strings.Contains(comment, fmt.Sprintf("@%s", tc.Reviewer)) {
t.Errorf("wanted comment to contain @%s; does not.", tc.Reviewer)
}
if !strings.Contains(comment, tc.AuthorUserType.String()) {
t.Errorf("wanted comment to contain user type (%s); does not.", tc.AuthorUserType.String())
}
if strings.Contains(comment, fmt.Sprintf("~%s~", tc.AuthorUserType.String())) {
t.Errorf("wanted user type (%s) in comment to not be crossed out, but it is", tc.AuthorUserType.String())
}
for _, ut := range []userType{communityUserType, googlerUserType, coreContributorUserType} {
if ut != tc.AuthorUserType && !strings.Contains(comment, fmt.Sprintf("~%s~", ut.String())) {
t.Errorf("wanted other user type (%s) in comment to be crossed out, but it is not", ut)
}
}

if tc.Trusted && !strings.Contains(comment, "Tests will run automatically") {
t.Errorf("wanted comment to say tests will run automatically; does not")
}
if !tc.Trusted && !strings.Contains(comment, "Tests will require approval") {
t.Errorf("wanted comment to say tests will require approval; does not")
}
})

}
}
2 changes: 1 addition & 1 deletion .ci/gcb-run-rake-tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
steps:
- name: 'gcr.io/$PROJECT_ID/downstream-builder'
- name: 'gcr.io/graphite-docker-images/build-environment'
id: run-rake-tests
entrypoint: bundle
dir: mmv1
Expand Down
Loading