这是indexloc提供的服务,不要输入任何密码
Skip to content

Add Deployment data source #172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions docs/data-sources/deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "vercel_deployment Data Source - terraform-provider-vercel"
subcategory: ""
description: |-
Provides information about an existing Deployment.
A Deployment is the result of building your Project and making it available through a live URL.
---

# vercel_deployment (Data Source)

Provides information about an existing Deployment.

A Deployment is the result of building your Project and making it available through a live URL.

## Example Usage

```terraform
data "vercel_deployment" "example" {
id = "https://my-vercel-project.vercel.app"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `id` (String) The ID or URL of the Deployment to read.

### Optional

- `team_id` (String) The Team ID to the Deployment belong to. Required when reading a team resource if a default team has not been set in the provider.

### Read-Only

- `domains` (List of String) A list of all the domains (default domains, staging domains and production domains) that were assigned upon deployment creation.
- `production` (Boolean) true if the deployment is a production deployment, meaning production aliases will be assigned.
- `project_id` (String) The project ID to add the deployment to.
- `ref` (String) The branch or commit hash that has been deployed. Note this will only work if the project is configured to use a Git repository.
- `url` (String) A unique URL that is automatically generated for a deployment.
3 changes: 3 additions & 0 deletions examples/data-sources/vercel_deployment/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "vercel_deployment" "example" {
id = "https://my-vercel-project.vercel.app"
}
164 changes: 164 additions & 0 deletions vercel/data_source_deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package vercel

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/vercel/terraform-provider-vercel/client"
)

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &deploymentDataSource{}
_ datasource.DataSourceWithConfigure = &deploymentDataSource{}
)

func newDeploymentDataSource() datasource.DataSource {
return &deploymentDataSource{}
}

type deploymentDataSource struct {
client *client.Client
}

func (d *deploymentDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_deployment"
}

func (d *deploymentDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*client.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}

d.client = client
}

// Schema returns the schema information for an deployment data source
func (r *deploymentDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: `
Provides information about an existing Deployment.

A Deployment is the result of building your Project and making it available through a live URL.
`,
Attributes: map[string]schema.Attribute{
"team_id": schema.StringAttribute{
Description: "The Team ID to the Deployment belong to. Required when reading a team resource if a default team has not been set in the provider.",
Optional: true,
Computed: true,
},
"id": schema.StringAttribute{
Required: true,
Description: "The ID or URL of the Deployment to read.",
},
"domains": schema.ListAttribute{
Description: "A list of all the domains (default domains, staging domains and production domains) that were assigned upon deployment creation.",
Computed: true,
ElementType: types.StringType,
},
"project_id": schema.StringAttribute{
Description: "The project ID to add the deployment to.",
Computed: true,
},
"url": schema.StringAttribute{
Description: "A unique URL that is automatically generated for a deployment.",
Computed: true,
},
"production": schema.BoolAttribute{
Description: "true if the deployment is a production deployment, meaning production aliases will be assigned.",
Computed: true,
},
"ref": schema.StringAttribute{
Description: "The branch or commit hash that has been deployed. Note this will only work if the project is configured to use a Git repository.",
Computed: true,
},
},
}
}

type DeploymentDataSource struct {
Domains types.List `tfsdk:"domains"`
ID types.String `tfsdk:"id"`
Production types.Bool `tfsdk:"production"`
ProjectID types.String `tfsdk:"project_id"`
TeamID types.String `tfsdk:"team_id"`
URL types.String `tfsdk:"url"`
Ref types.String `tfsdk:"ref"`
}

func convertResponseToDeploymentDataSource(in client.DeploymentResponse) DeploymentDataSource {
ref := types.StringNull()
if in.GitSource.Ref != "" {
ref = types.StringValue(in.GitSource.Ref)
}

var domains []attr.Value
for _, a := range in.Aliases {
domains = append(domains, types.StringValue(a))
}
return DeploymentDataSource{
Domains: types.ListValueMust(types.StringType, domains),
Production: types.BoolValue(in.Target != nil && *in.Target == "production"),
TeamID: toTeamID(in.TeamID),
ProjectID: types.StringValue(in.ProjectID),
ID: types.StringValue(in.ID),
URL: types.StringValue(in.URL),
Ref: ref,
}
}

// Read will read the deployment information by requesting it from the Vercel API, and will update terraform
// with this information.
// It is called by the provider whenever data source values should be read to update state.
func (d *deploymentDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config DeploymentDataSource
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

out, err := d.client.GetDeployment(ctx, config.ID.ValueString(), config.TeamID.ValueString())
if client.NotFound(err) {
resp.State.RemoveResource(ctx)
return
}
if err != nil {
resp.Diagnostics.AddError(
"Error reading deployment",
fmt.Sprintf("Could not get deployment %s %s, unexpected error: %s",
config.TeamID.ValueString(),
config.ID.ValueString(),
err,
),
)
return
}

result := convertResponseToDeploymentDataSource(out)
tflog.Info(ctx, "read deployment", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
})

diags = resp.State.Set(ctx, result)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
72 changes: 72 additions & 0 deletions vercel/data_source_deployment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package vercel_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAcc_DeploymentDataSource(t *testing.T) {
name := acctest.RandString(16)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccDeploymentDataSourceConfig(name, teamIDConfig()),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_id", "id"),
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_id", "project_id"),
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_id", "url"),
resource.TestCheckResourceAttr("data.vercel_deployment.by_id", "production", "true"),
resource.TestCheckResourceAttr("data.vercel_deployment.by_id", "domains.#", "2"),

resource.TestCheckResourceAttrSet("data.vercel_deployment.by_url", "id"),
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_url", "project_id"),
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_url", "url"),
resource.TestCheckResourceAttr("data.vercel_deployment.by_url", "production", "true"),
resource.TestCheckResourceAttr("data.vercel_deployment.by_url", "domains.#", "2"),
),
},
},
})
}

func testAccDeploymentDataSourceConfig(name, teamID string) string {
return fmt.Sprintf(`
data "vercel_deployment" "by_id" {
id = vercel_deployment.test.id
}

data "vercel_deployment" "by_url" {
id = vercel_deployment.test.url
}

resource "vercel_project" "test" {
name = "test-acc-deployment-%[1]s"
%[2]s
environment = [
{
key = "bar"
value = "baz"
target = ["preview"]
}
]
}

data "vercel_prebuilt_project" "test" {
path = "examples/two"
}

resource "vercel_deployment" "test" {
project_id = vercel_project.test.id
%[2]s

production = true
files = data.vercel_prebuilt_project.test.output
path_prefix = data.vercel_prebuilt_project.test.path
}
`, name, teamID)
}
1 change: 1 addition & 0 deletions vercel/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (p *vercelProvider) Resources(_ context.Context) []func() resource.Resource
func (p *vercelProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
newAliasDataSource,
newDeploymentDataSource,
newEdgeConfigDataSource,
newEdgeConfigSchemaDataSource,
newEdgeConfigTokenDataSource,
Expand Down