Skip to content

Commit 96b2bde

Browse files
authored
Add Deployment data source (#172)
1 parent d80d489 commit 96b2bde

File tree

5 files changed

+281
-0
lines changed

5 files changed

+281
-0
lines changed

docs/data-sources/deployment.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "vercel_deployment Data Source - terraform-provider-vercel"
4+
subcategory: ""
5+
description: |-
6+
Provides information about an existing Deployment.
7+
A Deployment is the result of building your Project and making it available through a live URL.
8+
---
9+
10+
# vercel_deployment (Data Source)
11+
12+
Provides information about an existing Deployment.
13+
14+
A Deployment is the result of building your Project and making it available through a live URL.
15+
16+
## Example Usage
17+
18+
```terraform
19+
data "vercel_deployment" "example" {
20+
id = "https://my-vercel-project.vercel.app"
21+
}
22+
```
23+
24+
<!-- schema generated by tfplugindocs -->
25+
## Schema
26+
27+
### Required
28+
29+
- `id` (String) The ID or URL of the Deployment to read.
30+
31+
### Optional
32+
33+
- `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.
34+
35+
### Read-Only
36+
37+
- `domains` (List of String) A list of all the domains (default domains, staging domains and production domains) that were assigned upon deployment creation.
38+
- `production` (Boolean) true if the deployment is a production deployment, meaning production aliases will be assigned.
39+
- `project_id` (String) The project ID to add the deployment to.
40+
- `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.
41+
- `url` (String) A unique URL that is automatically generated for a deployment.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
data "vercel_deployment" "example" {
2+
id = "https://my-vercel-project.vercel.app"
3+
}

vercel/data_source_deployment.go

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package vercel
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/attr"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource"
9+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
10+
"github.com/hashicorp/terraform-plugin-framework/types"
11+
"github.com/hashicorp/terraform-plugin-log/tflog"
12+
"github.com/vercel/terraform-provider-vercel/client"
13+
)
14+
15+
// Ensure the implementation satisfies the expected interfaces.
16+
var (
17+
_ datasource.DataSource = &deploymentDataSource{}
18+
_ datasource.DataSourceWithConfigure = &deploymentDataSource{}
19+
)
20+
21+
func newDeploymentDataSource() datasource.DataSource {
22+
return &deploymentDataSource{}
23+
}
24+
25+
type deploymentDataSource struct {
26+
client *client.Client
27+
}
28+
29+
func (d *deploymentDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
30+
resp.TypeName = req.ProviderTypeName + "_deployment"
31+
}
32+
33+
func (d *deploymentDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
34+
// Prevent panic if the provider has not been configured.
35+
if req.ProviderData == nil {
36+
return
37+
}
38+
39+
client, ok := req.ProviderData.(*client.Client)
40+
if !ok {
41+
resp.Diagnostics.AddError(
42+
"Unexpected Data Source Configure Type",
43+
fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
44+
)
45+
return
46+
}
47+
48+
d.client = client
49+
}
50+
51+
// Schema returns the schema information for an deployment data source
52+
func (r *deploymentDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
53+
resp.Schema = schema.Schema{
54+
Description: `
55+
Provides information about an existing Deployment.
56+
57+
A Deployment is the result of building your Project and making it available through a live URL.
58+
`,
59+
Attributes: map[string]schema.Attribute{
60+
"team_id": schema.StringAttribute{
61+
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.",
62+
Optional: true,
63+
Computed: true,
64+
},
65+
"id": schema.StringAttribute{
66+
Required: true,
67+
Description: "The ID or URL of the Deployment to read.",
68+
},
69+
"domains": schema.ListAttribute{
70+
Description: "A list of all the domains (default domains, staging domains and production domains) that were assigned upon deployment creation.",
71+
Computed: true,
72+
ElementType: types.StringType,
73+
},
74+
"project_id": schema.StringAttribute{
75+
Description: "The project ID to add the deployment to.",
76+
Computed: true,
77+
},
78+
"url": schema.StringAttribute{
79+
Description: "A unique URL that is automatically generated for a deployment.",
80+
Computed: true,
81+
},
82+
"production": schema.BoolAttribute{
83+
Description: "true if the deployment is a production deployment, meaning production aliases will be assigned.",
84+
Computed: true,
85+
},
86+
"ref": schema.StringAttribute{
87+
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.",
88+
Computed: true,
89+
},
90+
},
91+
}
92+
}
93+
94+
type DeploymentDataSource struct {
95+
Domains types.List `tfsdk:"domains"`
96+
ID types.String `tfsdk:"id"`
97+
Production types.Bool `tfsdk:"production"`
98+
ProjectID types.String `tfsdk:"project_id"`
99+
TeamID types.String `tfsdk:"team_id"`
100+
URL types.String `tfsdk:"url"`
101+
Ref types.String `tfsdk:"ref"`
102+
}
103+
104+
func convertResponseToDeploymentDataSource(in client.DeploymentResponse) DeploymentDataSource {
105+
ref := types.StringNull()
106+
if in.GitSource.Ref != "" {
107+
ref = types.StringValue(in.GitSource.Ref)
108+
}
109+
110+
var domains []attr.Value
111+
for _, a := range in.Aliases {
112+
domains = append(domains, types.StringValue(a))
113+
}
114+
return DeploymentDataSource{
115+
Domains: types.ListValueMust(types.StringType, domains),
116+
Production: types.BoolValue(in.Target != nil && *in.Target == "production"),
117+
TeamID: toTeamID(in.TeamID),
118+
ProjectID: types.StringValue(in.ProjectID),
119+
ID: types.StringValue(in.ID),
120+
URL: types.StringValue(in.URL),
121+
Ref: ref,
122+
}
123+
}
124+
125+
// Read will read the deployment information by requesting it from the Vercel API, and will update terraform
126+
// with this information.
127+
// It is called by the provider whenever data source values should be read to update state.
128+
func (d *deploymentDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
129+
var config DeploymentDataSource
130+
diags := req.Config.Get(ctx, &config)
131+
resp.Diagnostics.Append(diags...)
132+
if resp.Diagnostics.HasError() {
133+
return
134+
}
135+
136+
out, err := d.client.GetDeployment(ctx, config.ID.ValueString(), config.TeamID.ValueString())
137+
if client.NotFound(err) {
138+
resp.State.RemoveResource(ctx)
139+
return
140+
}
141+
if err != nil {
142+
resp.Diagnostics.AddError(
143+
"Error reading deployment",
144+
fmt.Sprintf("Could not get deployment %s %s, unexpected error: %s",
145+
config.TeamID.ValueString(),
146+
config.ID.ValueString(),
147+
err,
148+
),
149+
)
150+
return
151+
}
152+
153+
result := convertResponseToDeploymentDataSource(out)
154+
tflog.Info(ctx, "read deployment", map[string]interface{}{
155+
"team_id": result.TeamID.ValueString(),
156+
"project_id": result.ID.ValueString(),
157+
})
158+
159+
diags = resp.State.Set(ctx, result)
160+
resp.Diagnostics.Append(diags...)
161+
if resp.Diagnostics.HasError() {
162+
return
163+
}
164+
}

vercel/data_source_deployment_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package vercel_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
8+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
9+
)
10+
11+
func TestAcc_DeploymentDataSource(t *testing.T) {
12+
name := acctest.RandString(16)
13+
resource.Test(t, resource.TestCase{
14+
PreCheck: func() { testAccPreCheck(t) },
15+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
16+
Steps: []resource.TestStep{
17+
{
18+
Config: testAccDeploymentDataSourceConfig(name, teamIDConfig()),
19+
Check: resource.ComposeAggregateTestCheckFunc(
20+
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_id", "id"),
21+
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_id", "project_id"),
22+
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_id", "url"),
23+
resource.TestCheckResourceAttr("data.vercel_deployment.by_id", "production", "true"),
24+
resource.TestCheckResourceAttr("data.vercel_deployment.by_id", "domains.#", "2"),
25+
26+
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_url", "id"),
27+
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_url", "project_id"),
28+
resource.TestCheckResourceAttrSet("data.vercel_deployment.by_url", "url"),
29+
resource.TestCheckResourceAttr("data.vercel_deployment.by_url", "production", "true"),
30+
resource.TestCheckResourceAttr("data.vercel_deployment.by_url", "domains.#", "2"),
31+
),
32+
},
33+
},
34+
})
35+
}
36+
37+
func testAccDeploymentDataSourceConfig(name, teamID string) string {
38+
return fmt.Sprintf(`
39+
data "vercel_deployment" "by_id" {
40+
id = vercel_deployment.test.id
41+
}
42+
43+
data "vercel_deployment" "by_url" {
44+
id = vercel_deployment.test.url
45+
}
46+
47+
resource "vercel_project" "test" {
48+
name = "test-acc-deployment-%[1]s"
49+
%[2]s
50+
environment = [
51+
{
52+
key = "bar"
53+
value = "baz"
54+
target = ["preview"]
55+
}
56+
]
57+
}
58+
59+
data "vercel_prebuilt_project" "test" {
60+
path = "examples/two"
61+
}
62+
63+
resource "vercel_deployment" "test" {
64+
project_id = vercel_project.test.id
65+
%[2]s
66+
67+
production = true
68+
files = data.vercel_prebuilt_project.test.output
69+
path_prefix = data.vercel_prebuilt_project.test.path
70+
}
71+
`, name, teamID)
72+
}

vercel/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (p *vercelProvider) Resources(_ context.Context) []func() resource.Resource
6868
func (p *vercelProvider) DataSources(_ context.Context) []func() datasource.DataSource {
6969
return []func() datasource.DataSource{
7070
newAliasDataSource,
71+
newDeploymentDataSource,
7172
newEdgeConfigDataSource,
7273
newEdgeConfigSchemaDataSource,
7374
newEdgeConfigTokenDataSource,

0 commit comments

Comments
 (0)