From 2376f439f35480781c02aeb2832e39dd65f4d0dc Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Thu, 28 Aug 2025 14:50:12 -0400 Subject: [PATCH 01/11] Stacks ga deprecated --- stack.go | 4 +- stack_deployments.go | 38 ---- stack_diagnostic.go | 48 ----- stack_plan.go | 345 ------------------------------- stack_plan_integration_test.go | 68 ------ stack_plan_operation.go | 88 -------- stack_source.go | 103 --------- stack_source_integration_test.go | 128 ------------ tfe.go | 8 - 9 files changed, 2 insertions(+), 828 deletions(-) delete mode 100644 stack_deployments.go delete mode 100644 stack_diagnostic.go delete mode 100644 stack_plan.go delete mode 100644 stack_plan_integration_test.go delete mode 100644 stack_plan_operation.go delete mode 100644 stack_source.go delete mode 100644 stack_source_integration_test.go diff --git a/stack.go b/stack.go index f94e2d1cd..0257b7b45 100644 --- a/stack.go +++ b/stack.go @@ -304,7 +304,7 @@ func (s stacks) Update(ctx context.Context, stackID string, options StackUpdateO // Delete deletes a stack. func (s stacks) Delete(ctx context.Context, stackID string) error { - req, err := s.client.NewRequest("POST", fmt.Sprintf("stacks/%s/delete", url.PathEscape(stackID)), nil) + req, err := s.client.NewRequest("DELETE", fmt.Sprintf("stacks/%s", url.PathEscape(stackID)), nil) if err != nil { return err } @@ -314,7 +314,7 @@ func (s stacks) Delete(ctx context.Context, stackID string) error { // ForceDelete deletes a stack that still has deployments. func (s stacks) ForceDelete(ctx context.Context, stackID string) error { - req, err := s.client.NewRequest("POST", fmt.Sprintf("stacks/%s/force-delete", url.PathEscape(stackID)), nil) + req, err := s.client.NewRequest("DELETE", fmt.Sprintf("stacks/%s?force=true", url.PathEscape(stackID)), nil) if err != nil { return err } diff --git a/stack_deployments.go b/stack_deployments.go deleted file mode 100644 index eb631cf02..000000000 --- a/stack_deployments.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tfe - -import ( - "context" - "fmt" - "net/url" -) - -// StackDeployments describes all the stacks deployments-related methods that the -// HCP Terraform API supports. -// NOTE WELL: This is a beta feature and is subject to change until noted otherwise in the -// release notes. -type StackDeployments interface { - // Read returns a stack deployment by its name. - Read(ctx context.Context, stackID, deployment string) (*StackDeployment, error) -} - -type stackDeployments struct { - client *Client -} - -func (s stackDeployments) Read(ctx context.Context, stackID, deploymentName string) (*StackDeployment, error) { - req, err := s.client.NewRequest("GET", fmt.Sprintf("stacks/%s/stack-deployments/%s", url.PathEscape(stackID), url.PathEscape(deploymentName)), nil) - if err != nil { - return nil, err - } - - deployment := &StackDeployment{} - err = req.Do(ctx, deployment) - if err != nil { - return nil, err - } - - return deployment, nil -} diff --git a/stack_diagnostic.go b/stack_diagnostic.go deleted file mode 100644 index 223c4358f..000000000 --- a/stack_diagnostic.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tfe - -// StackDiagnostic represents any sourcebundle.Diagnostic value. The simplest form has -// just a severity, single line summary, and optional detail. If there is more -// information about the source of the diagnostic, this is represented in the -// range field. -type StackDiagnostic struct { - Severity string `jsonapi:"attr,severity"` - Summary string `jsonapi:"attr,summary"` - Detail string `jsonapi:"attr,detail"` - Range *DiagnosticRange `jsonapi:"attr,range"` -} - -// DiagnosticPos represents a position in the source code. -type DiagnosticPos struct { - // Line is a one-based count for the line in the indicated file. - Line int `jsonapi:"attr,line"` - - // Column is a one-based count of Unicode characters from the start of the line. - Column int `jsonapi:"attr,column"` - - // Byte is a zero-based offset into the indicated file. - Byte int `jsonapi:"attr,byte"` -} - -// DiagnosticRange represents the filename and position of the diagnostic -// subject. This defines the range of the source to be highlighted in the -// output. Note that the snippet may include additional surrounding source code -// if the diagnostic has a context range. -// -// The stacks-specific source field represents the full source bundle address -// of the file, while the filename field is the sub path relative to its -// enclosing package. This represents an attempt to be somewhat backwards -// compatible with the existing Terraform JSON diagnostic format, where -// filename is root module relative. -// -// The Start position is inclusive, and the End position is exclusive. Exact -// positions are intended for highlighting for human interpretation only and -// are subject to change. -type DiagnosticRange struct { - Filename string `jsonapi:"attr,filename"` - Source string `jsonapi:"attr,source"` - Start DiagnosticPos `jsonapi:"attr,start"` - End DiagnosticPos `jsonapi:"attr,end"` -} diff --git a/stack_plan.go b/stack_plan.go deleted file mode 100644 index 8edef8770..000000000 --- a/stack_plan.go +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tfe - -import ( - "context" - "encoding/json" - "fmt" - "net/url" - "time" -) - -// StackPlans describes all the stacks plans-related methods that the HCP Terraform API supports. -// NOTE WELL: This is a beta feature and is subject to change until noted otherwise in the -// release notes. -type StackPlans interface { - // Read returns a stack plan by its ID. - Read(ctx context.Context, stackPlanID string) (*StackPlan, error) - - // ListByConfiguration returns a list of stack plans for a given stack configuration. - ListByConfiguration(ctx context.Context, stackConfigurationID string, options *StackPlansListOptions) (*StackPlanList, error) - - // Approve approves a stack plan. - Approve(ctx context.Context, stackPlanID string) error - - // Cancel cancels a stack plan. - Cancel(ctx context.Context, stackPlanID string) error - - // Discard discards a stack plan. - Discard(ctx context.Context, stackPlanID string) error - - // PlanDescription returns the plan description for a stack plan. - PlanDescription(ctx context.Context, stackPlanID string) (*JSONChangeDesc, error) - - // AwaitTerminal generates a channel that will receive the status of the stack plan as it progresses. - // See WaitForStatusResult for more information. - AwaitTerminal(ctx context.Context, stackPlanID string) <-chan WaitForStatusResult - - // AwaitRunning generates a channel that will receive the status of the stack plan as it progresses. - // See WaitForStatusResult for more information. - AwaitRunning(ctx context.Context, stackPlanID string) <-chan WaitForStatusResult -} - -type StackPlansStatusFilter string - -const ( - StackPlansStatusFilterCreated StackPlansStatusFilter = "created" - StackPlansStatusFilterRunning StackPlansStatusFilter = "running" - StackPlansStatusFilterPaused StackPlansStatusFilter = "paused" - StackPlansStatusFilterFinished StackPlansStatusFilter = "finished" - StackPlansStatusFilterDiscarded StackPlansStatusFilter = "discarded" - StackPlansStatusFilterErrored StackPlansStatusFilter = "errored" - StackPlansStatusFilterCanceled StackPlansStatusFilter = "canceled" -) - -type StackPlanStatus string - -const ( - StackPlanStatusCreated StackPlanStatus = "created" - StackPlanStatusRunning StackPlanStatus = "running" - StackPlanStatusRunningQueued StackPlanStatus = "running_queued" - StackPlanStatusRunningPlanning StackPlanStatus = "running_planning" - StackPlanStatusRunningApplying StackPlanStatus = "running_applying" - StackPlanStatusFinished StackPlanStatus = "finished" - StackPlanStatusFinishedNoChanges StackPlanStatus = "finished_no_changes" - StackPlanStatusFinishedPlanned StackPlanStatus = "finished_planned" - StackPlanStatusFinishedApplied StackPlanStatus = "finished_applied" - StackPlanStatusDiscarded StackPlanStatus = "discarded" - StackPlanStatusErrored StackPlanStatus = "errored" - StackPlanStatusCanceled StackPlanStatus = "canceled" -) - -type StackPlansIncludeOpt string - -func (s StackPlanStatus) String() string { - return string(s) -} - -const ( - StackPlansIncludeOperations StackPlansIncludeOpt = "stack_plan_operations" -) - -type StackPlansListOptions struct { - ListOptions - - // Optional: A query string to filter plans by status. - Status StackPlansStatusFilter `url:"filter[status],omitempty"` - - // Optional: A query string to filter plans by deployment. - Deployment string `url:"filter[deployment],omitempty"` - - Include []StackPlansIncludeOpt `url:"include,omitempty"` -} - -type StackPlanList struct { - *Pagination - Items []*StackPlan -} - -// stackPlans implements StackPlans. -type stackPlans struct { - client *Client -} - -var _ StackPlans = &stackPlans{} - -// StackPlanStatusTimestamps are the timestamps of the status changes for a stack -type StackPlanStatusTimestamps struct { - CreatedAt time.Time `jsonapi:"attr,created-at,rfc3339"` - RunningAt time.Time `jsonapi:"attr,running-at,rfc3339"` - PausedAt time.Time `jsonapi:"attr,paused-at,rfc3339"` - FinishedAt time.Time `jsonapi:"attr,finished-at,rfc3339"` -} - -// PlanChanges is the summary of the planned changes -type PlanChanges struct { - Add int `jsonapi:"attr,add"` - Total int `jsonapi:"attr,total"` - Change int `jsonapi:"attr,change"` - Import int `jsonapi:"attr,import"` - Remove int `jsonapi:"attr,remove"` -} - -// StackPlan represents a plan for a stack. -type StackPlan struct { - ID string `jsonapi:"primary,stack-plans"` - PlanMode string `jsonapi:"attr,plan-mode"` - PlanNumber string `jsonapi:"attr,plan-number"` - Status StackPlanStatus `jsonapi:"attr,status"` - StatusTimestamps *StackPlanStatusTimestamps `jsonapi:"attr,status-timestamps"` - IsPlanned bool `jsonapi:"attr,is-planned"` - Changes *PlanChanges `jsonapi:"attr,changes"` - Deployment string `jsonapi:"attr,deployment"` - - // Relationships - StackConfiguration *StackConfiguration `jsonapi:"relation,stack-configuration"` - Stack *Stack `jsonapi:"relation,stack"` - StackPlanOperations []*StackPlanOperation `jsonapi:"relation,stack-plan-operations"` -} - -// JSONChangeDesc represents a change description of a stack plan / apply operation. -type JSONChangeDesc struct { - FormatVersion uint64 `json:"terraform_stack_change_description"` - Interim bool `json:"interim,omitempty"` - Applyable bool `json:"applyable"` - PlanMode string `json:"plan_mode"` - Components []JSONComponent `json:"components"` - ResourceInstances []JSONResourceInstance `json:"resource_instances"` - DeferredResourceInstances []JSONResourceInstanceDeferral `json:"deferred_resource_instances"` - Outputs map[string]JSONOutput `json:"outputs"` -} - -// JSONComponent represents a change description of a single component in a plan. -type JSONComponent struct { - Address string `json:"address"` - ComponentAddress string `json:"component_address"` - InstanceCorrelator string `json:"instance_correlator"` - ComponentCorrelator string `json:"component_correlator"` - Actions []ChangeAction `json:"actions"` - Complete bool `json:"complete"` -} - -// ChangeAction are the actions a change can have: no-op, create, read, update, delte, forget. -type ChangeAction string - -// JSONResourceInstance is the change description of a single resource instance in a plan. -type JSONResourceInstance struct { - ComponentInstanceCorrelator string `json:"component_instance_correlator"` - ComponentInstanceAddress string `json:"component_instance_address"` - Address string `json:"address"` - PreviousComponentInstanceAddress string `json:"previous_component_instance_address,omitempty"` - PreviousAddress string `json:"previous_address,omitempty"` - DeposedKey string `json:"deposed,omitempty"` - ResourceMode string `json:"mode,omitempty"` - ResourceType string `json:"type"` - ProviderAddr string `json:"provider_name"` - Change Change `json:"change"` - ResourceName string `json:"resource_name"` - Index json.RawMessage `json:"index"` - IndexUnknown bool `json:"index_unknown"` - ModuleAddr string `json:"module_address"` - ActionReason string `json:"action_reason,omitempty"` -} - -// JSONResourceInstanceDeferral is the change description of a single resource instance that is deferred. -type JSONResourceInstanceDeferral struct { - ResourceInstance JSONResourceInstance `json:"resource_instance"` - Deferred JSONDeferred `json:"deferred"` -} - -// JSONDeferred contains the reason why a resource instance is deferred: instance_count_unknown, resource_config_unknown, provider_config_unknown, provider_config_unknown, or deferred_prereq. -type JSONDeferred struct { - Reason string `json:"reason"` -} - -// JSONOutput is the value of a single output in a plan. -type JSONOutput struct { - Change json.RawMessage `json:"change"` -} - -// Change represents the change of a resource instance in a plan. -type Change struct { - Actions []ChangeAction `json:"actions"` - After json.RawMessage `json:"after"` - Before json.RawMessage `json:"before"` - AfterUnknown json.RawMessage `json:"after_unknown"` - BeforeSensitive json.RawMessage `json:"before_sensitive"` - AfterSensitive json.RawMessage `json:"after_sensitive"` - Importing *JSONImporting `json:"importing,omitempty"` - ReplacePaths json.RawMessage `json:"replace_paths,omitempty"` -} - -// JSONImporting represents the import status of a resource instance in a plan. -type JSONImporting struct { - // True within a deferred instance - Unknown bool `json:"unknown"` - ID string `json:"id"` - GeneratedConfig string `json:"generated_config"` -} - -func (s stackPlans) Read(ctx context.Context, stackPlanID string) (*StackPlan, error) { - req, err := s.client.NewRequest("GET", fmt.Sprintf("stack-plans/%s", url.PathEscape(stackPlanID)), nil) - if err != nil { - return nil, err - } - - sp := &StackPlan{} - err = req.Do(ctx, sp) - if err != nil { - return nil, err - } - - return sp, nil -} - -func (s stackPlans) ListByConfiguration(ctx context.Context, stackConfigurationID string, options *StackPlansListOptions) (*StackPlanList, error) { - req, err := s.client.NewRequest("GET", fmt.Sprintf("stack-configurations/%s/stack-plans", url.PathEscape(stackConfigurationID)), options) - if err != nil { - return nil, err - } - - sl := &StackPlanList{} - err = req.Do(ctx, sl) - if err != nil { - return nil, err - } - - return sl, nil -} - -func (s stackPlans) Approve(ctx context.Context, stackPlanID string) error { - req, err := s.client.NewRequest("POST", fmt.Sprintf("stack-plans/%s/approve", url.PathEscape(stackPlanID)), nil) - if err != nil { - return err - } - - return req.Do(ctx, nil) -} - -func (s stackPlans) Discard(ctx context.Context, stackPlanID string) error { - req, err := s.client.NewRequest("POST", fmt.Sprintf("stack-plans/%s/discard", url.PathEscape(stackPlanID)), nil) - if err != nil { - return err - } - - return req.Do(ctx, nil) -} - -func (s stackPlans) Cancel(ctx context.Context, stackPlanID string) error { - req, err := s.client.NewRequest("POST", fmt.Sprintf("stack-plans/%s/cancel", url.PathEscape(stackPlanID)), nil) - if err != nil { - return err - } - - return req.Do(ctx, nil) -} - -func (s stackPlans) PlanDescription(ctx context.Context, stackPlanID string) (*JSONChangeDesc, error) { - req, err := s.client.NewRequest("GET", fmt.Sprintf("stack-plans/%s/plan-description", url.PathEscape(stackPlanID)), nil) - if err != nil { - return nil, err - } - - jd := &JSONChangeDesc{} - err = req.DoJSON(ctx, jd) - if err != nil { - return nil, err - } - - return jd, nil -} - -// AwaitTerminal generates a channel that will receive the status of the stack plan as it progresses. -// The channel will be closed when the stack plan reaches a final status or an error occurs. The -// read will be retried dependending on the configuration of the client. When the channel is closed, -// the last value will either be a terminal status (finished, finished_no_changes, finished_applied, -// finished_planned, discarded, canceled, errorer), or an error. The status check will continue even -// if the stack plan is waiting for approval. Check the status within the the channel to determine -// if the stack plan needs approval. -func (s stackPlans) AwaitTerminal(ctx context.Context, stackPlanID string) <-chan WaitForStatusResult { - return awaitPoll(ctx, stackPlanID, func(ctx context.Context) (string, error) { - stackPlan, err := s.Read(ctx, stackPlanID) - if err != nil { - return "", err - } - - return stackPlan.Status.String(), nil - }, []string{ - StackPlanStatusFinished.String(), - StackPlanStatusFinishedNoChanges.String(), - StackPlanStatusFinishedApplied.String(), - StackPlanStatusFinishedPlanned.String(), - StackPlanStatusDiscarded.String(), - StackPlanStatusErrored.String(), - StackPlanStatusCanceled.String(), - }) -} - -// AwaitRunning generates a channel that will receive the status of the stack plan as it progresses. -// The channel will be closed when the stack plan reaches a running status (running, running_queued, -// running_planning, running_applying), a terminal status (finished, finished_no_changes, finished_applied, -// finished_planned, discarded, canceled, errorer), or an error occurs. The read will be retried -// dependending on the configuration of the client. -func (s stackPlans) AwaitRunning(ctx context.Context, stackPlanID string) <-chan WaitForStatusResult { - return awaitPoll(ctx, stackPlanID, func(ctx context.Context) (string, error) { - stackPlan, err := s.Read(ctx, stackPlanID) - if err != nil { - return "", err - } - - return stackPlan.Status.String(), nil - }, []string{ - StackPlanStatusRunning.String(), - StackPlanStatusRunningPlanning.String(), - StackPlanStatusRunningApplying.String(), - StackPlanStatusFinished.String(), - StackPlanStatusFinishedNoChanges.String(), - StackPlanStatusFinishedApplied.String(), - StackPlanStatusFinishedPlanned.String(), - StackPlanStatusDiscarded.String(), - StackPlanStatusErrored.String(), - StackPlanStatusCanceled.String(), - }) -} diff --git a/stack_plan_integration_test.go b/stack_plan_integration_test.go deleted file mode 100644 index 29ae34a8a..000000000 --- a/stack_plan_integration_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tfe - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestStackPlanList(t *testing.T) { - skipUnlessBeta(t) - - client := testClient(t) - ctx := context.Background() - - orgTest, orgTestCleanup := createOrganization(t, client) - t.Cleanup(orgTestCleanup) - - _, err := client.Projects.Create(ctx, orgTest.Name, ProjectCreateOptions{ - Name: "test-project-2", - }) - require.NoError(t, err) - - oauthClient, cleanup := createOAuthClient(t, client, orgTest, nil) - t.Cleanup(cleanup) - - stack, err := client.Stacks.Create(ctx, StackCreateOptions{ - Name: "aa-test-stack", - VCSRepo: &StackVCSRepoOptions{ - Identifier: "brandonc/pet-nulls-stack", - OAuthTokenID: oauthClient.OAuthTokens[0].ID, - }, - Project: &Project{ - ID: orgTest.DefaultProject.ID, - }, - }) - require.NoError(t, err) - - stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID) - require.NoError(t, err) - - stackUpdated = pollStackDeployments(t, ctx, client, stackUpdated.ID) - require.NotNil(t, stackUpdated.LatestStackConfiguration) - - planList, err := client.StackPlans.ListByConfiguration(ctx, stackUpdated.LatestStackConfiguration.ID, &StackPlansListOptions{}) - require.NoError(t, err) - - require.Len(t, planList.Items, 4) - - plan, err := client.StackPlans.Read(ctx, planList.Items[0].ID) - require.NoError(t, err) - require.NotNil(t, plan) - - jsonSchema, err := client.StackConfigurations.JSONSchemas(ctx, stackUpdated.LatestStackConfiguration.ID) - require.NoError(t, err) - require.NotNil(t, jsonSchema) - - planDesc, err := client.StackPlans.PlanDescription(ctx, planList.Items[0].ID) - require.NoError(t, err) - require.NotNil(t, planDesc) - - spo, err := client.StackPlanOperations.Read(ctx, stackUpdated.LatestStackConfiguration.ID) - require.NoError(t, err) - require.NotNil(t, spo) -} diff --git a/stack_plan_operation.go b/stack_plan_operation.go deleted file mode 100644 index 3674203d4..000000000 --- a/stack_plan_operation.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tfe - -import ( - "context" - "fmt" - "io" - "net/http" - "net/url" -) - -// NOTE WELL: This is a beta feature and is subject to change until noted otherwise in the -// release notes. -type StackPlanOperations interface { - // Read returns a stack plan operation by its ID. - Read(ctx context.Context, stackPlanOperationID string) (*StackPlanOperation, error) - - // Get Stack Plans from Configuration Version - DownloadEventStream(ctx context.Context, stackPlanOperationID string) ([]byte, error) -} - -type stackPlanOperations struct { - client *Client -} - -var _ StackPlanOperations = &stackPlanOperations{} - -type StackPlanOperation struct { - ID string `jsonapi:"primary,stack-plan-operations"` - Type string `jsonapi:"attr,operation-type"` - Status string `jsonapi:"attr,status"` - EventStreamURL string `jsonapi:"attr,event-stream-url"` - Diagnostics []*StackDiagnostic `jsonapi:"attr,diags"` - - // Relations - StackPlan *StackPlan `jsonapi:"relation,stack-plan"` -} - -func (s stackPlanOperations) Read(ctx context.Context, stackPlanOperationID string) (*StackPlanOperation, error) { - req, err := s.client.NewRequest("GET", fmt.Sprintf("stack-plan-operations/%s", url.PathEscape(stackPlanOperationID)), nil) - if err != nil { - return nil, err - } - - spo := &StackPlanOperation{} - err = req.Do(ctx, spo) - if err != nil { - return nil, err - } - - return spo, nil -} - -func (s stackPlanOperations) DownloadEventStream(ctx context.Context, eventStreamURL string) ([]byte, error) { - // Create a new request. - req, err := http.NewRequest("GET", eventStreamURL, nil) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - - // Attach the default headers. - for k, v := range s.client.headers { - req.Header[k] = v - } - - // Retrieve the next chunk. - resp, err := s.client.http.HTTPClient.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - // Basic response checking. - if err := checkResponseCode(resp); err != nil { - return nil, err - } - - // Read the retrieved chunk. - b, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - return b, nil -} diff --git a/stack_source.go b/stack_source.go deleted file mode 100644 index 16cde92fa..000000000 --- a/stack_source.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tfe - -import ( - "context" - "fmt" - "io" - "net/url" -) - -// StackSources describes all the stack-sources related methods that the HCP Terraform API supports. -// NOTE WELL: This is a beta feature and is subject to change until noted otherwise in the -// release notes. -type StackSources interface { - // Read retrieves a stack source by its ID. - Read(ctx context.Context, stackSourceID string) (*StackSource, error) - - // CreateAndUpload packages and uploads the specified Terraform Stacks - // configuration files in association with a Stack. - CreateAndUpload(ctx context.Context, stackID string, path string, opts *CreateStackSourceOptions) (*StackSource, error) - - // UploadTarGzip is used to upload Terraform configuration files contained a tar gzip archive. - // Any stream implementing io.Reader can be passed into this method. This method is also - // particularly useful for tar streams created by non-default go-slug configurations. - // - // **Note**: This method does not validate the content being uploaded and is therefore the caller's - // responsibility to ensure the raw content is a valid Terraform configuration. - UploadTarGzip(ctx context.Context, uploadURL string, archive io.Reader) error -} - -type CreateStackSourceOptions struct { - SelectedDeployments []string `jsonapi:"attr,selected-deployments,omitempty"` - SpeculativeEnabled *bool `jsonapi:"attr,speculative,omitempty"` -} - -var _ StackSources = (*stackSources)(nil) - -type stackSources struct { - client *Client -} - -// StackSource represents a source of Terraform Stacks configuration files. -type StackSource struct { - ID string `jsonapi:"primary,stack-sources"` - UploadURL *string `jsonapi:"attr,upload-url"` - StackConfiguration *StackConfiguration `jsonapi:"relation,stack-configuration"` - Stack *Stack `jsonapi:"relation,stack"` -} - -// Read retrieves a stack source by its ID. -func (s *stackSources) Read(ctx context.Context, stackSourceID string) (*StackSource, error) { - u := fmt.Sprintf("stack-sources/%s", url.PathEscape(stackSourceID)) - req, err := s.client.NewRequest("GET", u, nil) - if err != nil { - return nil, err - } - - ss := &StackSource{} - err = req.Do(ctx, ss) - if err != nil { - return nil, err - } - - return ss, nil -} - -// CreateAndUpload packages and uploads the specified Terraform Stacks -// configuration files in association with a Stack. -func (s *stackSources) CreateAndUpload(ctx context.Context, stackID, path string, opts *CreateStackSourceOptions) (*StackSource, error) { - if opts == nil { - opts = &CreateStackSourceOptions{} - } - u := fmt.Sprintf("stacks/%s/stack-sources", url.PathEscape(stackID)) - req, err := s.client.NewRequest("POST", u, opts) - if err != nil { - return nil, err - } - - ss := &StackSource{} - err = req.Do(ctx, ss) - if err != nil { - return nil, err - } - - body, err := packContents(path) - if err != nil { - return nil, err - } - - return ss, s.UploadTarGzip(ctx, *ss.UploadURL, body) -} - -// UploadTarGzip is used to upload Terraform configuration files contained a tar gzip archive. -// Any stream implementing io.Reader can be passed into this method. This method is also -// particularly useful for tar streams created by non-default go-slug configurations. -// -// **Note**: This method does not validate the content being uploaded and is therefore the caller's -// responsibility to ensure the raw content is a valid Terraform configuration. -func (s *stackSources) UploadTarGzip(ctx context.Context, uploadURL string, archive io.Reader) error { - return s.client.doForeignPUTRequest(ctx, uploadURL, archive) -} diff --git a/stack_source_integration_test.go b/stack_source_integration_test.go deleted file mode 100644 index 3e3445d24..000000000 --- a/stack_source_integration_test.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tfe - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestStackSourceCreateUploadAndRead(t *testing.T) { - skipUnlessBeta(t) - - client := testClient(t) - ctx := context.Background() - - orgTest, orgTestCleanup := createOrganization(t, client) - t.Cleanup(orgTestCleanup) - - oauthClient, cleanup := createOAuthClient(t, client, orgTest, nil) - t.Cleanup(cleanup) - - stack, err := client.Stacks.Create(ctx, StackCreateOptions{ - Project: orgTest.DefaultProject, - Name: "test-stack", - VCSRepo: &StackVCSRepoOptions{ - Identifier: "hashicorp-guides/pet-nulls-stack", - OAuthTokenID: oauthClient.OAuthTokens[0].ID, - }, - }) - require.NoError(t, err) - - ss, err := client.StackSources.CreateAndUpload(ctx, stack.ID, "test-fixtures/stack-source", &CreateStackSourceOptions{ - SelectedDeployments: []string{"simple"}, - }) - require.NoError(t, err) - require.NotNil(t, ss) - require.Nil(t, ss.StackConfiguration) - - ctx, cancel := context.WithTimeout(ctx, 20*time.Second) - defer cancel() - - done := make(chan struct{}) - go func() { - for { - ss, err = client.StackSources.Read(ctx, ss.ID) - require.NoError(t, err) - - if ss.StackConfiguration != nil { - done <- struct{}{} - return - } - - time.Sleep(2 * time.Second) - } - }() - - select { - case <-done: - t.Logf("Found stack source configuration %q", ss.StackConfiguration.ID) - return - case <-ctx.Done(): - require.Fail(t, "timed out waiting for stack source to be processed") - } -} - -func TestStackSourceSpeculatives(t *testing.T) { - skipUnlessBeta(t) - - client := testClient(t) - ctx := context.Background() - - orgTest, orgTestCleanup := createOrganization(t, client) - t.Cleanup(orgTestCleanup) - - oauthClient, cleanup := createOAuthClient(t, client, orgTest, nil) - t.Cleanup(cleanup) - - stackVCS, err := client.Stacks.Create(ctx, StackCreateOptions{ - Project: orgTest.DefaultProject, - Name: "test-stack-vcs", - VCSRepo: &StackVCSRepoOptions{ - Identifier: "hashicorp-guides/pet-nulls-stack", - OAuthTokenID: oauthClient.OAuthTokens[0].ID, - }, - }) - require.NoError(t, err) - - stack, err := client.Stacks.Create(ctx, StackCreateOptions{ - Project: &Project{ - ID: orgTest.DefaultProject.ID, - }, - Name: "test-stack", - }) - require.NoError(t, err) - - t.Run("with speculative run enabled for VCS upload", func(t *testing.T) { - ss, err := client.StackSources.CreateAndUpload(ctx, stackVCS.ID, "test-fixtures/stack-source", &CreateStackSourceOptions{ - SelectedDeployments: []string{"simple"}, - SpeculativeEnabled: Bool(true), - }) - require.NoError(t, err) - require.NotNil(t, ss) - require.NotNil(t, ss.UploadURL) - }) - - t.Run("with speculative run disabled for manual upload", func(t *testing.T) { - ss, err := client.StackSources.CreateAndUpload(ctx, stack.ID, "test-fixtures/stack-source", &CreateStackSourceOptions{ - SelectedDeployments: []string{"simple"}, - SpeculativeEnabled: Bool(false), - }) - require.NoError(t, err) - require.NotNil(t, ss) - require.NotNil(t, ss.UploadURL) - }) - - t.Run("with invalid speculative run option for VCS upload", func(t *testing.T) { - ss, err := client.StackSources.CreateAndUpload(ctx, stackVCS.ID, "test-fixtures/stack-source", &CreateStackSourceOptions{ - SelectedDeployments: []string{"simple"}, - SpeculativeEnabled: Bool(false), - }) - require.Nil(t, ss) - require.Error(t, err) - }) -} diff --git a/tfe.go b/tfe.go index 3fbcf5805..ce7a997e7 100644 --- a/tfe.go +++ b/tfe.go @@ -166,13 +166,9 @@ type Client struct { SSHKeys SSHKeys Stacks Stacks StackConfigurations StackConfigurations - StackDeployments StackDeployments StackDeploymentGroups StackDeploymentGroups StackDeploymentRuns StackDeploymentRuns StackDeploymentSteps StackDeploymentSteps - StackPlans StackPlans - StackPlanOperations StackPlanOperations - StackSources StackSources StateVersionOutputs StateVersionOutputs StateVersions StateVersions TaskResults TaskResults @@ -500,13 +496,9 @@ func NewClient(cfg *Config) (*Client, error) { client.SSHKeys = &sshKeys{client: client} client.Stacks = &stacks{client: client} client.StackConfigurations = &stackConfigurations{client: client} - client.StackDeployments = &stackDeployments{client: client} client.StackDeploymentGroups = &stackDeploymentGroups{client: client} client.StackDeploymentRuns = &stackDeploymentRuns{client: client} client.StackDeploymentSteps = &stackDeploymentSteps{client: client} - client.StackPlans = &stackPlans{client: client} - client.StackPlanOperations = &stackPlanOperations{client: client} - client.StackSources = &stackSources{client: client} client.StateVersionOutputs = &stateVersionOutputs{client: client} client.StateVersions = &stateVersions{client: client} client.TaskResults = &taskResults{client: client} From 5a35f2b25344860b2d3ecac39b0d1d27bf8f5554 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Thu, 28 Aug 2025 17:11:50 -0400 Subject: [PATCH 02/11] diagnostic back --- stack_diagnostic.go | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 stack_diagnostic.go diff --git a/stack_diagnostic.go b/stack_diagnostic.go new file mode 100644 index 000000000..223c4358f --- /dev/null +++ b/stack_diagnostic.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package tfe + +// StackDiagnostic represents any sourcebundle.Diagnostic value. The simplest form has +// just a severity, single line summary, and optional detail. If there is more +// information about the source of the diagnostic, this is represented in the +// range field. +type StackDiagnostic struct { + Severity string `jsonapi:"attr,severity"` + Summary string `jsonapi:"attr,summary"` + Detail string `jsonapi:"attr,detail"` + Range *DiagnosticRange `jsonapi:"attr,range"` +} + +// DiagnosticPos represents a position in the source code. +type DiagnosticPos struct { + // Line is a one-based count for the line in the indicated file. + Line int `jsonapi:"attr,line"` + + // Column is a one-based count of Unicode characters from the start of the line. + Column int `jsonapi:"attr,column"` + + // Byte is a zero-based offset into the indicated file. + Byte int `jsonapi:"attr,byte"` +} + +// DiagnosticRange represents the filename and position of the diagnostic +// subject. This defines the range of the source to be highlighted in the +// output. Note that the snippet may include additional surrounding source code +// if the diagnostic has a context range. +// +// The stacks-specific source field represents the full source bundle address +// of the file, while the filename field is the sub path relative to its +// enclosing package. This represents an attempt to be somewhat backwards +// compatible with the existing Terraform JSON diagnostic format, where +// filename is root module relative. +// +// The Start position is inclusive, and the End position is exclusive. Exact +// positions are intended for highlighting for human interpretation only and +// are subject to change. +type DiagnosticRange struct { + Filename string `jsonapi:"attr,filename"` + Source string `jsonapi:"attr,source"` + Start DiagnosticPos `jsonapi:"attr,start"` + End DiagnosticPos `jsonapi:"attr,end"` +} From 78af404167a043ddc918fd74fe33eb6167811df3 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Fri, 29 Aug 2025 13:26:31 -0400 Subject: [PATCH 03/11] Update CHANGELOG.md --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 551482556..2e9820d6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ # v1.91.1 +## Enhancements + +* Updates endpoint for deleting stack from `POST` to `DELETE` and removing `/delete` from endpoint by +* Updates endpoint for force deleting stack from `POST` to `DELETE` and removing `/force-delete` from endpoint and adding `?force=true` by + +## Deprecations + +* The `GET` endpoint to return a `StackPlan` by its ID has been deprecated by +* The `GET` endpoint to return a list of stack plans for a given stack configuration has been deprecated by +* The `POST` endpoint to approve a stack plan has been deprecated by +* The `POST` endpoint to cancel a stack plan has been deprecated by +* The `POST` endpoint to discard a stack plan has been deprecated by +* The `GET` endpoint to return the plan description for a stack plan has been deprecated by +* The `AwaitTerminal` method to generate a channel that will receive the status of the stack plan has been deprecated by +* The `AwaitRunning` method to generate a channel that will receive the status of the stack plan has been deprecated by +* The `GET` endpoint to return a stack plan operation by its ID has been deprecated by +* The `GET` endpoint to return a stack source by its ID has been deprecated by +* The `POST` endpoint to package and upload the specified Terraform Stacks configuration files in association with a Stack has been deprecated by + ## Bug Fixes * Fixes timestamp attribute mapping for deployment runs to use correct API field names (`created-at`/`updated-at` instead of `started-at`/`completed-at`) by @shwetamurali [#1199](https://github.com/hashicorp/go-tfe/pull/1199) From 1b5ffec00c2db34faeafd68cc0985554d9f6b6ec Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Tue, 2 Sep 2025 10:51:42 -0400 Subject: [PATCH 04/11] Update CHANGELOG.md --- CHANGELOG.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e9820d6a..3ead431d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,17 +9,17 @@ ## Deprecations -* The `GET` endpoint to return a `StackPlan` by its ID has been deprecated by -* The `GET` endpoint to return a list of stack plans for a given stack configuration has been deprecated by -* The `POST` endpoint to approve a stack plan has been deprecated by -* The `POST` endpoint to cancel a stack plan has been deprecated by -* The `POST` endpoint to discard a stack plan has been deprecated by -* The `GET` endpoint to return the plan description for a stack plan has been deprecated by -* The `AwaitTerminal` method to generate a channel that will receive the status of the stack plan has been deprecated by -* The `AwaitRunning` method to generate a channel that will receive the status of the stack plan has been deprecated by -* The `GET` endpoint to return a stack plan operation by its ID has been deprecated by -* The `GET` endpoint to return a stack source by its ID has been deprecated by -* The `POST` endpoint to package and upload the specified Terraform Stacks configuration files in association with a Stack has been deprecated by +* The `GET` endpoint to return a `StackPlan` by its ID has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `GET` endpoint to return a list of stack plans for a given stack configuration has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `POST` endpoint to approve a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `POST` endpoint to cancel a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `POST` endpoint to discard a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `GET` endpoint to return the plan description for a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `AwaitTerminal` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `AwaitRunning` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `GET` endpoint to return a stack plan operation by its ID has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `GET` endpoint to return a stack source by its ID has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `POST` endpoint to package and upload the specified Terraform Stacks configuration files in association with a Stack has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) ## Bug Fixes From 867e9662ea90b57ecd1200b4690f806f7e50fcc3 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Tue, 2 Sep 2025 11:43:08 -0400 Subject: [PATCH 05/11] Update CHANGELOG.md --- CHANGELOG.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ead431d7..5a2a2bcaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,17 +9,17 @@ ## Deprecations -* The `GET` endpoint to return a `StackPlan` by its ID has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `GET` endpoint to return a list of stack plans for a given stack configuration has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `POST` endpoint to approve a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `POST` endpoint to cancel a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `POST` endpoint to discard a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `GET` endpoint to return the plan description for a stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `AwaitTerminal` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `AwaitRunning` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `GET` endpoint to return a stack plan operation by its ID has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `GET` endpoint to return a stack source by its ID has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) -* The `POST` endpoint to package and upload the specified Terraform Stacks configuration files in association with a Stack has been deprecated by @sahar-azizighannad [#...](https://github.com/hashicorp/go-tfe/pull/...) +* The `GET` endpoint to return a `StackPlan` by its ID has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `GET` endpoint to return a list of stack plans for a given stack configuration has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `POST` endpoint to approve a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `POST` endpoint to cancel a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `POST` endpoint to discard a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `GET` endpoint to return the plan description for a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `AwaitTerminal` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `AwaitRunning` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `GET` endpoint to return a stack plan operation by its ID has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `GET` endpoint to return a stack source by its ID has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* The `POST` endpoint to package and upload the specified Terraform Stacks configuration files in association with a Stack has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) ## Bug Fixes From d92382a740f2ee0067adb253d2b3880fe0ea74a8 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Tue, 2 Sep 2025 12:27:41 -0400 Subject: [PATCH 06/11] Update stack_integration_test.go --- stack_integration_test.go | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/stack_integration_test.go b/stack_integration_test.go index 2f5669c04..1ec463898 100644 --- a/stack_integration_test.go +++ b/stack_integration_test.go @@ -340,37 +340,6 @@ func pollStackDeployments(t *testing.T, ctx context.Context, client *Client, sta return } -func pollStackDeploymentStatus(t *testing.T, ctx context.Context, client *Client, stackID, deploymentName, status string) { - // pollStackDeployments will poll the given stack until it has deployments or the deadline is reached. - ctx, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute)) - defer cancel() - - deadline, _ := ctx.Deadline() - t.Logf("Polling stack %q for deployments with deadline of %s", stackID, deadline) - - ticker := time.NewTicker(2 * time.Second) - defer ticker.Stop() - - for finished := false; !finished; { - t.Log("...") - select { - case <-ctx.Done(): - t.Fatalf("Stack deployment %s/%s did not have status %q at deadline", stackID, deploymentName, status) - case <-ticker.C: - var err error - deployment, err := client.StackDeployments.Read(ctx, stackID, deploymentName) - if err != nil { - t.Fatalf("Failed to read stack deployment %s/%s: %s", stackID, deploymentName, err) - } - - t.Logf("Stack deployment %s/%s had status %q", stackID, deploymentName, deployment.Status) - if deployment.Status == status { - finished = true - } - } - } -} - func pollStackConfigurationStatus(t *testing.T, ctx context.Context, client *Client, stackConfigID, status string) (stackConfig *StackConfiguration) { // pollStackDeployments will poll the given stack until it has deployments or the deadline is reached. ctx, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute)) @@ -440,9 +409,5 @@ func TestStackConverged(t *testing.T) { require.ElementsMatch(t, deployments, stack.DeploymentNames) require.NotNil(t, stack.LatestStackConfiguration) - for _, deployment := range deployments { - pollStackDeploymentStatus(t, ctx, client, stack.ID, deployment, "paused") - } - pollStackConfigurationStatus(t, ctx, client, stack.LatestStackConfiguration.ID, "converged") } From d57e656be3356116b23e73af3bfdd6032fb5d827 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Tue, 2 Sep 2025 13:52:35 -0400 Subject: [PATCH 07/11] Update CHANGELOG.md Co-authored-by: Chris Trombley --- CHANGELOG.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a2a2bcaa..9b667f21d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,18 +9,7 @@ ## Deprecations -* The `GET` endpoint to return a `StackPlan` by its ID has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `GET` endpoint to return a list of stack plans for a given stack configuration has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `POST` endpoint to approve a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `POST` endpoint to cancel a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `POST` endpoint to discard a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `GET` endpoint to return the plan description for a stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `AwaitTerminal` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `AwaitRunning` method to generate a channel that will receive the status of the stack plan has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `GET` endpoint to return a stack plan operation by its ID has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `GET` endpoint to return a stack source by its ID has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* The `POST` endpoint to package and upload the specified Terraform Stacks configuration files in association with a Stack has been deprecated by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) - +* The beta `StackDeployments`, `StackPlan`, `StackPlanOperation`, and `StackSource` resources have been removed, by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) ## Bug Fixes * Fixes timestamp attribute mapping for deployment runs to use correct API field names (`created-at`/`updated-at` instead of `started-at`/`completed-at`) by @shwetamurali [#1199](https://github.com/hashicorp/go-tfe/pull/1199) From ea36d561f77904667667905ad18819dde8d7e7c8 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Tue, 2 Sep 2025 16:39:09 -0400 Subject: [PATCH 08/11] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a9e2ec8..6ef6f24fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ ## Enhancements -* Updates endpoint for deleting stack from `POST` to `DELETE` and removing `/delete` from endpoint by -* Updates endpoint for force deleting stack from `POST` to `DELETE` and removing `/force-delete` from endpoint and adding `?force=true` by +* Updates endpoint for deleting stack from `POST` to `DELETE` and removing `/delete` from endpoint by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) +* Updates endpoint for force deleting stack from `POST` to `DELETE` and removing `/force-delete` from endpoint and adding `?force=true` by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) ## Deprecations From 140f0ecaadf2040af540dfb41f6bd764df686113 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Wed, 3 Sep 2025 15:14:05 -0400 Subject: [PATCH 09/11] Update stack.go --- stack.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/stack.go b/stack.go index 0257b7b45..7848d7ffd 100644 --- a/stack.go +++ b/stack.go @@ -137,21 +137,6 @@ type StackConfiguration struct { Stack *Stack `jsonapi:"relation,stack"` } -// StackDeployment represents a stack deployment, specified by configuration -type StackDeployment struct { - // Attributes - ID string `jsonapi:"primary,stack-deployments"` - Name string `jsonapi:"attr,name"` - Status string `jsonapi:"attr,status"` - DeployedAt time.Time `jsonapi:"attr,deployed-at,iso8601"` - ErrorsCount int `jsonapi:"attr,errors-count"` - WarningsCount int `jsonapi:"attr,warnings-count"` - PausedCount int `jsonapi:"attr,paused-count"` - - // Relationships - CurrentStackState *StackState `jsonapi:"relation,current-stack-state"` -} - // StackState represents a stack state type StackState struct { // Attributes From ef8ec3df6d1e7a0ee5138d29c3b8df24c0b31b49 Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Mon, 15 Sep 2025 15:13:26 -0400 Subject: [PATCH 10/11] Update CHANGELOG.md --- CHANGELOG.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e00010ade..e0ef456af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,20 +7,16 @@ * Adds BETA support for performing Registry Module test runs on custom Agents by @hashimooon [#1209](httpsLhttps://github.com/hashicorp/go-tfe/pull/1209) * Adds support for managing agent pools on `Stacks` by @maed223 [#1214](https://github.com/hashicorp/go-tfe/pull/1214) +## Deprecations + +* The beta `StackDeployments`, `StackPlan`, `StackPlanOperation`, and `StackSource` resources have been removed, by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) + ## Bug Fixes * Fixes arch validation on Terraform, OPA, and Sentinel Tool Versions when providing top level `url` and `sha` with multiple `archs` by @kelsi-hoyle [#1212](https://github.com/hashicorp/go-tfe/pull/1212) # v1.91.1 -## Enhancements - -* Updates endpoint for deleting stack from `POST` to `DELETE` and removing `/delete` from endpoint by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) -* Updates endpoint for force deleting stack from `POST` to `DELETE` and removing `/force-delete` from endpoint and adding `?force=true` by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) - -## Deprecations - -* The beta `StackDeployments`, `StackPlan`, `StackPlanOperation`, and `StackSource` resources have been removed, by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) ## Bug Fixes * Fixes timestamp attribute mapping for deployment runs to use correct API field names (`created-at`/`updated-at` instead of `started-at`/`completed-at`) by @shwetamurali [#1199](https://github.com/hashicorp/go-tfe/pull/1199) From 170a21c365a2f86d9289358a088641dcfc72837e Mon Sep 17 00:00:00 2001 From: sahar-azizighannad Date: Tue, 16 Sep 2025 14:44:44 -0400 Subject: [PATCH 11/11] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df91f0439..94fa68e2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## Enhancements * Exports the StackConfiguration UploadTarGzip receiver function[#1219](https://github.com/hashicorp/go-tfe/pull/1219) +## Deprecations + +* The beta `StackDeployments`, `StackPlan`, `StackPlanOperation`, and `StackSource` resources have been removed, by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) + # v1.92.0 ## Enhancements @@ -10,10 +14,6 @@ * Adds BETA support for performing Registry Module test runs on custom Agents by @hashimooon [#1209](httpsLhttps://github.com/hashicorp/go-tfe/pull/1209) * Adds support for managing agent pools on `Stacks` by @maed223 [#1214](https://github.com/hashicorp/go-tfe/pull/1214) -## Deprecations - -* The beta `StackDeployments`, `StackPlan`, `StackPlanOperation`, and `StackSource` resources have been removed, by @sahar-azizighannad [#1205](https://github.com/hashicorp/go-tfe/pull/1205) - ## Bug Fixes * Fixes arch validation on Terraform, OPA, and Sentinel Tool Versions when providing top level `url` and `sha` with multiple `archs` by @kelsi-hoyle [#1212](https://github.com/hashicorp/go-tfe/pull/1212)