Skip to content

Commit 289b989

Browse files
authored
Add reason field for workspace builds (coder#2438)
* add reason field for workspace build * add the reason field to FE via API * update BuildReasonMember to BuildReasonInitiator * add unit tests * add more unit tests * add error for unknown transition * fix lint * add documentation * fix unit tests * fix generated types * remove nested transaction * rename migration file
1 parent 7dcfea1 commit 289b989

15 files changed

+111
-17
lines changed

coderd/autobuild/executor/lifecycle_executor.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa
209209
}
210210
provisionerJobID := uuid.New()
211211
now := database.Now()
212+
213+
var buildReason database.BuildReason
214+
switch trans {
215+
case database.WorkspaceTransitionStart:
216+
buildReason = database.BuildReasonAutostart
217+
case database.WorkspaceTransitionStop:
218+
buildReason = database.BuildReasonAutostop
219+
default:
220+
return xerrors.Errorf("Unsupported transition: %q", trans)
221+
}
222+
212223
newProvisionerJob, err := store.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
213224
ID: provisionerJobID,
214225
CreatedAt: now,
@@ -236,6 +247,7 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa
236247
InitiatorID: workspace.OwnerID,
237248
Transition: trans,
238249
JobID: newProvisionerJob.ID,
250+
Reason: buildReason,
239251
})
240252
if err != nil {
241253
return xerrors.Errorf("insert workspace build: %w", err)

coderd/autobuild/executor/lifecycle_executor_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ func TestExecutorAutostartOK(t *testing.T) {
5151
assert.Len(t, stats.Transitions, 1)
5252
assert.Contains(t, stats.Transitions, workspace.ID)
5353
assert.Equal(t, database.WorkspaceTransitionStart, stats.Transitions[workspace.ID])
54+
55+
workspace = coderdtest.MustWorkspace(t, client, workspace.ID)
56+
assert.Equal(t, codersdk.BuildReasonAutostart, workspace.LatestBuild.Reason)
5457
}
5558

5659
func TestExecutorAutostartTemplateUpdated(t *testing.T) {
@@ -200,6 +203,9 @@ func TestExecutorAutostopOK(t *testing.T) {
200203
assert.Len(t, stats.Transitions, 1)
201204
assert.Contains(t, stats.Transitions, workspace.ID)
202205
assert.Equal(t, database.WorkspaceTransitionStop, stats.Transitions[workspace.ID])
206+
207+
workspace = coderdtest.MustWorkspace(t, client, workspace.ID)
208+
assert.Equal(t, codersdk.BuildReasonAutostop, workspace.LatestBuild.Reason)
203209
}
204210

205211
func TestExecutorAutostopExtend(t *testing.T) {

coderd/database/databasefake/databasefake.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,7 @@ func (q *fakeQuerier) InsertWorkspaceBuild(_ context.Context, arg database.Inser
17441744
JobID: arg.JobID,
17451745
ProvisionerState: arg.ProvisionerState,
17461746
Deadline: arg.Deadline,
1747+
Reason: arg.Reason,
17471748
}
17481749
q.workspaceBuilds = append(q.workspaceBuilds, workspaceBuild)
17491750
return workspaceBuild, nil

coderd/database/dump.sql

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ALTER TABLE ONLY workspace_builds
2+
DROP COLUMN IF EXISTS reason;
3+
4+
DROP TYPE build_reason;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CREATE TYPE build_reason AS ENUM ('initiator', 'autostart', 'autostop');
2+
3+
ALTER TABLE ONLY workspace_builds
4+
ADD COLUMN IF NOT EXISTS reason build_reason NOT NULL DEFAULT 'initiator';

coderd/database/models.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 22 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/workspacebuilds.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,11 @@ INSERT INTO
114114
initiator_id,
115115
job_id,
116116
provisioner_state,
117-
deadline
117+
deadline,
118+
reason
118119
)
119120
VALUES
120-
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING *;
121+
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING *;
121122

122123
-- name: UpdateWorkspaceBuildByID :exec
123124
UPDATE

coderd/workspacebuilds.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
439439
InitiatorID: apiKey.UserID,
440440
Transition: database.WorkspaceTransition(createBuild.Transition),
441441
JobID: provisionerJob.ID,
442+
Reason: database.BuildReasonInitiator,
442443
})
443444
if err != nil {
444445
return xerrors.Errorf("insert workspace build: %w", err)
@@ -639,6 +640,7 @@ func convertWorkspaceBuild(
639640
InitiatorUsername: initiatorName,
640641
Job: convertProvisionerJob(job),
641642
Deadline: workspaceBuild.Deadline,
643+
Reason: codersdk.BuildReason(workspaceBuild.Reason),
642644
}
643645
}
644646

coderd/workspaces.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
436436
JobID: provisionerJob.ID,
437437
BuildNumber: 1, // First build!
438438
Deadline: time.Time{}, // provisionerd will set this upon success
439+
Reason: database.BuildReasonInitiator,
439440
})
440441
if err != nil {
441442
return xerrors.Errorf("insert workspace build: %w", err)
@@ -806,6 +807,7 @@ func convertWorkspaces(ctx context.Context, db database.Store, workspaces []data
806807
ProvisionerState: workspaceBuild.ProvisionerState,
807808
JobID: workspaceBuild.JobID,
808809
Deadline: workspaceBuild.Deadline,
810+
Reason: workspaceBuild.Reason,
809811
}
810812
}
811813
templateByID := map[uuid.UUID]database.Template{}

coderd/workspaces_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ func TestWorkspace(t *testing.T) {
3333
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
3434
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
3535

36-
_, err := client.Workspace(context.Background(), workspace.ID)
36+
ws, err := client.Workspace(context.Background(), workspace.ID)
3737
require.NoError(t, err)
38+
require.Equal(t, user.UserID, ws.LatestBuild.InitiatorID)
39+
require.Equal(t, codersdk.BuildReasonInitiator, ws.LatestBuild.Reason)
3840
})
3941

4042
t.Run("Deleted", func(t *testing.T) {

codersdk/workspacebuilds.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ const (
1919
WorkspaceTransitionDelete WorkspaceTransition = "delete"
2020
)
2121

22+
type BuildReason string
23+
24+
const (
25+
// "initiator" is used when a workspace build is triggered by a user.
26+
// Combined with the initiator id/username, it indicates which user initiated the build.
27+
BuildReasonInitiator BuildReason = "initiator"
28+
// "autostart" is used when a build to start a workspace is triggered by Autostart.
29+
// The initiator id/username in this case is the workspace owner and can be ignored.
30+
BuildReasonAutostart BuildReason = "autostart"
31+
// "autostop" is used when a build to stop a workspace is triggered by Autostop.
32+
// The initiator id/username in this case is the workspace owner and can be ignored.
33+
BuildReasonAutostop BuildReason = "autostop"
34+
)
35+
2236
// WorkspaceBuild is an at-point representation of a workspace state.
2337
// BuildNumbers start at 1 and increase by 1 for each subsequent build
2438
type WorkspaceBuild struct {
@@ -37,6 +51,7 @@ type WorkspaceBuild struct {
3751
InitiatorUsername string `json:"initiator_name"`
3852
Job ProvisionerJob `json:"job"`
3953
Deadline time.Time `json:"deadline"`
54+
Reason BuildReason `db:"reason" json:"reason"`
4055
}
4156

4257
// WorkspaceBuild returns a single workspace build for a workspace.

0 commit comments

Comments
 (0)