From 704a5eb1e5bcf4555666f5000bf62082009fe596 Mon Sep 17 00:00:00 2001 From: Jamie Lennox Date: Tue, 29 May 2018 17:30:55 +1000 Subject: [PATCH 1/3] Allow using in repo configuration for cloudbuild trigger Cloudbuild triggers have a complex configuration that can be defined from the API. When using the console, the more typical way of doing this is to defined the configuration within the repository and point the configuration to the file that defines the config. This can be supported by sending the filename parameter instead of the build parameter, however only one can be sent. --- google/resource_cloudbuild_build_trigger.go | 18 ++++++++++++++++-- .../docs/r/cloudbuild_trigger.html.markdown | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/google/resource_cloudbuild_build_trigger.go b/google/resource_cloudbuild_build_trigger.go index a4236ed2e94..c5bcfb127cd 100644 --- a/google/resource_cloudbuild_build_trigger.go +++ b/google/resource_cloudbuild_build_trigger.go @@ -36,6 +36,12 @@ func resourceCloudBuildTrigger() *schema.Resource { Computed: true, ForceNew: true, }, + "filename": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"build"}, + }, "build": { Type: schema.TypeList, Description: "Contents of the build template.", @@ -142,7 +148,12 @@ func resourceCloudbuildBuildTriggerCreate(d *schema.ResourceData, meta interface buildTrigger.Description = v.(string) } - buildTrigger.Build = expandCloudbuildBuildTriggerBuild(d) + if v, ok := d.GetOk("filename"); ok { + buildTrigger.Filename = v.(string) + } else { + buildTrigger.Build = expandCloudbuildBuildTriggerBuild(d) + } + buildTrigger.TriggerTemplate = expandCloudbuildBuildTriggerTemplate(d, project) tstr, err := json.Marshal(buildTrigger) @@ -179,7 +190,10 @@ func resourceCloudbuildBuildTriggerRead(d *schema.ResourceData, meta interface{} if buildTrigger.TriggerTemplate != nil { d.Set("trigger_template", flattenCloudbuildBuildTriggerTemplate(d, config, buildTrigger.TriggerTemplate)) } - if buildTrigger.Build != nil { + + if buildTrigger.Filename != "" { + d.Set("filename", buildTrigger.Filename) + } else if buildTrigger.Build != nil { d.Set("build", flattenCloudbuildBuildTriggerBuild(d, config, buildTrigger.Build)) } diff --git a/website/docs/r/cloudbuild_trigger.html.markdown b/website/docs/r/cloudbuild_trigger.html.markdown index b080471bdf8..dc6e23d39b0 100644 --- a/website/docs/r/cloudbuild_trigger.html.markdown +++ b/website/docs/r/cloudbuild_trigger.html.markdown @@ -33,6 +33,21 @@ resource "google_cloudbuild_trigger" "build_trigger" { } ``` +OR + +```hcl +resource "google_cloudbuild_trigger" "build_trigger" { + project = "my-project" + trigger_template { + branch_name = "master" + project = "my-project" + repo_name = "some-repo" + } + filename = "cloudbuild.yaml" +} +``` + + ## Argument Reference (Argument descriptions sourced from https://godoc.org/google.golang.org/api/cloudbuild/v1#BuildTrigger) @@ -59,6 +74,10 @@ will be expanded when the build is created: or resolved from the specified branch or tag. * `$SHORT_SHA`: first 7 characters of `$REVISION_ID` or `$COMMIT_SHA`. +* `filename` - (Optional) Specify the path to a Cloud Build configuration file +in the Git repo. This is mutually exclusive with `build`. By default this is +typically `cloudbuild.yaml` however it can be specified by the user. + --- The `trigger_template` block supports: From ef23dc9f48698f4ea18c9f6cb79943c6e4141801 Mon Sep 17 00:00:00 2001 From: Jamie Lennox Date: Wed, 30 May 2018 16:20:26 +1000 Subject: [PATCH 2/3] Acceptance testing for cloudbuild trigger with filename Ensure that when a cloudbuild repo trigger is created with a filename, that filename is what actually ends up in the cloud. --- .../resource_cloudbuild_build_trigger_test.go | 109 ++++++++++++++++-- 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/google/resource_cloudbuild_build_trigger_test.go b/google/resource_cloudbuild_build_trigger_test.go index 63fefd9af3e..c9d9bdf0e25 100644 --- a/google/resource_cloudbuild_build_trigger_test.go +++ b/google/resource_cloudbuild_build_trigger_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" + cloudbuild "google.golang.org/api/cloudbuild/v1" ) func TestAccCloudBuildTrigger_basic(t *testing.T) { @@ -37,24 +38,80 @@ func TestAccCloudBuildTrigger_basic(t *testing.T) { }) } +func TestAccCloudBuildTrigger_filename(t *testing.T) { + t.Parallel() + + projectID := "terraform-" + acctest.RandString(10) + projectOrg := getTestOrgFromEnv(t) + projectBillingAccount := getTestBillingAccountFromEnv(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGoogleCloudBuildTriggerVersionsDestroyed, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testGoogleCloudBuildTrigger_filename(projectID, projectOrg, projectBillingAccount), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleCloudFilenameConfig("google_cloudbuild_trigger.filename_build_trigger"), + ), + }, + resource.TestStep{ + Config: testGoogleCloudBuildTrigger_removed(projectID, projectOrg, projectBillingAccount), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleCloudBuildTriggerWasRemovedFromState("google_cloudbuild_trigger.filename_build_trigger"), + ), + }, + }, + }) + +} + +func testAccGetBuildTrigger(s *terraform.State, resourceName string) (*cloudbuild.BuildTrigger, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return nil, fmt.Errorf("Resource not found: %s", resourceName) + } + + if rs.Primary.ID == "" { + return nil, fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + project := rs.Primary.Attributes["project"] + + trigger, err := config.clientBuild.Projects.Triggers.Get(project, rs.Primary.ID).Do() + if err != nil { + return nil, fmt.Errorf("Trigger does not exist") + } + + return trigger, nil +} + func testAccCheckGoogleCloudBuildTriggerExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { + _, err := testAccGetBuildTrigger(s, resourceName) - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("Resource not found: %s", resourceName) + if err != nil { + return fmt.Errorf("Trigger does not exist") } - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - config := testAccProvider.Meta().(*Config) - project := rs.Primary.Attributes["project"] + return nil + } +} + +func testAccCheckGoogleCloudFilenameConfig(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + trigger, err := testAccGetBuildTrigger(s, resourceName) - _, err := config.clientBuild.Projects.Triggers.Get(project, rs.Primary.ID).Do() if err != nil { return fmt.Errorf("Trigger does not exist") } + + if trigger.Filename != "cloudbuild.yaml" { + return fmt.Errorf("Config filename mismatch: %s", trigger.Filename) + } + return nil } } @@ -147,6 +204,40 @@ resource "google_cloudbuild_trigger" "build_trigger" { `, projectID, projectID, projectOrg, projectBillingAccount) } +func testGoogleCloudBuildTrigger_filename(projectID, projectOrg, projectBillingAccount string) string { + return fmt.Sprintf(` +resource "google_project" "acceptance" { + name = "%s" + project_id = "%s" + org_id = "%s" + billing_account = "%s" +} + +resource "google_project_services" "acceptance" { + project = "${google_project.acceptance.project_id}" + + services = [ + "cloudbuild.googleapis.com", + "containerregistry.googleapis.com", + "logging.googleapis.com", + "pubsub.googleapis.com", + "storage-api.googleapis.com", + ] +} + +resource "google_cloudbuild_trigger" "filename_build_trigger" { + project = "${google_project_services.acceptance.project}" + description = "acceptance test build trigger" + trigger_template { + branch_name = "master" + project = "${google_project_services.acceptance.project}" + repo_name = "some-repo" + } + filename = "cloudbuild.yaml" +} + `, projectID, projectID, projectOrg, projectBillingAccount) +} + func testGoogleCloudBuildTrigger_removed(projectID, projectOrg, projectBillingAccount string) string { return fmt.Sprintf(` resource "google_project" "acceptance" { From d700c35cb63effdab7620e2f071584728b796140 Mon Sep 17 00:00:00 2001 From: Jamie Lennox Date: Fri, 1 Jun 2018 10:06:52 +1000 Subject: [PATCH 3/3] Don't specify "by default" in cloudbuild-trigger. The docs shouldn't say that "cloudbuild.yaml" is used by default. There is no default from the APIs, but the console suggest using this value. Just say it's the typical value in documentation. --- website/docs/r/cloudbuild_trigger.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/cloudbuild_trigger.html.markdown b/website/docs/r/cloudbuild_trigger.html.markdown index dc6e23d39b0..05d3ab4e19f 100644 --- a/website/docs/r/cloudbuild_trigger.html.markdown +++ b/website/docs/r/cloudbuild_trigger.html.markdown @@ -75,8 +75,8 @@ will be expanded when the build is created: * `$SHORT_SHA`: first 7 characters of `$REVISION_ID` or `$COMMIT_SHA`. * `filename` - (Optional) Specify the path to a Cloud Build configuration file -in the Git repo. This is mutually exclusive with `build`. By default this is -typically `cloudbuild.yaml` however it can be specified by the user. +in the Git repo. This is mutually exclusive with `build`. This is typically +`cloudbuild.yaml` however it can be specified by the user. ---