Skip to content

Commit

Permalink
Merge pull request #469 from hashicorp/gs/add-pre-plan
Browse files Browse the repository at this point in the history
Update Run and Workspace Run Tasks for Pre-plan Run Tasks
  • Loading branch information
glennsarti committed Aug 1, 2022
2 parents 6b5c37f + f602464 commit ce0f146
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,8 @@
## Enhancements

* Adds new run creation attributes: `allow-empty-apply`, `terraform-version`, `plan-only` by @sebasslash [#482](https://github.com/hashicorp/go-tfe/pull/447)
* Adds additional Task Stage and Run Statuses for Pre-plan run tasks by @glennsarti [#469](https://github.com/hashicorp/go-tfe/pull/469)
* Adds `stage` field to the create and update methods for Workspace Run Tasks by @glennsarti [#469](https://github.com/hashicorp/go-tfe/pull/469)

# v1.6.0

Expand Down
21 changes: 15 additions & 6 deletions run.go
Expand Up @@ -51,26 +51,30 @@ type RunStatus string
// List all available run statuses.
const (
RunApplied RunStatus = "applied"
RunApplyQueued RunStatus = "apply_queued"
RunApplying RunStatus = "applying"
RunApplyQueued RunStatus = "apply_queued"
RunCanceled RunStatus = "canceled"
RunConfirmed RunStatus = "confirmed"
RunCostEstimated RunStatus = "cost_estimated"
RunCostEstimating RunStatus = "cost_estimating"
RunDiscarded RunStatus = "discarded"
RunErrored RunStatus = "errored"
RunFetching RunStatus = "fetching"
RunFetchingCompleted RunStatus = "fetching_completed"
RunPending RunStatus = "pending"
RunPlanQueued RunStatus = "plan_queued"
RunPlanned RunStatus = "planned"
RunPlannedAndFinished RunStatus = "planned_and_finished"
RunPlanning RunStatus = "planning"
RunPlanQueued RunStatus = "plan_queued"
RunPolicyChecked RunStatus = "policy_checked"
RunPolicyChecking RunStatus = "policy_checking"
RunPolicyOverride RunStatus = "policy_override"
RunPolicySoftFailed RunStatus = "policy_soft_failed"
RunPostPlanRunning RunStatus = "post_plan_running"
RunPostPlanCompleted RunStatus = "post_plan_completed"
RunPostPlanRunning RunStatus = "post_plan_running"
RunPrePlanCompleted RunStatus = "pre_plan_completed"
RunPrePlanRunning RunStatus = "pre_plan_running"
RunQueuing RunStatus = "queuing"
)

// RunSource represents a source type of a run.
Expand Down Expand Up @@ -157,8 +161,8 @@ type RunPermissions struct {
// RunStatusTimestamps holds the timestamps for individual run statuses.
type RunStatusTimestamps struct {
AppliedAt time.Time `jsonapi:"attr,applied-at,rfc3339"`
ApplyQueuedAt time.Time `jsonapi:"attr,apply-queued-at,rfc3339"`
ApplyingAt time.Time `jsonapi:"attr,applying-at,rfc3339"`
ApplyQueuedAt time.Time `jsonapi:"attr,apply-queued-at,rfc3339"`
CanceledAt time.Time `jsonapi:"attr,canceled-at,rfc3339"`
ConfirmedAt time.Time `jsonapi:"attr,confirmed-at,rfc3339"`
CostEstimatedAt time.Time `jsonapi:"attr,cost-estimated-at,rfc3339"`
Expand All @@ -168,13 +172,18 @@ type RunStatusTimestamps struct {
FetchedAt time.Time `jsonapi:"attr,fetched-at,rfc3339"`
FetchingAt time.Time `jsonapi:"attr,fetching-at,rfc3339"`
ForceCanceledAt time.Time `jsonapi:"attr,force-canceled-at,rfc3339"`
PlanQueueableAt time.Time `jsonapi:"attr,plan-queueable-at,rfc3339"`
PlanQueuedAt time.Time `jsonapi:"attr,plan-queued-at,rfc3339"`
PlannedAndFinishedAt time.Time `jsonapi:"attr,planned-and-finished-at,rfc3339"`
PlannedAt time.Time `jsonapi:"attr,planned-at,rfc3339"`
PlanningAt time.Time `jsonapi:"attr,planning-at,rfc3339"`
PlanQueueableAt time.Time `jsonapi:"attr,plan-queueable-at,rfc3339"`
PlanQueuedAt time.Time `jsonapi:"attr,plan-queued-at,rfc3339"`
PolicyCheckedAt time.Time `jsonapi:"attr,policy-checked-at,rfc3339"`
PolicySoftFailedAt time.Time `jsonapi:"attr,policy-soft-failed-at,rfc3339"`
PostPlanCompletedAt time.Time `jsonapi:"attr,post-plan-completed-at,rfc3339"`
PostPlanRunningAt time.Time `jsonapi:"attr,post-plan-running-at,rfc3339"`
PrePlanCompletedAt time.Time `jsonapi:"attr,pre-plan-completed-at,rfc3339"`
PrePlanRunningAt time.Time `jsonapi:"attr,pre-plan-running-at,rfc3339"`
QueuingAt time.Time `jsonapi:"attr,queuing-at,rfc3339"`
}

// RunIncludeOpt represents the available options for include query params.
Expand Down
1 change: 1 addition & 0 deletions task_stages.go
Expand Up @@ -29,6 +29,7 @@ type taskStages struct {
type Stage string

const (
PrePlan Stage = "pre_plan"
PostPlan Stage = "post_plan"
)

Expand Down
4 changes: 4 additions & 0 deletions workspace_run_task.go
Expand Up @@ -37,6 +37,7 @@ type workspaceRunTasks struct {
type WorkspaceRunTask struct {
ID string `jsonapi:"primary,workspace-tasks"`
EnforcementLevel TaskEnforcementLevel `jsonapi:"attr,enforcement-level"`
Stage Stage `jsonapi:"attr,stage"`

RunTask *RunTask `jsonapi:"relation,task"`
Workspace *Workspace `jsonapi:"relation,workspace"`
Expand All @@ -60,12 +61,15 @@ type WorkspaceRunTaskCreateOptions struct {
EnforcementLevel TaskEnforcementLevel `jsonapi:"attr,enforcement-level"`
// Required: The run task to attach to the workspace
RunTask *RunTask `jsonapi:"relation,task"`
// Optional: The stage to run the task in. This is currently in BETA
Stage *Stage `jsonapi:"attr,stage,omitempty"`
}

// WorkspaceRunTaskUpdateOptions represent the set of options for updating a workspace run task.
type WorkspaceRunTaskUpdateOptions struct {
Type string `jsonapi:"primary,workspace-tasks"`
EnforcementLevel TaskEnforcementLevel `jsonapi:"attr,enforcement-level,omitempty"`
Stage *Stage `jsonapi:"attr,stage,omitempty"` // The stage to run the task in. This is currently in BETA
}

// List all run tasks attached to a workspace
Expand Down
77 changes: 77 additions & 0 deletions workspace_run_task_integration_test.go
Expand Up @@ -46,6 +46,47 @@ func TestWorkspaceRunTasksCreate(t *testing.T) {
})
}

func TestWorkspaceRunTasksCreateBeta(t *testing.T) {
// Once Pre-Plan Tasks are generally available, this can replace the above TestWorkspaceRunTasksCreate
skipIfBeta(t)
skipIfFreeOnly(t)

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

runTaskTest, runTaskTestCleanup := createRunTask(t, client, orgTest)
defer runTaskTestCleanup()

wkspaceTest, wkspaceTestCleanup := createWorkspace(t, client, orgTest)
defer wkspaceTestCleanup()

t.Run("attach run task to workspace", func(t *testing.T) {
s := PrePlan
wr, err := client.WorkspaceRunTasks.Create(ctx, wkspaceTest.ID, WorkspaceRunTaskCreateOptions{
EnforcementLevel: Mandatory,
Stage: &s,
RunTask: runTaskTest,
})

require.NoError(t, err)
defer func() {
client.WorkspaceRunTasks.Delete(ctx, wkspaceTest.ID, wr.ID)
}()

assert.NotEmpty(t, wr.ID)
assert.Equal(t, wr.EnforcementLevel, Mandatory)
assert.Equal(t, wr.Stage, s)

t.Run("ensure run task is deserialized properly", func(t *testing.T) {
assert.NotNil(t, wr.RunTask)
assert.NotEmpty(t, wr.RunTask.ID)
})
})
}

func TestWorkspaceRunTasksList(t *testing.T) {
skipIfFreeOnly(t)

Expand Down Expand Up @@ -146,6 +187,42 @@ func TestWorkspaceRunTasksUpdate(t *testing.T) {
})
}

func TestWorkspaceRunTasksUpdateBeta(t *testing.T) {
// Once Pre-Plan Tasks are generally available, this can replace the above TestWorkspaceRunTasksUpdate
skipIfBeta(t)
skipIfFreeOnly(t)

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

wkspaceTest, wkspaceTestCleanup := createWorkspace(t, client, orgTest)
defer wkspaceTestCleanup()

runTaskTest, runTaskTestCleanup := createRunTask(t, client, orgTest)
defer runTaskTestCleanup()

wrTaskTest, wrTaskTestCleanup := createWorkspaceRunTask(t, client, wkspaceTest, runTaskTest)
defer wrTaskTestCleanup()

t.Run("update task", func(t *testing.T) {
stage := PrePlan
wr, err := client.WorkspaceRunTasks.Update(ctx, wkspaceTest.ID, wrTaskTest.ID, WorkspaceRunTaskUpdateOptions{
EnforcementLevel: Mandatory,
Stage: &stage,
})
require.NoError(t, err)

wr, err = client.WorkspaceRunTasks.Read(ctx, wkspaceTest.ID, wr.ID)
require.NoError(t, err)

assert.Equal(t, wr.EnforcementLevel, Mandatory)
assert.Equal(t, wr.Stage, PrePlan)
})
}

func TestWorkspaceRunTasksDelete(t *testing.T) {
skipIfFreeOnly(t)

Expand Down

0 comments on commit ce0f146

Please sign in to comment.