Skip to content

Commit 78425f8

Browse files
authored
Merge pull request #1172 from hashicorp/TF-25656/deployment-run-cancel
Add `Cancel` to deployment run interface
2 parents b352292 + fdf107f commit 78425f8

File tree

4 files changed

+116
-5
lines changed

4 files changed

+116
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Enhancements
44
* Add the `Links` attribute to the `StackDeploymentStep` struct to support the deployment step GET endpoint by @shwetamurali [#1167](https://github.com/h)
5+
* Adds endpoint for cancelling `StackDeploymentRun` by @Maed223 [#1172](https://github.com/hashicorp/go-tfe/pull/1172)
56

67
# v1.88.0
78

stack_deployment_runs.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type StackDeploymentRuns interface {
1717
Read(ctx context.Context, stackDeploymentRunID string) (*StackDeploymentRun, error)
1818
ReadWithOptions(ctx context.Context, stackDeploymentRunID string, options *StackDeploymentRunReadOptions) (*StackDeploymentRun, error)
1919
ApproveAllPlans(ctx context.Context, deploymentRunID string) error
20+
Cancel(ctx context.Context, stackDeploymentRunID string) error
2021
}
2122

2223
// stackDeploymentRuns implements StackDeploymentRuns.
@@ -120,6 +121,15 @@ func (s stackDeploymentRuns) ApproveAllPlans(ctx context.Context, stackDeploymen
120121
return req.Do(ctx, nil)
121122
}
122123

124+
func (s stackDeploymentRuns) Cancel(ctx context.Context, stackDeploymentRunID string) error {
125+
req, err := s.client.NewRequest("POST", fmt.Sprintf("stack-deployment-runs/%s/cancel", url.PathEscape(stackDeploymentRunID)), nil)
126+
if err != nil {
127+
return err
128+
}
129+
130+
return req.Do(ctx, nil)
131+
}
132+
123133
func (o *StackDeploymentRunReadOptions) valid() error {
124134
for _, include := range o.Include {
125135
switch include {

stack_deployment_runs_integration_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package tfe
66
import (
77
"context"
88
"testing"
9+
"time"
910

1011
"github.com/stretchr/testify/assert"
1112
"github.com/stretchr/testify/require"
@@ -216,3 +217,96 @@ func TestStackDeploymentRunsApproveAllPlans(t *testing.T) {
216217
require.NoError(t, err)
217218
})
218219
}
220+
221+
func TestStackDeploymentRunsCancel(t *testing.T) {
222+
skipUnlessBeta(t)
223+
224+
client := testClient(t)
225+
ctx := context.Background()
226+
227+
orgTest, orgTestCleanup := createOrganization(t, client)
228+
t.Cleanup(orgTestCleanup)
229+
230+
oauthClient, cleanup := createOAuthClient(t, client, orgTest, nil)
231+
t.Cleanup(cleanup)
232+
233+
stack, err := client.Stacks.Create(ctx, StackCreateOptions{
234+
Project: orgTest.DefaultProject,
235+
Name: "test-stack",
236+
VCSRepo: &StackVCSRepoOptions{
237+
Identifier: "hashicorp-guides/pet-nulls-stack",
238+
OAuthTokenID: oauthClient.OAuthTokens[0].ID,
239+
Branch: "main",
240+
},
241+
})
242+
require.NoError(t, err)
243+
require.NotNil(t, stack)
244+
245+
stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID)
246+
require.NoError(t, err)
247+
require.NotNil(t, stackUpdated)
248+
249+
stack = pollStackDeployments(t, ctx, client, stackUpdated.ID)
250+
require.NotNil(t, stack.LatestStackConfiguration)
251+
252+
// Get the deployment group ID from the stack configuration
253+
deploymentGroups, err := client.StackDeploymentGroups.List(ctx, stack.LatestStackConfiguration.ID, nil)
254+
require.NoError(t, err)
255+
require.NotNil(t, deploymentGroups)
256+
require.NotEmpty(t, deploymentGroups.Items)
257+
258+
deploymentGroupID := deploymentGroups.Items[0].ID
259+
260+
runList, err := client.StackDeploymentRuns.List(ctx, deploymentGroupID, nil)
261+
require.NoError(t, err)
262+
assert.NotNil(t, runList)
263+
264+
deploymentRunID := runList.Items[0].ID
265+
266+
t.Run("cancel deployment run", func(t *testing.T) {
267+
t.Parallel()
268+
err := client.StackDeploymentRuns.ApproveAllPlans(ctx, deploymentRunID)
269+
require.NoError(t, err)
270+
271+
pollStackDeploymentRunForDeployingStatus(t, ctx, client, deploymentRunID)
272+
273+
err = client.StackDeploymentRuns.Cancel(ctx, deploymentRunID)
274+
require.NoError(t, err)
275+
276+
dr, err := client.StackDeploymentRuns.Read(ctx, deploymentRunID)
277+
require.NoError(t, err)
278+
assert.NotNil(t, dr)
279+
assert.Equal(t, "abandoned", dr.Status)
280+
})
281+
}
282+
283+
func pollStackDeploymentRunForDeployingStatus(t *testing.T, ctx context.Context, client *Client, stackDeploymentRunID string) {
284+
t.Helper()
285+
286+
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute))
287+
defer cancel()
288+
289+
deadline, _ := ctx.Deadline()
290+
t.Logf("Polling stack deployment run %q for deploying status, with deadline of %s", stackDeploymentRunID, deadline)
291+
292+
ticker := time.NewTicker(2 * time.Second)
293+
defer ticker.Stop()
294+
295+
for finished := false; !finished; {
296+
t.Log("...")
297+
select {
298+
case <-ctx.Done():
299+
t.Fatalf("Stack deployment run %q not deploying at deadline", stackDeploymentRunID)
300+
case <-ticker.C:
301+
var err error
302+
sdr, err := client.StackDeploymentRuns.Read(ctx, stackDeploymentRunID)
303+
if err != nil {
304+
t.Fatalf("Failed to read stack deployment run %q: %s", stackDeploymentRunID, err)
305+
}
306+
307+
if sdr.Status == "deploying" {
308+
finished = true
309+
}
310+
}
311+
}
312+
}

stack_integration_test.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ func pollStackDeployments(t *testing.T, ctx context.Context, client *Client, sta
307307
defer cancel()
308308

309309
deadline, _ := ctx.Deadline()
310-
t.Logf("Polling stack %q for deployments with deadline of %s", stackID, deadline)
310+
t.Logf("Polling stack %q for deployment groups with deadline of %s", stackID, deadline)
311311

312312
ticker := time.NewTicker(2 * time.Second)
313313
defer ticker.Stop()
@@ -316,16 +316,22 @@ func pollStackDeployments(t *testing.T, ctx context.Context, client *Client, sta
316316
t.Log("...")
317317
select {
318318
case <-ctx.Done():
319-
t.Fatalf("Stack %q had no deployments at deadline", stackID)
319+
t.Fatalf("Stack %q had no deployment groups at deadline", stackID)
320320
case <-ticker.C:
321321
var err error
322-
stack, err = client.Stacks.Read(ctx, stackID, nil)
322+
stack, err = client.Stacks.Read(ctx, stackID, &StackReadOptions{
323+
Include: []StackIncludeOpt{StackIncludeLatestStackConfiguration},
324+
})
323325
if err != nil {
324326
t.Fatalf("Failed to read stack %q: %s", stackID, err)
325327
}
328+
groups, err := client.StackDeploymentGroups.List(ctx, stack.LatestStackConfiguration.ID, nil)
329+
if err != nil {
330+
t.Fatalf("Failed to read deployment groups %q: %s", stackID, err)
331+
}
326332

327-
t.Logf("Stack %q had %d deployments", stack.ID, len(stack.DeploymentNames))
328-
if len(stack.DeploymentNames) > 0 {
333+
t.Logf("Stack %q had %d deployment groups", stack.ID, len(stack.DeploymentNames))
334+
if groups.TotalCount > 0 {
329335
finished = true
330336
}
331337
}

0 commit comments

Comments
 (0)