Skip to content

Commit b352292

Browse files
Merge pull request #1166 from hashicorp/TF-27757/deployment-step-advance
Added deployment step advance endpoint
2 parents 06efce6 + 6f075c8 commit b352292

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* Adds BETA support for reading, testing and updating Organization Audit Configuration by @glennsarti-hashi [#1151](https://github.com/hashicorp/go-tfe/pull/1151)
1111
* Adds `Completed` status to `StackConfiguration` by @hwatkins05-hashicorp [#1163](https://github.com/hashicorp/go-tfe/pull/1163)
1212
* Adds `CreatedAt` and `UpdatedAt` fields to `StackConfiguration` by @Maed223 [#1168](https://github.com/hashicorp/go-tfe/pull/1168)
13+
* Adds endpoint for advancing `StackDeploymentStep` by @hwatkins05-hashicorp [#1166](https://github.com/hashicorp/go-tfe/pull/1166)
1314

1415
# v1.87.0
1516

stack_deployment_steps.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import (
1717
type StackDeploymentSteps interface {
1818
// List returns the stack deployment steps for a stack deployment run.
1919
List(ctx context.Context, stackDeploymentRunID string, opts *StackDeploymentStepsListOptions) (*StackDeploymentStepList, error)
20+
// Read returns a stack deployment step by its ID.
2021
Read(ctx context.Context, stackDeploymentStepID string) (*StackDeploymentStep, error)
22+
// Advance advances the stack deployment step when in the "pending_operator" state.
23+
Advance(ctx context.Context, stackDeploymentStepID string) error
2124
}
2225

2326
// StackDeploymentStep represents a step from a stack deployment
@@ -66,6 +69,7 @@ func (s stackDeploymentSteps) List(ctx context.Context, stackDeploymentRunID str
6669
return &steps, nil
6770
}
6871

72+
// Read returns a stack deployment step by its ID.
6973
func (s stackDeploymentSteps) Read(ctx context.Context, stackDeploymentStepID string) (*StackDeploymentStep, error) {
7074
req, err := s.client.NewRequest("GET", fmt.Sprintf("stack-deployment-steps/%s", url.PathEscape(stackDeploymentStepID)), nil)
7175
if err != nil {
@@ -80,3 +84,13 @@ func (s stackDeploymentSteps) Read(ctx context.Context, stackDeploymentStepID st
8084

8185
return &step, nil
8286
}
87+
88+
// Advance advances the stack deployment step when in the "pending_operator" state.
89+
func (s stackDeploymentSteps) Advance(ctx context.Context, stackDeploymentStepID string) error {
90+
req, err := s.client.NewRequest("POST", fmt.Sprintf("stack-deployment-steps/%s/advance", url.PathEscape(stackDeploymentStepID)), nil)
91+
if err != nil {
92+
return err
93+
}
94+
95+
return req.Do(ctx, nil)
96+
}

stack_deployment_steps_integration_test.go

Lines changed: 101 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"
@@ -162,3 +163,103 @@ func TestStackDeploymentStepsRead(t *testing.T) {
162163
require.Error(t, err)
163164
})
164165
}
166+
167+
func TestStackDeploymentStepsAdvance(t *testing.T) {
168+
skipUnlessBeta(t)
169+
170+
client := testClient(t)
171+
ctx := context.Background()
172+
173+
orgTest, orgTestCleanup := createOrganization(t, client)
174+
t.Cleanup(orgTestCleanup)
175+
176+
oauthClient, cleanup := createOAuthClient(t, client, orgTest, nil)
177+
t.Cleanup(cleanup)
178+
179+
stack, err := client.Stacks.Create(ctx, StackCreateOptions{
180+
Project: orgTest.DefaultProject,
181+
Name: "testing-stack",
182+
VCSRepo: &StackVCSRepoOptions{
183+
Identifier: "hashicorp-guides/pet-nulls-stack",
184+
OAuthTokenID: oauthClient.OAuthTokens[0].ID,
185+
Branch: "main",
186+
},
187+
})
188+
require.NoError(t, err)
189+
require.NotNil(t, stack)
190+
191+
stackUpdated, err := client.Stacks.UpdateConfiguration(ctx, stack.ID)
192+
require.NoError(t, err)
193+
require.NotNil(t, stackUpdated)
194+
195+
stack = pollStackDeployments(t, ctx, client, stackUpdated.ID)
196+
require.NotNil(t, stack.LatestStackConfiguration)
197+
198+
stackDeploymentGroups, err := client.StackDeploymentGroups.List(ctx, stack.LatestStackConfiguration.ID, nil)
199+
require.NoError(t, err)
200+
require.NotEmpty(t, stackDeploymentGroups)
201+
202+
sdg := stackDeploymentGroups.Items[0]
203+
204+
stackDeploymentRuns, err := client.StackDeploymentRuns.List(ctx, sdg.ID, nil)
205+
require.NoError(t, err)
206+
require.NotEmpty(t, stackDeploymentRuns)
207+
208+
sdr := stackDeploymentRuns.Items[0]
209+
210+
steps, err := client.StackDeploymentSteps.List(ctx, sdr.ID, nil)
211+
assert.NoError(t, err)
212+
assert.NotEmpty(t, steps)
213+
214+
step := steps.Items[0]
215+
step = pollStackDeploymentStepStatus(t, ctx, client, step.ID, "pending_operator")
216+
require.NotNil(t, step)
217+
218+
t.Run("Advance with valid ID", func(t *testing.T) {
219+
err := client.StackDeploymentSteps.Advance(ctx, step.ID)
220+
assert.NoError(t, err)
221+
222+
// Verify that the step status has changed to "completed"
223+
sds, err := client.StackDeploymentSteps.Read(ctx, step.ID)
224+
assert.NoError(t, err)
225+
assert.Equal(t, "completed", sds.Status)
226+
})
227+
228+
t.Run("Advance with invalid ID", func(t *testing.T) {
229+
err := client.StackDeploymentSteps.Advance(ctx, "")
230+
require.Error(t, err)
231+
})
232+
}
233+
234+
func pollStackDeploymentStepStatus(t *testing.T, ctx context.Context, client *Client, stackDeploymentStepID, status string) (deploymentStep *StackDeploymentStep) {
235+
// pollStackDeploymentStepStatus will poll the given stack deployment step until its status changes or the deadline is reached.
236+
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute))
237+
defer cancel()
238+
239+
deadline, _ := ctx.Deadline()
240+
t.Logf("Polling stack deployment step %q for change in status with deadline of %s", stackDeploymentStepID, deadline)
241+
242+
ticker := time.NewTicker(2 * time.Second)
243+
defer ticker.Stop()
244+
245+
var err error
246+
for finished := false; !finished; {
247+
t.Log("...")
248+
select {
249+
case <-ctx.Done():
250+
t.Fatalf("Stack deployment step %s did not have status %q at deadline", stackDeploymentStepID, status)
251+
case <-ticker.C:
252+
deploymentStep, err = client.StackDeploymentSteps.Read(ctx, stackDeploymentStepID)
253+
if err != nil {
254+
t.Fatalf("Failed to read stack deployment step %s: %s", stackDeploymentStepID, err)
255+
}
256+
257+
t.Logf("Stack deployment step %s had status %q", deploymentStep.ID, deploymentStep.Status)
258+
if deploymentStep.Status == status {
259+
finished = true
260+
}
261+
}
262+
}
263+
264+
return
265+
}

0 commit comments

Comments
 (0)