From 205ea0e5137d1b475ff71bd29a081f91c5681e6c Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:48:14 +0200 Subject: [PATCH] Allow setting the PR URL template for repos. --- CHANGELOG.md | 9 ++- docs/resources/repository.md | 1 + pkg/dbt_cloud/repository.go | 68 ++++++++++++++----- pkg/sdkv2/resources/repository.go | 22 +++++- .../resources/repository_acceptance_test.go | 5 +- 5 files changed, 81 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 674a83ef..2ce08f45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,14 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.13...HEAD) +## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v1.3.14...HEAD) + +# [0.3.14](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.13...v0.3.14) + +### Changes + +- Add support for setting the `pull_request_url_template` in `dbtcloud_repository` + # [0.3.13](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.3.12...v0.3.13) diff --git a/docs/resources/repository.md b/docs/resources/repository.md index 248f9427..38b85516 100644 --- a/docs/resources/repository.md +++ b/docs/resources/repository.md @@ -108,6 +108,7 @@ resource "dbtcloud_repository" "ado_repo" { - `github_installation_id` (Number) Identifier for the GitHub App - (for GitHub native integration only) - `gitlab_project_id` (Number) Identifier for the Gitlab project - (for GitLab native integration only) - `is_active` (Boolean) Whether the repository is active +- `pull_request_url_template` (String) URL template for creating a pull request. If it is not set, the default template will create a PR from the current branch to the branch configured in the Development environment. ### Read-Only diff --git a/pkg/dbt_cloud/repository.go b/pkg/dbt_cloud/repository.go index b80178d2..72c03587 100644 --- a/pkg/dbt_cloud/repository.go +++ b/pkg/dbt_cloud/repository.go @@ -9,19 +9,21 @@ import ( ) type Repository struct { - ID *int `json:"id,omitempty"` - AccountID int `json:"account_id"` - ProjectID int `json:"project_id"` - RemoteUrl string `json:"remote_url"` - State int `json:"state"` - AzureActiveDirectoryProjectID *string `json:"azure_active_directory_project_id,omitempty"` - AzureActiveDirectoryRepositoryID *string `json:"azure_active_directory_repository_id,omitempty"` - AzureBypassWebhookRegistrationFailure *bool `json:"azure_bypass_webhook_registration_failure,omitempty"` - GitCloneStrategy string `json:"git_clone_strategy"` - RepositoryCredentialsID *int `json:"repository_credentials_id,omitempty"` - GitlabProjectID *int `json:"gitlab_project_id"` - GithubInstallationID *int `json:"github_installation_id"` - DeployKey DeployKey `json:"deploy_key,omitempty"` + ID *int `json:"id,omitempty"` + AccountID int `json:"account_id"` + ProjectID int `json:"project_id"` + RemoteUrl string `json:"remote_url"` + State int `json:"state"` + AzureActiveDirectoryProjectID *string `json:"azure_active_directory_project_id,omitempty"` + AzureActiveDirectoryRepositoryID *string `json:"azure_active_directory_repository_id,omitempty"` + AzureBypassWebhookRegistrationFailure *bool `json:"azure_bypass_webhook_registration_failure,omitempty"` + GitCloneStrategy string `json:"git_clone_strategy"` + RepositoryCredentialsID *int `json:"repository_credentials_id,omitempty"` + GitlabProjectID *int `json:"gitlab_project_id,omitempty"` + GithubInstallationID *int `json:"github_installation_id,omitempty"` + DeployKey *DeployKey `json:"deploy_key,omitempty"` + DeployKeyID *int `json:"deploy_key_id,omitempty"` + PullRequestURLTemplate string `json:"pull_request_url_template,omitempty"` } type DeployKey struct { @@ -82,6 +84,7 @@ func (c *Client) CreateRepository( azureActiveDirectoryProjectID string, azureActiveDirectoryRepositoryID string, azureBypassWebhookRegistrationFailure bool, + pullRequestURLTemplate string, ) (*Repository, error) { state := STATE_ACTIVE if !isActive { @@ -89,11 +92,12 @@ func (c *Client) CreateRepository( } newRepository := Repository{ - AccountID: c.AccountID, - ProjectID: projectID, - RemoteUrl: remoteUrl, - State: state, - GitCloneStrategy: gitCloneStrategy, + AccountID: c.AccountID, + ProjectID: projectID, + RemoteUrl: remoteUrl, + State: state, + GitCloneStrategy: gitCloneStrategy, + PullRequestURLTemplate: pullRequestURLTemplate, } if gitlabProjectID != 0 { newRepository.GitlabProjectID = &gitlabProjectID @@ -136,6 +140,30 @@ func (c *Client) CreateRepository( return nil, err } + if pullRequestURLTemplate != "" { + // this is odd but we can't provide the pullRequestURLTemplate in the initial create + // we need to update the repository with the pullRequestURLTemplate + + // we need to update the repository with the deploy key id that was created + if repositoryResponse.Data.DeployKeyID != nil { + newRepository.DeployKeyID = repositoryResponse.Data.DeployKeyID + } + // and we also need to provide the credentials id if it was created + if repositoryResponse.Data.RepositoryCredentialsID != nil { + newRepository.RepositoryCredentialsID = repositoryResponse.Data.RepositoryCredentialsID + } + + updatedRepo, err := c.UpdateRepository( + strconv.Itoa(*repositoryResponse.Data.ID), + strconv.Itoa(projectID), + newRepository, + ) + if err != nil { + return nil, err + } + return updatedRepo, nil + } + return &repositoryResponse.Data, nil } @@ -143,6 +171,10 @@ func (c *Client) UpdateRepository( repositoryID, projectID string, repository Repository, ) (*Repository, error) { + + // we need to remove the GitLab project ID for updates + repository.GitlabProjectID = nil + repositoryData, err := json.Marshal(repository) if err != nil { return nil, err diff --git a/pkg/sdkv2/resources/repository.go b/pkg/sdkv2/resources/repository.go index c65c8df4..137485b5 100644 --- a/pkg/sdkv2/resources/repository.go +++ b/pkg/sdkv2/resources/repository.go @@ -98,6 +98,12 @@ func ResourceRepository() *schema.Resource { Computed: true, Description: "Public key generated by dbt when using `deploy_key` clone strategy", }, + "pull_request_url_template": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "URL template for creating a pull request. If it is not set, the default template will create a PR from the current branch to the branch configured in the Development environment.", + }, }, Importer: &schema.ResourceImporter{ @@ -124,6 +130,7 @@ func resourceRepositoryCreate( azureActiveDirectoryProjectID := d.Get("azure_active_directory_project_id").(string) azureActiveDirectoryRepositoryID := d.Get("azure_active_directory_repository_id").(string) azureBypassWebhookRegistrationFailure := d.Get("azure_bypass_webhook_registration_failure").(bool) + pullRequestURLTemplate := d.Get("pull_request_url_template").(string) repository, err := c.CreateRepository( projectId, @@ -135,6 +142,7 @@ func resourceRepositoryCreate( azureActiveDirectoryProjectID, azureActiveDirectoryRepositoryID, azureBypassWebhookRegistrationFailure, + pullRequestURLTemplate, ) if err != nil { return diag.FromErr(err) @@ -210,8 +218,10 @@ func resourceRepositoryRead( if err := d.Set("github_installation_id", repository.GithubInstallationID); err != nil { return diag.FromErr(err) } - if err := d.Set("deploy_key", repository.DeployKey.PublicKey); err != nil { - return diag.FromErr(err) + if repository.DeployKey != nil { + if err := d.Set("deploy_key", repository.DeployKey.PublicKey); err != nil { + return diag.FromErr(err) + } } // the following values are not sent back by the API so we set them as they are in the config if err := d.Set("azure_active_directory_project_id", d.Get("azure_active_directory_project_id").(string)); err != nil { @@ -223,6 +233,9 @@ func resourceRepositoryRead( if err := d.Set("azure_bypass_webhook_registration_failure", d.Get("azure_bypass_webhook_registration_failure").(bool)); err != nil { return diag.FromErr(err) } + if err := d.Set("pull_request_url_template", repository.PullRequestURLTemplate); err != nil { + return diag.FromErr(err) + } return diags } @@ -237,7 +250,7 @@ func resourceRepositoryUpdate( projectIdString := strings.Split(d.Id(), dbt_cloud.ID_DELIMITER)[0] repositoryIdString := strings.Split(d.Id(), dbt_cloud.ID_DELIMITER)[1] - if d.HasChange("is_active") { + if d.HasChange("is_active") || d.HasChange("pull_request_url_template") { repository, err := c.GetRepository(repositoryIdString, projectIdString) if err != nil { return diag.FromErr(err) @@ -251,6 +264,9 @@ func resourceRepositoryUpdate( repository.State = dbt_cloud.STATE_DELETED } } + if d.HasChange("pull_request_url_template") { + repository.PullRequestURLTemplate = d.Get("pull_request_url_template").(string) + } _, err = c.UpdateRepository(repositoryIdString, projectIdString, *repository) if err != nil { diff --git a/pkg/sdkv2/resources/repository_acceptance_test.go b/pkg/sdkv2/resources/repository_acceptance_test.go index 956a8085..ff166372 100644 --- a/pkg/sdkv2/resources/repository_acceptance_test.go +++ b/pkg/sdkv2/resources/repository_acceptance_test.go @@ -109,8 +109,8 @@ resource "dbtcloud_project" "test_project" { resource "dbtcloud_repository" "test_repository_github" { remote_url = "%s" project_id = dbtcloud_project.test_project.id - fetch_deploy_key = true - depends_on = [dbtcloud_project.test_project] + git_clone_strategy = "deploy_key" + pull_request_url_template = "https://github.com/my-org/my-repo/compare/qa...{{source}}" } `, projectName, repoUrl) } @@ -126,6 +126,7 @@ resource "dbtcloud_repository" "test_repository_github_application" { project_id = dbtcloud_project.test_project.id github_installation_id = 28374841 git_clone_strategy = "github_app" + pull_request_url_template = "https://github.com/my-org/my-repo/compare/qa...{{source}}" } `, projectName, repoUrl) }