diff --git a/client/deployment_create.go b/client/deployment_create.go
index 5ac38fc5..4a029f38 100644
--- a/client/deployment_create.go
+++ b/client/deployment_create.go
@@ -20,6 +20,11 @@ type DeploymentFile struct {
Sha string `json:"sha"`
Size int `json:"size"`
}
+type GitSource struct {
+ RepoId string `json:"repoId"`
+ Ref string `json:"ref"`
+ Type string `json:"type"`
+}
// CreateDeploymentRequest defines the request the Vercel API expects in order to create a deployment.
type CreateDeploymentRequest struct {
@@ -35,6 +40,7 @@ type CreateDeploymentRequest struct {
Regions []string `json:"regions,omitempty"`
Routes []interface{} `json:"routes,omitempty"`
Target string `json:"target,omitempty"`
+ GitSource *GitSource `json:"gitSource,omitempty"`
}
// DeploymentResponse defines the response the Vercel API returns when a deployment is created or updated.
@@ -59,15 +65,16 @@ type DeploymentResponse struct {
Build struct {
Environment []string `json:"env"`
} `json:"build"`
- AliasAssigned bool `json:"aliasAssigned"`
- ChecksConclusion string `json:"checksConclusion"`
- ErrorCode string `json:"errorCode"`
- ErrorMessage string `json:"errorMessage"`
- ID string `json:"id"`
- ProjectID string `json:"projectId"`
- ReadyState string `json:"readyState"`
- Target *string `json:"target"`
- URL string `json:"url"`
+ AliasAssigned bool `json:"aliasAssigned"`
+ ChecksConclusion string `json:"checksConclusion"`
+ ErrorCode string `json:"errorCode"`
+ ErrorMessage string `json:"errorMessage"`
+ ID string `json:"id"`
+ ProjectID string `json:"projectId"`
+ ReadyState string `json:"readyState"`
+ Target *string `json:"target"`
+ URL string `json:"url"`
+ GitSource GitSource `json:"gitSource"`
}
// IsComplete is used to determine whether a deployment is still processing, or whether it is fully done.
diff --git a/docs/resources/deployment.md b/docs/resources/deployment.md
index 009d2a36..b28e9fa4 100644
--- a/docs/resources/deployment.md
+++ b/docs/resources/deployment.md
@@ -63,13 +63,14 @@ resource "vercel_deployment" "example" {
### Required
-- `files` (Map of String) A map of files to be uploaded for the deployment. This should be provided by a `vercel_project_directory` or `vercel_file` data source.
- `project_id` (String) The project ID to add the deployment to.
### Optional
- `delete_on_destroy` (Boolean) Set to true to hard delete the Vercel deployment when destroying the Terraform resource. If unspecified, deployments are retained indefinitely. Note that deleted deployments are not recoverable.
- `environment` (Map of String) A map of environment variable names to values. These are specific to a Deployment, and can also be configured on the `vercel_project` resource.
+- `files` (Map of String) A map of files to be uploaded for the deployment. This should be provided by a `vercel_project_directory` or `vercel_file` data source. Required if `git_source` is not set
+- `git_source` (Attributes) A map with the Git repo information. Required if `files` is not set (see [below for nested schema](#nestedatt--git_source))
- `path_prefix` (String) If specified then the `path_prefix` will be stripped from the start of file paths as they are uploaded to Vercel. If this is omitted, then any leading `../`s will be stripped.
- `production` (Boolean) true if the deployment is a production deployment, meaning production aliases will be assigned.
- `project_settings` (Attributes) Project settings that will be applied to the deployment. (see [below for nested schema](#nestedatt--project_settings))
@@ -81,6 +82,16 @@ resource "vercel_deployment" "example" {
- `id` (String) The ID of this resource.
- `url` (String) A unique URL that is automatically generated for a deployment.
+
+### Nested Schema for `git_source`
+
+Optional:
+
+- `ref` (String) Branch or commit hash
+- `repo_id` (String) Frontend git repo ID
+- `type` (String) Type of git repo, supported values are: github
+
+
### Nested Schema for `project_settings`
diff --git a/vercel/resource_deployment.go b/vercel/resource_deployment.go
index 38d847fe..59418320 100644
--- a/vercel/resource_deployment.go
+++ b/vercel/resource_deployment.go
@@ -79,8 +79,8 @@ Once the build step has completed successfully, a new, immutable deployment will
Type: types.BoolType,
},
"files": {
- Description: "A map of files to be uploaded for the deployment. This should be provided by a `vercel_project_directory` or `vercel_file` data source.",
- Required: true,
+ Description: "A map of files to be uploaded for the deployment. This should be provided by a `vercel_project_directory` or `vercel_file` data source. Required if `git_source` is not set",
+ Optional: true,
PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()},
Type: types.MapType{
ElemType: types.StringType,
@@ -89,6 +89,34 @@ Once the build step has completed successfully, a new, immutable deployment will
mapItemsMinCount(1),
},
},
+ "git_source": {
+ Description: "A map with the Git repo information. Required if `files` is not set",
+ Optional: true,
+ PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()},
+ Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
+ "repo_id": {
+ Required: true,
+ PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()},
+ Type: types.StringType,
+ Description: "Frontend git repo ID",
+ },
+ "ref": {
+ Required: true,
+ PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()},
+ Type: types.StringType,
+ Description: "Branch or commit hash",
+ },
+ "type": {
+ Required: true,
+ PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()},
+ Type: types.StringType,
+ Description: "Type of git repo, supported values are: github",
+ Validators: []tfsdk.AttributeValidator{
+ stringOneOf("github", "gitlab", "bitbucket", "custom"),
+ },
+ },
+ }),
+ },
"project_settings": {
Description: "Project settings that will be applied to the deployment.",
Optional: true,
@@ -171,6 +199,14 @@ func (r resourceDeployment) Create(ctx context.Context, req tfsdk.CreateResource
)
return
}
+ err := plan.checkMutualyExclusiveAttributes()
+ if err != nil {
+ resp.Diagnostics.AddError(
+ "Error creating deployment",
+ "Error checking arguments: "+err.Error(),
+ )
+ return
+ }
files, filesBySha, err := plan.getFiles()
if err != nil {
@@ -192,12 +228,19 @@ func (r resourceDeployment) Create(ctx context.Context, req tfsdk.CreateResource
return
}
+ var gitSource *client.GitSource
+ if plan.GitSource != nil {
+ gs := plan.GitSource.toRequest()
+ gitSource = &gs
+ }
+
cdr := client.CreateDeploymentRequest{
Files: files,
Environment: environment,
ProjectID: plan.ProjectID.Value,
ProjectSettings: plan.ProjectSettings.toRequest(),
Target: target,
+ GitSource: gitSource,
}
out, err := r.p.client.CreateDeployment(ctx, cdr, plan.TeamID.Value)
diff --git a/vercel/resource_deployment_model.go b/vercel/resource_deployment_model.go
index 4f965c98..868093db 100644
--- a/vercel/resource_deployment_model.go
+++ b/vercel/resource_deployment_model.go
@@ -20,6 +20,13 @@ type ProjectSettings struct {
RootDirectory types.String `tfsdk:"root_directory"`
}
+// GitSource represents the Git integration source for a deployment.
+type GitSource struct {
+ RepoId types.String `tfsdk:"repo_id"`
+ Ref types.String `tfsdk:"ref"`
+ Type types.String `tfsdk:"type"`
+}
+
// Deployment represents the terraform state for a deployment resource.
type Deployment struct {
Domains types.List `tfsdk:"domains"`
@@ -33,6 +40,7 @@ type Deployment struct {
TeamID types.String `tfsdk:"team_id"`
URL types.String `tfsdk:"url"`
DeleteOnDestroy types.Bool `tfsdk:"delete_on_destroy"`
+ GitSource *GitSource `tfsdk:"git_source"`
}
// setIfNotUnknown is a helper function to set a value in a map if it is not unknown.
@@ -46,6 +54,16 @@ func setIfNotUnknown(m map[string]interface{}, v types.String, name string) {
}
}
+// toRequest takes the input of GitSource and converts them into the required
+// format for a CreateDeploymentRequest.
+func (g *GitSource) toRequest() client.GitSource {
+ return client.GitSource{
+ Ref: g.Ref.Value,
+ RepoId: g.RepoId.Value,
+ Type: g.Type.Value,
+ }
+}
+
// toRequest takes a set of ProjectSettings and converts them into the required
// format for a CreateDeploymentRequest.
func (p *ProjectSettings) toRequest() map[string]interface{} {
@@ -187,5 +205,19 @@ func convertResponseToDeployment(response client.DeploymentResponse, plan Deploy
PathPrefix: fillStringNull(plan.PathPrefix),
ProjectSettings: plan.ProjectSettings.fillNulls(),
DeleteOnDestroy: plan.DeleteOnDestroy,
+ GitSource: plan.GitSource,
+ }
+}
+
+// checkMutualyExclusiveAttributes checks whether git_source and files are not set at the same time
+func (d *Deployment) checkMutualyExclusiveAttributes() error {
+ // Error if both are nil
+ if d.Files != nil && d.GitSource != nil {
+ return fmt.Errorf("only one of \"files\" or \"git_source\" must be set, not both")
+ }
+ // Error if both are set
+ if d.Files == nil && d.GitSource == nil {
+ return fmt.Errorf("either \"files\" or \"git_source\" must be set")
}
+ return nil
}
diff --git a/vercel/resource_deployment_test.go b/vercel/resource_deployment_test.go
index 6fd3c6f6..9abd7557 100644
--- a/vercel/resource_deployment_test.go
+++ b/vercel/resource_deployment_test.go
@@ -248,6 +248,24 @@ func testAccDeployment(t *testing.T, tid string) {
})
}
+func TestAcc_DeployFromGitSource(t *testing.T) {
+ projectSuffix := acctest.RandString(16)
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ CheckDestroy: noopDestroyCheck,
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccDeployFromGitSource(projectSuffix),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ testAccDeploymentExists("vercel_deployment.test", ""),
+ resource.TestCheckResourceAttr("vercel_deployment.test", "production", "true"),
+ ),
+ },
+ },
+ })
+}
+
func testAccDeploymentConfigWithNoDeployment(projectSuffix string) string {
return fmt.Sprintf(`
resource "vercel_project" "test" {
@@ -327,3 +345,20 @@ resource "vercel_deployment" "test" {
path_prefix = "../vercel/example"
}`, projectSuffix)
}
+
+func testAccDeployFromGitSource(projectSuffix string) string {
+ return fmt.Sprintf(`
+resource "vercel_project" "test" {
+ name = "test-acc-deployment-%s"
+}
+
+resource "vercel_deployment" "test" {
+ project_id = vercel_project.test.id
+ git_source = {
+ ref = "main"
+ repo_id = "452772221"
+ type = "github"
+ }
+ path_prefix = "vercel/example"
+}`, projectSuffix)
+}