diff --git a/client/project_create.go b/client/project_create.go index ed86914f..d48aecaa 100644 --- a/client/project_create.go +++ b/client/project_create.go @@ -29,16 +29,18 @@ type EnvironmentVariable struct { // CreateProjectRequest defines the information necessary to create a project. type CreateProjectRequest struct { - Name string `json:"name"` - BuildCommand *string `json:"buildCommand"` - DevCommand *string `json:"devCommand"` - EnvironmentVariables []EnvironmentVariable `json:"environmentVariables"` - Framework *string `json:"framework"` - GitRepository *GitRepository `json:"gitRepository,omitempty"` - InstallCommand *string `json:"installCommand"` - OutputDirectory *string `json:"outputDirectory"` - PublicSource *bool `json:"publicSource"` - RootDirectory *string `json:"rootDirectory"` + BuildCommand *string `json:"buildCommand"` + CommandForIgnoringBuildStep *string `json:"commandForIgnoringBuildStep,omitempty"` + DevCommand *string `json:"devCommand"` + EnvironmentVariables []EnvironmentVariable `json:"environmentVariables"` + Framework *string `json:"framework"` + GitRepository *GitRepository `json:"gitRepository,omitempty"` + InstallCommand *string `json:"installCommand"` + Name string `json:"name"` + OutputDirectory *string `json:"outputDirectory"` + PublicSource *bool `json:"publicSource"` + RootDirectory *string `json:"rootDirectory"` + ServerlessFunctionRegion *string `json:"serverlessFunctionRegion,omitempty"` } // CreateProject will create a project within Vercel. diff --git a/client/project_get.go b/client/project_get.go index 6ac51fd6..5e08c7f1 100644 --- a/client/project_get.go +++ b/client/project_get.go @@ -40,15 +40,16 @@ func (r *ProjectResponse) Repository() *Repository { return nil } -// ProjectResponse defines the information vercel returns about a project. +// ProjectResponse defines the information Vercel returns about a project. type ProjectResponse struct { - BuildCommand *string `json:"buildCommand"` - DevCommand *string `json:"devCommand"` - EnvironmentVariables []EnvironmentVariable `json:"env"` - Framework *string `json:"framework"` - ID string `json:"id"` - InstallCommand *string `json:"installCommand"` - Link *struct { + BuildCommand *string `json:"buildCommand"` + CommandForIgnoringBuildStep *string `json:"commandForIgnoringBuildStep"` + DevCommand *string `json:"devCommand"` + EnvironmentVariables []EnvironmentVariable `json:"env"` + Framework *string `json:"framework"` + ID string `json:"id"` + InstallCommand *string `json:"installCommand"` + Link *struct { Type string `json:"type"` // github Org string `json:"org"` @@ -61,13 +62,14 @@ type ProjectResponse struct { ProjectName string `json:"projectName"` ProjectID int64 `json:"projectId,string"` } `json:"link"` - Name string `json:"name"` - OutputDirectory *string `json:"outputDirectory"` - PublicSource *bool `json:"publicSource"` - RootDirectory *string `json:"rootDirectory"` + Name string `json:"name"` + OutputDirectory *string `json:"outputDirectory"` + PublicSource *bool `json:"publicSource"` + RootDirectory *string `json:"rootDirectory"` + ServerlessFunctionRegion *string `json:"serverlessFunctionRegion"` } -// GetProject retrieves information about an existing project from vercel. +// GetProject retrieves information about an existing project from Vercel. func (c *Client) GetProject(ctx context.Context, projectID, teamID string) (r ProjectResponse, err error) { url := fmt.Sprintf("%s/v8/projects/%s", c.baseURL, projectID) if teamID != "" { diff --git a/client/project_update.go b/client/project_update.go index 6db6e523..5f8c1718 100644 --- a/client/project_update.go +++ b/client/project_update.go @@ -16,17 +16,19 @@ import ( // - setting the field to an empty value (e.g. '') will remove the setting for that field. // - omitting the value entirely from the request will _not_ update the field. type UpdateProjectRequest struct { - Name *string `json:"name,omitempty"` - BuildCommand *string `json:"buildCommand"` - DevCommand *string `json:"devCommand"` - Framework *string `json:"framework"` - InstallCommand *string `json:"installCommand"` - OutputDirectory *string `json:"outputDirectory"` - PublicSource *bool `json:"publicSource"` - RootDirectory *string `json:"rootDirectory"` + BuildCommand *string `json:"buildCommand"` + CommandForIgnoringBuildStep *string `json:"commandForIgnoringBuildStep"` + DevCommand *string `json:"devCommand"` + Framework *string `json:"framework"` + InstallCommand *string `json:"installCommand"` + Name *string `json:"name,omitempty"` + OutputDirectory *string `json:"outputDirectory"` + PublicSource *bool `json:"publicSource"` + RootDirectory *string `json:"rootDirectory"` + ServerlessFunctionRegion *string `json:"serverlessFunctionRegion"` } -// UpdateProject updates an existing projects configuration within vercel. +// UpdateProject updates an existing projects configuration within Vercel. func (c *Client) UpdateProject(ctx context.Context, projectID, teamID string, request UpdateProjectRequest) (r ProjectResponse, err error) { url := fmt.Sprintf("%s/v8/projects/%s", c.baseURL, projectID) if teamID != "" { diff --git a/vercel/data_source_project.go b/vercel/data_source_project.go index 38e535da..d789c7cc 100644 --- a/vercel/data_source_project.go +++ b/vercel/data_source_project.go @@ -52,6 +52,16 @@ For more detailed information, please see the [Vercel documentation](https://ver Type: types.StringType, Description: "The dev command for this project. If omitted, this value will be automatically detected.", }, + "ignore_command": { + Computed: true, + Type: types.StringType, + Description: "When a commit is pushed to the Git repository that is connected with your Project, its SHA will determine if a new Build has to be issued. If the SHA was deployed before, no new Build will be issued. You can customize this behavior with a command that exits with code 1 (new Build needed) or code 0.", + }, + "serverless_function_region": { + Computed: true, + Type: types.StringType, + Description: "The region on Vercel's network to which your Serverless Functions are deployed. It should be close to any data source your Serverless Function might depend on. A new Deployment is required for your changes to take effect. Please see [Vercel's documentation](https://vercel.com/docs/concepts/edge-network/regions) for a full list of regions.", + }, "environment": { Description: "A list of environment variables that should be configured for the project.", Computed: true, @@ -91,9 +101,8 @@ For more detailed information, please see the [Vercel documentation](https://ver Description: "The framework that is being used for this project. If omitted, no framework is selected.", }, "git_repository": { - Description: "The Git Repository that will be connected to the project. When this is defined, any pushes to the specified connected Git Repository will be automatically deployed. This requires the corresponding Vercel for [Github](https://vercel.com/docs/concepts/git/vercel-for-github), [Gitlab](https://vercel.com/docs/concepts/git/vercel-for-gitlab) or [Bitbucket](https://vercel.com/docs/concepts/git/vercel-for-bitbucket) plugins to be installed.", - Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()}, + Description: "The Git Repository that will be connected to the project. When this is defined, any pushes to the specified connected Git Repository will be automatically deployed. This requires the corresponding Vercel for [Github](https://vercel.com/docs/concepts/git/vercel-for-github), [Gitlab](https://vercel.com/docs/concepts/git/vercel-for-gitlab) or [Bitbucket](https://vercel.com/docs/concepts/git/vercel-for-bitbucket) plugins to be installed.", + Computed: true, Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{ "type": { Description: "The git provider of the repository. Must be either `github`, `gitlab`, or `bitbucket`.", @@ -102,13 +111,11 @@ For more detailed information, please see the [Vercel documentation](https://ver Validators: []tfsdk.AttributeValidator{ stringOneOf("github", "gitlab", "bitbucket"), }, - PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()}, }, "repo": { - Description: "The name of the git repository. For example: `vercel/next.js`.", - Type: types.StringType, - Computed: true, - PlanModifiers: tfsdk.AttributePlanModifiers{tfsdk.RequiresReplace()}, + Description: "The name of the git repository. For example: `vercel/next.js`.", + Type: types.StringType, + Computed: true, }, }), }, diff --git a/vercel/resource_project.go b/vercel/resource_project.go index d2ef4428..ce39994f 100644 --- a/vercel/resource_project.go +++ b/vercel/resource_project.go @@ -55,6 +55,37 @@ For more detailed information, please see the [Vercel documentation](https://ver Type: types.StringType, Description: "The dev command for this project. If omitted, this value will be automatically detected.", }, + "ignore_command": { + Optional: true, + Type: types.StringType, + Description: "When a commit is pushed to the Git repository that is connected with your Project, its SHA will determine if a new Build has to be issued. If the SHA was deployed before, no new Build will be issued. You can customize this behavior with a command that exits with code 1 (new Build needed) or code 0.", + }, + "serverless_function_region": { + Optional: true, + Computed: true, + Type: types.StringType, + Description: "The region on Vercel's network to which your Serverless Functions are deployed. It should be close to any data source your Serverless Function might depend on. A new Deployment is required for your changes to take effect. Please see [Vercel's documentation](https://vercel.com/docs/concepts/edge-network/regions) for a full list of regions.", + Validators: []tfsdk.AttributeValidator{ + stringOneOf( + "arn1", + "bom1", + "cdg1", + "cle1", + "dub1", + "fra1", + "gru1", + "hkg1", + "hnd1", + "iad1", + "icn1", + "lhr1", + "pdx1", + "sfo1", + "sin1", + "syd1", + ), + }, + }, "environment": { Description: "A set of environment variables that should be configured for the project.", Optional: true, diff --git a/vercel/resource_project_model.go b/vercel/resource_project_model.go index 495fbf20..f135a190 100644 --- a/vercel/resource_project_model.go +++ b/vercel/resource_project_model.go @@ -7,18 +7,20 @@ import ( // Project reflects the state terraform stores internally for a project. type Project struct { - BuildCommand types.String `tfsdk:"build_command"` - DevCommand types.String `tfsdk:"dev_command"` - Environment []EnvironmentItem `tfsdk:"environment"` - Framework types.String `tfsdk:"framework"` - GitRepository *GitRepository `tfsdk:"git_repository"` - ID types.String `tfsdk:"id"` - InstallCommand types.String `tfsdk:"install_command"` - Name types.String `tfsdk:"name"` - OutputDirectory types.String `tfsdk:"output_directory"` - PublicSource types.Bool `tfsdk:"public_source"` - RootDirectory types.String `tfsdk:"root_directory"` - TeamID types.String `tfsdk:"team_id"` + BuildCommand types.String `tfsdk:"build_command"` + DevCommand types.String `tfsdk:"dev_command"` + Environment []EnvironmentItem `tfsdk:"environment"` + Framework types.String `tfsdk:"framework"` + GitRepository *GitRepository `tfsdk:"git_repository"` + ID types.String `tfsdk:"id"` + IgnoreCommand types.String `tfsdk:"ignore_command"` + InstallCommand types.String `tfsdk:"install_command"` + Name types.String `tfsdk:"name"` + OutputDirectory types.String `tfsdk:"output_directory"` + PublicSource types.Bool `tfsdk:"public_source"` + RootDirectory types.String `tfsdk:"root_directory"` + ServerlessFunctionRegion types.String `tfsdk:"serverless_function_region"` + TeamID types.String `tfsdk:"team_id"` } func parseEnvironment(vars []EnvironmentItem) []client.EnvironmentVariable { @@ -43,16 +45,18 @@ func parseEnvironment(vars []EnvironmentItem) []client.EnvironmentVariable { func (p *Project) toCreateProjectRequest() client.CreateProjectRequest { return client.CreateProjectRequest{ - Name: p.Name.Value, - BuildCommand: toStrPointer(p.BuildCommand), - DevCommand: toStrPointer(p.DevCommand), - EnvironmentVariables: parseEnvironment(p.Environment), - Framework: toStrPointer(p.Framework), - GitRepository: p.GitRepository.toCreateProjectRequest(), - InstallCommand: toStrPointer(p.InstallCommand), - OutputDirectory: toStrPointer(p.OutputDirectory), - PublicSource: toBoolPointer(p.PublicSource), - RootDirectory: toStrPointer(p.RootDirectory), + BuildCommand: toStrPointer(p.BuildCommand), + CommandForIgnoringBuildStep: toStrPointer(p.IgnoreCommand), + DevCommand: toStrPointer(p.DevCommand), + EnvironmentVariables: parseEnvironment(p.Environment), + Framework: toStrPointer(p.Framework), + GitRepository: p.GitRepository.toCreateProjectRequest(), + InstallCommand: toStrPointer(p.InstallCommand), + Name: p.Name.Value, + OutputDirectory: toStrPointer(p.OutputDirectory), + PublicSource: toBoolPointer(p.PublicSource), + RootDirectory: toStrPointer(p.RootDirectory), + ServerlessFunctionRegion: toStrPointer(p.ServerlessFunctionRegion), } } @@ -62,14 +66,16 @@ func (p *Project) toUpdateProjectRequest(oldName string) client.UpdateProjectReq name = &p.Name.Value } return client.UpdateProjectRequest{ - Name: name, - BuildCommand: toStrPointer(p.BuildCommand), - DevCommand: toStrPointer(p.DevCommand), - Framework: toStrPointer(p.Framework), - InstallCommand: toStrPointer(p.InstallCommand), - OutputDirectory: toStrPointer(p.OutputDirectory), - RootDirectory: toStrPointer(p.RootDirectory), - PublicSource: toBoolPointer(p.PublicSource), + BuildCommand: toStrPointer(p.BuildCommand), + CommandForIgnoringBuildStep: toStrPointer(p.IgnoreCommand), + DevCommand: toStrPointer(p.DevCommand), + Framework: toStrPointer(p.Framework), + InstallCommand: toStrPointer(p.InstallCommand), + Name: name, + OutputDirectory: toStrPointer(p.OutputDirectory), + PublicSource: toBoolPointer(p.PublicSource), + RootDirectory: toStrPointer(p.RootDirectory), + ServerlessFunctionRegion: toStrPointer(p.ServerlessFunctionRegion), } } @@ -141,17 +147,19 @@ func convertResponseToProject(response client.ProjectResponse, tid types.String) } return Project{ - TeamID: teamID, - ID: types.String{Value: response.ID}, - Name: types.String{Value: response.Name}, - BuildCommand: fromStringPointer(response.BuildCommand), - DevCommand: fromStringPointer(response.DevCommand), - Framework: fromStringPointer(response.Framework), - InstallCommand: fromStringPointer(response.InstallCommand), - OutputDirectory: fromStringPointer(response.OutputDirectory), - PublicSource: fromBoolPointer(response.PublicSource), - RootDirectory: fromStringPointer(response.RootDirectory), - GitRepository: gr, - Environment: env, + BuildCommand: fromStringPointer(response.BuildCommand), + DevCommand: fromStringPointer(response.DevCommand), + Environment: env, + Framework: fromStringPointer(response.Framework), + GitRepository: gr, + ID: types.String{Value: response.ID}, + IgnoreCommand: fromStringPointer(response.CommandForIgnoringBuildStep), + InstallCommand: fromStringPointer(response.InstallCommand), + Name: types.String{Value: response.Name}, + OutputDirectory: fromStringPointer(response.OutputDirectory), + PublicSource: fromBoolPointer(response.PublicSource), + RootDirectory: fromStringPointer(response.RootDirectory), + ServerlessFunctionRegion: fromStringPointer(response.ServerlessFunctionRegion), + TeamID: teamID, } } diff --git a/vercel/resource_project_test.go b/vercel/resource_project_test.go index 60815fad..b0e1bff7 100644 --- a/vercel/resource_project_test.go +++ b/vercel/resource_project_test.go @@ -47,6 +47,8 @@ func TestAcc_Project(t *testing.T) { resource.TestCheckResourceAttr("vercel_project.test", "output_directory", ".output"), resource.TestCheckResourceAttr("vercel_project.test", "public_source", "true"), resource.TestCheckResourceAttr("vercel_project.test", "root_directory", "ui/src"), + resource.TestCheckResourceAttr("vercel_project.test", "ignore_command", "echo 'wat'"), + resource.TestCheckResourceAttr("vercel_project.test", "serverless_function_region", "syd1"), resource.TestCheckTypeSetElemNestedAttrs("vercel_project.test", "environment.*", map[string]string{ "key": "foo", "value": "bar", @@ -296,6 +298,8 @@ resource "vercel_project" "test" { %s build_command = "npm run build" dev_command = "npm run serve" + ignore_command = "echo 'wat'" + serverless_function_region = "syd1" framework = "nextjs" install_command = "npm install" output_directory = ".output"