Skip to content

Commit 3691f3d

Browse files
authored
Merge branch 'GoogleCloudPlatform:main' into lv_dp
2 parents 2c08595 + 7a11f3d commit 3691f3d

File tree

226 files changed

+9164
-933
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

226 files changed

+9164
-933
lines changed

.ci/infra/terraform/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,4 @@ Quotas that will need to be adjusted to support all tests:
7373
- compute.googleapis.com/c2_cpus (us-central1)
7474
- compute.googleapis.com/n2_cpus (us-central1) to 36+
7575
- VMware Engine standard 72 vCPUs nodes per region - southamerica-east1 to 21
76+
- logging.googleapis.com/log_buckets_count to 200
Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,43 @@
11
package cmd
22

33
import (
4-
"magician/exec"
5-
"magician/github"
6-
"os"
74
"testing"
85
)
96

107
func TestFetchPRNumber(t *testing.T) {
11-
rnr, err := exec.NewRunner()
12-
if err != nil {
13-
t.Errorf("error creating Runner: %s", err)
14-
}
15-
16-
githubToken, ok := os.LookupEnv("GITHUB_TOKEN_CLASSIC")
17-
if !ok {
18-
t.Errorf("did not provide GITHUB_TOKEN_CLASSIC environment variable")
8+
mr := NewMockRunner()
9+
gh := &mockGithub{
10+
calledMethods: make(map[string][][]any),
11+
commitMessage: "Add `additional_group_keys` attribute to `google_cloud_identity_group` resource (#9217) (#6504)\n\n* Add `additional_group_keys` attribute to `google_cloud_identity_group` resource\n\n* Update acceptance test to check for attribute\n\n* Fix test check\n\n* Add `output: true` to nested properties in output field\n[upstream:49d3741f9d4d810a0a4768363bb8498afa21c688]\n\nSigned-off-by: Modular Magician <[email protected]>",
1912
}
2013

21-
gh := github.NewClient(githubToken)
22-
23-
prNumber, err := fetchPRNumber("8c6e61bb62d52c950008340deafc1e2a2041898a", "main", rnr, gh)
24-
14+
// Call function with mocks
15+
prNumber, err := fetchPRNumber("8c6e61bb62d52c950008340deafc1e2a2041898a", "main", mr, gh)
2516
if err != nil {
2617
t.Errorf("error fetching PR number: %s", err)
2718
}
2819

2920
if prNumber != "6504" {
3021
t.Errorf("PR number is %s, expected 6504", prNumber)
3122
}
23+
24+
// Verify GitHub API was called
25+
if calls, ok := gh.calledMethods["GetCommitMessage"]; !ok || len(calls) == 0 {
26+
t.Errorf("Expected GetCommitMessage to be called")
27+
} else {
28+
args := calls[0]
29+
if len(args) != 3 {
30+
t.Errorf("Expected GetCommitMessage to be called with 3 arguments, got %d", len(args))
31+
} else {
32+
if args[0] != "hashicorp" {
33+
t.Errorf("Expected owner to be 'hashicorp', got '%s'", args[0])
34+
}
35+
if args[1] != "terraform-provider-google-beta" {
36+
t.Errorf("Expected repo to be 'terraform-provider-google-beta', got '%s'", args[1])
37+
}
38+
if args[2] != "8c6e61bb62d52c950008340deafc1e2a2041898a" {
39+
t.Errorf("Expected SHA to be '8c6e61bb62d52c950008340deafc1e2a2041898a', got '%s'", args[2])
40+
}
41+
}
42+
}
3243
}

.ci/magician/cmd/generate_comment.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ var (
4545
)
4646

4747
type Diff struct {
48-
Title string
49-
Repo string
50-
ShortStat string
48+
Title string
49+
Repo string
50+
ShortStat string
51+
CommitSHA string
52+
OldCommitSHA string
5153
}
5254

5355
type BreakingChange struct {
@@ -77,7 +79,6 @@ type Errors struct {
7779
}
7880

7981
type diffCommentData struct {
80-
PrNumber int
8182
Diffs []Diff
8283
BreakingChanges []BreakingChange
8384
MissingServiceLabels []string
@@ -214,9 +215,7 @@ func execGenerateComment(prNumber int, ghTokenMagicModules, buildId, buildStep,
214215
}
215216

216217
// Initialize repos
217-
data := diffCommentData{
218-
PrNumber: prNumber,
219-
}
218+
data := diffCommentData{}
220219
for _, repo := range []*source.Repo{&tpgRepo, &tpgbRepo, &tgcRepo, &tfoicsRepo} {
221220
errors[repo.Title] = []string{}
222221
repo.Branch = newBranch
@@ -262,10 +261,24 @@ func execGenerateComment(prNumber int, ghTokenMagicModules, buildId, buildStep,
262261
errors[repo.Title] = append(errors[repo.Title], "Failed to compute repo diff shortstats")
263262
}
264263
if shortStat != "" {
264+
variablePath := fmt.Sprintf("/workspace/commitSHA_modular-magician_%s.txt", repo.Name)
265+
oldVariablePath := fmt.Sprintf("/workspace/commitSHA_modular-magician_%s-old.txt", repo.Name)
266+
commitSHA, err := rnr.ReadFile(variablePath)
267+
if err != nil {
268+
errors[repo.Title] = append(errors[repo.Title], "Failed to read commit sha from file")
269+
continue
270+
}
271+
oldCommitSHA, err := rnr.ReadFile(oldVariablePath)
272+
if err != nil {
273+
errors[repo.Title] = append(errors[repo.Title], "Failed to read old commit sha from file")
274+
continue
275+
}
265276
diffs = append(diffs, Diff{
266-
Title: repo.Title,
267-
Repo: repo.Name,
268-
ShortStat: shortStat,
277+
Title: repo.Title,
278+
Repo: repo.Name,
279+
ShortStat: shortStat,
280+
CommitSHA: commitSHA,
281+
OldCommitSHA: oldCommitSHA,
269282
})
270283
repo.ChangedFiles, err = ctlr.DiffNameOnly(repo, oldBranch, newBranch)
271284
if err != nil {

.ci/magician/cmd/generate_comment_test.go

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package cmd
1717

1818
import (
19+
"fmt"
1920
"os"
2021
"reflect"
2122
"testing"
@@ -38,6 +39,22 @@ func TestExecGenerateComment(t *testing.T) {
3839
"GOPATH": os.Getenv("GOPATH"),
3940
"HOME": os.Getenv("HOME"),
4041
}
42+
for _, repo := range []string{
43+
"terraform-provider-google",
44+
"terraform-provider-google-beta",
45+
"terraform-google-conversion",
46+
} {
47+
variablePathOld := fmt.Sprintf("/workspace/commitSHA_modular-magician_%s-old.txt", repo)
48+
variablePath := fmt.Sprintf("/workspace/commitSHA_modular-magician_%s.txt", repo)
49+
err := mr.WriteFile(variablePathOld, "1a2a3a4a")
50+
if err != nil {
51+
t.Errorf("Error writing file: %s", err)
52+
}
53+
err = mr.WriteFile(variablePath, "1a2a3a4b")
54+
if err != nil {
55+
t.Errorf("Error writing file: %s", err)
56+
}
57+
}
4158
execGenerateComment(
4259
123456,
4360
"*******",
@@ -115,7 +132,7 @@ func TestExecGenerateComment(t *testing.T) {
115132
{"123456", "terraform-provider-breaking-change-test", "success", "https://console.cloud.google.com/cloud-build/builds;region=global/build1;step=17?project=project1", "sha1"},
116133
{"123456", "terraform-provider-missing-service-labels", "success", "https://console.cloud.google.com/cloud-build/builds;region=global/build1;step=17?project=project1", "sha1"},
117134
},
118-
"PostComment": {{"123456", "Hi there, I'm the Modular magician. I've detected the following information about your changes:\n\n## Diff report\n\nYour PR generated some diffs in downstreams - here they are.\n\n`google` provider: [Diff](https://github.com/modular-magician/terraform-provider-google/compare/auto-pr-123456-old..auto-pr-123456) ( 2 files changed, 40 insertions(+))\n`google-beta` provider: [Diff](https://github.com/modular-magician/terraform-provider-google-beta/compare/auto-pr-123456-old..auto-pr-123456) ( 2 files changed, 40 insertions(+))\n`terraform-google-conversion`: [Diff](https://github.com/modular-magician/terraform-google-conversion/compare/auto-pr-123456-old..auto-pr-123456) ( 1 file changed, 10 insertions(+))\n\n\n\n## Missing test report\nYour PR includes resource fields which are not covered by any test.\n\nResource: `google_folder_access_approval_settings` (3 total tests)\nPlease add an acceptance test which includes these fields. The test should include the following:\n\n```hcl\nresource \"google_folder_access_approval_settings\" \"primary\" {\n uncovered_field = # value needed\n}\n\n```\n\n\n"}},
135+
"PostComment": {{"123456", "Hi there, I'm the Modular magician. I've detected the following information about your changes:\n\n## Diff report\n\nYour PR generated some diffs in downstreams - here they are.\n\n`google` provider: [Diff](https://github.com/modular-magician/terraform-provider-google/compare/1a2a3a4a..1a2a3a4b) ( 2 files changed, 40 insertions(+))\n`google-beta` provider: [Diff](https://github.com/modular-magician/terraform-provider-google-beta/compare/1a2a3a4a..1a2a3a4b) ( 2 files changed, 40 insertions(+))\n`terraform-google-conversion`: [Diff](https://github.com/modular-magician/terraform-google-conversion/compare/1a2a3a4a..1a2a3a4b) ( 1 file changed, 10 insertions(+))\n\n\n\n## Missing test report\nYour PR includes resource fields which are not covered by any test.\n\nResource: `google_folder_access_approval_settings` (3 total tests)\nPlease add an acceptance test which includes these fields. The test should include the following:\n\n```hcl\nresource \"google_folder_access_approval_settings\" \"primary\" {\n uncovered_field = # value needed\n}\n\n```\n\n\n"}},
119136
"AddLabels": {{"123456", []string{"service/alloydb"}}},
120137
} {
121138
if actualCalls, ok := gh.calledMethods[method]; !ok {
@@ -170,24 +187,27 @@ func TestFormatDiffComment(t *testing.T) {
170187
},
171188
"diffs are displayed": {
172189
data: diffCommentData{
173-
PrNumber: 1234567890,
174190
Diffs: []Diff{
175191
{
176-
Title: "Repo 1",
177-
Repo: "repo-1",
178-
ShortStat: "+1 added, -1 removed",
192+
Title: "Repo 1",
193+
Repo: "repo-1",
194+
ShortStat: "+1 added, -1 removed",
195+
CommitSHA: "1a2a3a4b",
196+
OldCommitSHA: "1a2a3a4a",
179197
},
180198
{
181-
Title: "Repo 2",
182-
Repo: "repo-2",
183-
ShortStat: "+2 added, -2 removed",
199+
Title: "Repo 2",
200+
Repo: "repo-2",
201+
ShortStat: "+2 added, -2 removed",
202+
CommitSHA: "1a2a3a4d",
203+
OldCommitSHA: "1a2a3a4c",
184204
},
185205
},
186206
},
187207
expectedStrings: []string{
188208
"## Diff report",
189209
"generated some diffs",
190-
"Repo 1: [Diff](https://github.com/modular-magician/repo-1/compare/auto-pr-1234567890-old..auto-pr-1234567890) (+1 added, -1 removed)\nRepo 2: [Diff](https://github.com/modular-magician/repo-2/compare/auto-pr-1234567890-old..auto-pr-1234567890) (+2 added, -2 removed)",
210+
"Repo 1: [Diff](https://github.com/modular-magician/repo-1/compare/1a2a3a4a..1a2a3a4b) (+1 added, -1 removed)\nRepo 2: [Diff](https://github.com/modular-magician/repo-2/compare/1a2a3a4c..1a2a3a4d) (+2 added, -2 removed)",
191211
},
192212
notExpectedStrings: []string{
193213
"hasn't generated any diffs",

.ci/magician/cmd/generate_downstream.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,11 @@ func runMake(downstreamRepo *source.Repo, command string, rnr ExecRunner) error
300300
return err
301301
}
302302
case "terraform":
303+
// --- legacy -- can be cleaned up after go/mm-pull/13722 is submitted
303304
if _, err := rnr.Run("make", []string{"clean-provider", "OUTPUT_PATH=" + downstreamRepo.Path}, nil); err != nil {
304305
return err
305306
}
307+
// -------------------------------------------------------------------
306308
if _, err := rnr.Run("make", []string{"provider", "OUTPUT_PATH=" + downstreamRepo.Path, fmt.Sprintf("VERSION=%s", downstreamRepo.Version)}, nil); err != nil {
307309
return err
308310
}
@@ -338,8 +340,9 @@ func createCommit(scratchRepo *source.Repo, commitMessage string, rnr ExecRunner
338340
return "", err
339341
}
340342

341-
if _, err := rnr.Run("git", []string{"commit", "--signoff", "-m", commitMessage}, nil); err != nil {
342-
return "", err
343+
_, commitErr := rnr.Run("git", []string{"commit", "--signoff", "-m", commitMessage}, nil)
344+
if commitErr != nil && !strings.Contains(commitErr.Error(), "nothing to commit") {
345+
return "", commitErr
343346
}
344347

345348
commitSha, err := rnr.Run("git", []string{"rev-parse", "HEAD"}, nil)
@@ -352,16 +355,21 @@ func createCommit(scratchRepo *source.Repo, commitMessage string, rnr ExecRunner
352355

353356
// auto-pr's use commitSHA_modular-magician_<repo>_.txt file to communicate commmit hash
354357
// across cloudbuild steps. Used in test-tpg to execute unit tests for the HEAD commit
355-
if strings.HasPrefix(scratchRepo.Branch, "auto-pr-") && !strings.HasSuffix(scratchRepo.Branch, "-old") {
356-
variablePath := fmt.Sprintf("/workspace/commitSHA_modular-magician_%s.txt", scratchRepo.Name)
358+
if strings.HasPrefix(scratchRepo.Branch, "auto-pr-") {
359+
var variablePath string
360+
if strings.HasSuffix(scratchRepo.Branch, "-old") {
361+
variablePath = fmt.Sprintf("/workspace/commitSHA_modular-magician_%s-old.txt", scratchRepo.Name)
362+
} else {
363+
variablePath = fmt.Sprintf("/workspace/commitSHA_modular-magician_%s.txt", scratchRepo.Name)
364+
}
357365
fmt.Println("variablePath: ", variablePath)
358366
err = rnr.WriteFile(variablePath, commitSha)
359367
if err != nil {
360368
fmt.Println("Error:", err)
361369
}
362370
}
363371

364-
return commitSha, err
372+
return commitSha, commitErr
365373
}
366374

367375
func addChangelogEntry(downstreamRepo *source.Repo, pullRequest *github.PullRequest, rnr ExecRunner) error {

.ci/magician/cmd/mock_github_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type mockGithub struct {
2929
pullRequestComments []github.PullRequestComment
3030
teamMembers map[string][]github.User
3131
calledMethods map[string][][]any
32+
commitMessage string
3233
}
3334

3435
func (m *mockGithub) GetPullRequest(prNumber string) (github.PullRequest, error) {
@@ -63,7 +64,7 @@ func (m *mockGithub) GetPullRequestComments(prNumber string) ([]github.PullReque
6364

6465
func (m *mockGithub) GetCommitMessage(owner, repo, sha string) (string, error) {
6566
m.calledMethods["GetCommitMessage"] = append(m.calledMethods["GetCommitMessage"], []any{owner, repo, sha})
66-
return "commit message", nil
67+
return m.commitMessage, nil
6768
}
6869

6970
func (m *mockGithub) GetTeamMembers(organization, team string) ([]github.User, error) {

.ci/magician/cmd/mock_runner_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type mockRunner struct {
4141
cwd string
4242
dirStack *list.List
4343
notifyError bool
44+
fileContents map[string]string
4445
}
4546

4647
func sortedEnvString(env map[string]string) string {
@@ -107,10 +108,14 @@ func (mr *mockRunner) Walk(root string, fn filepath.WalkFunc) error {
107108
}
108109

109110
func (mr *mockRunner) ReadFile(name string) (string, error) {
110-
return "", nil
111+
return mr.fileContents[name], nil
111112
}
112113

113114
func (mr *mockRunner) WriteFile(name, data string) error {
115+
if mr.fileContents == nil {
116+
mr.fileContents = make(map[string]string)
117+
}
118+
mr.fileContents[name] = data
114119
return nil
115120
}
116121

.ci/magician/cmd/templates/DIFF_COMMENT.md.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Your PR hasn't generated any diffs, but I'll let you know if a future commit doe
77
Your PR generated some diffs in downstreams - here they are.
88

99
{{range .Diffs -}}
10-
{{.Title}}: [Diff](https://github.com/modular-magician/{{.Repo}}/compare/auto-pr-{{$.PrNumber}}-old..auto-pr-{{$.PrNumber}}) ({{.ShortStat}})
10+
{{.Title}}: [Diff](https://github.com/modular-magician/{{.Repo}}/compare/{{.OldCommitSHA}}..{{.CommitSHA}}) ({{.ShortStat}})
1111
{{end -}}
1212
{{end -}}
1313

.ci/magician/github/get.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,28 @@ func (gh *Client) GetTeamMembers(organization, team string) ([]User, error) {
145145
}
146146
return members, nil
147147
}
148+
149+
func (gh *Client) IsOrgMember(author, org string) bool {
150+
url := fmt.Sprintf("https://api.github.com/orgs/%s/members/%s", org, author)
151+
err := utils.RequestCallWithRetry(url, "GET", gh.token, nil, nil)
152+
return err == nil
153+
}
154+
155+
func (gh *Client) IsTeamMember(organization, teamSlug, username string) bool {
156+
type TeamMembership struct {
157+
URL string `json:"url"`
158+
Role string `json:"role"`
159+
State string `json:"state"`
160+
}
161+
162+
url := fmt.Sprintf("https://api.github.com/orgs/%s/teams/%s/memberships/%s", organization, teamSlug, username)
163+
var membership TeamMembership
164+
err := utils.RequestCallWithRetry(url, "GET", gh.token, &membership, nil)
165+
166+
if err != nil {
167+
return false
168+
}
169+
170+
// User is considered a member if state is "active"
171+
return membership.State == "active"
172+
}

.ci/magician/github/membership.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,19 @@ func (gh *Client) GetUserType(user string) UserType {
5050
return CoreContributorUserType
5151
}
5252

53-
if isOrgMember(user, "GoogleCloudPlatform", gh.token) {
53+
if gh.IsTeamMember("GoogleCloudPlatform", "terraform", user) {
54+
fmt.Println("User is an active member of the 'terraform' team in 'GoogleCloudPlatform' organization")
55+
return GooglerUserType
56+
} else {
57+
fmt.Printf("User '%s' is not an active member of the 'terraform' team in 'GoogleCloudPlatform' organization\n", user)
58+
}
59+
60+
if gh.IsOrgMember(user, "GoogleCloudPlatform") {
5461
fmt.Println("User is a GCP org member")
5562
return GooglerUserType
5663
}
5764

58-
if isOrgMember(user, "googlers", gh.token) {
65+
if gh.IsOrgMember(user, "googlers") {
5966
fmt.Println("User is a googlers org member")
6067
return GooglerUserType
6168
}
@@ -74,13 +81,6 @@ func IsCoreReviewer(user string) bool {
7481
return isCoreReviewer
7582
}
7683

77-
func isOrgMember(author, org, githubToken string) bool {
78-
url := fmt.Sprintf("https://api.github.com/orgs/%s/members/%s", org, author)
79-
err := utils.RequestCallWithRetry(url, "GET", githubToken, nil, nil)
80-
81-
return err == nil
82-
}
83-
8484
// GetRandomReviewer returns a random available reviewer (optionally excluding some people from the reviewer pool)
8585
func GetRandomReviewer(excludedReviewers []string) string {
8686
availableReviewers := AvailableReviewers(excludedReviewers)

.ci/magician/github/set.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"fmt"
2020
utils "magician/utility"
2121
"strings"
22+
"time"
2223
)
2324

2425
func (gh *Client) PostBuildStatus(prNumber, title, state, targetURL, commitSha string) error {
@@ -165,7 +166,10 @@ func (gh *Client) MergePullRequest(owner, repo, prNumber, commitSha string) erro
165166
// Check if the error is "Merge already in progress" (405)
166167
if strings.Contains(err.Error(), "Merge already in progress") {
167168
fmt.Printf("Pull request %s is already being merged\n", prNumber)
168-
return nil
169+
// This status does not indicate that the Pull Request was merged
170+
// Try again after 20s
171+
time.Sleep(20 * time.Second)
172+
return gh.MergePullRequest(owner, repo, prNumber, commitSha)
169173
}
170174
// Check if the PR is already merged (returns 405 Pull Request is not mergeable)
171175
if strings.Contains(err.Error(), "Pull Request is not mergeable") {

0 commit comments

Comments
 (0)