Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 25af21b

Browse files
authored
feat!: remove has_ai_task and the task build reasons (#29085)
Drops the `has_ai_task` column from `template_versions` and `workspace_builds` (with its index and view projections) and removes the three task build reasons (`task_auto_pause`, `task_manual_pause`, `task_resume`) from the `build_reason` enum. Existing rows are remapped before the enum swap: automatic pauses become `autostop`, manual pauses and resumes become `initiator`, and `workspace_build_orchestrations.child_reason` follows the same mapping. The query filters, provisionerdserver flag writes, and audit ignore entries for the column go with it. **Migration cost:** recreating `build_reason` rewrites `workspace_builds`. `TestMigration000593TaskBuildReasonRewriteTiming` seeds 1,000 workspaces, 100,000 builds (30,000 with task reasons) and 5,000 orchestrations and asserts the migration stays under a two-minute bound; locally it takes about 0.7 to 1.0 s. The test is skipped under `-short`. **Breaking change:** the down migration re-adds `has_ai_task` as `false` and restores the enum values; remapped reasons keep their new values. **Review changes:** the migration test now asserts only the row remaps (schema and enum introspection removed per review); renumbered from 000592 to 000593. **Stack context:** Coder Tasks removal stack (CODAGT-642): #28743 frontend → #28788 CLI → #28789 API → #28790 provisioner → #29084 notifications → **#29085 build reasons** → #29086 tables → #28750 permissions. The last four PRs replace the single data-drop migration that used to live in #28750; each carries one concern and its own migration number. > Created by Xum (AI agent) on behalf of @ibetitsmike.
1 parent f809776 commit 25af21b

18 files changed

Lines changed: 516 additions & 179 deletions

coderd/database/dbauthz/dbauthz.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8335,7 +8335,7 @@ func (q *querier) UpdateTemplateVersionExternalAuthProvidersByJobID(ctx context.
83358335
}
83368336

83378337
func (q *querier) UpdateTemplateVersionFlagsByJobID(ctx context.Context, arg database.UpdateTemplateVersionFlagsByJobIDParams) error {
8338-
// An actor is allowed to update the template version ai task and external agent flag if they are authorized to update the template.
8338+
// An actor is allowed to update the template version external agent flag if they are authorized to update the template.
83398339
tv, err := q.db.GetTemplateVersionByJobID(ctx, arg.JobID)
83408340
if err != nil {
83418341
return err

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2906,7 +2906,7 @@ func (s *MethodTestSuite) TestTemplate() {
29062906
s.Run("UpdateTemplateVersionFlagsByJobID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
29072907
t := testutil.Fake(s.T(), faker, database.Template{})
29082908
tv := testutil.Fake(s.T(), faker, database.TemplateVersion{TemplateID: uuid.NullUUID{UUID: t.ID, Valid: true}})
2909-
arg := database.UpdateTemplateVersionFlagsByJobIDParams{JobID: tv.JobID, HasAITask: sql.NullBool{Bool: true, Valid: true}, HasExternalAgent: sql.NullBool{Bool: true, Valid: true}}
2909+
arg := database.UpdateTemplateVersionFlagsByJobIDParams{JobID: tv.JobID, HasExternalAgent: sql.NullBool{Bool: true, Valid: true}}
29102910
dbm.EXPECT().GetTemplateVersionByJobID(gomock.Any(), tv.JobID).Return(tv, nil).AnyTimes()
29112911
dbm.EXPECT().GetTemplateByID(gomock.Any(), t.ID).Return(t, nil).AnyTimes()
29122912
dbm.EXPECT().UpdateTemplateVersionFlagsByJobID(gomock.Any(), arg).Return(nil).AnyTimes()
@@ -4453,7 +4453,6 @@ func (s *MethodTestSuite) TestWorkspace() {
44534453
dbm.EXPECT().UpdateWorkspaceBuildFlagsByID(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
44544454
check.Args(database.UpdateWorkspaceBuildFlagsByIDParams{
44554455
ID: b.ID,
4456-
HasAITask: sql.NullBool{Bool: true, Valid: true},
44574456
HasExternalAgent: sql.NullBool{Bool: true, Valid: true},
44584457
UpdatedAt: b.UpdatedAt,
44594458
}).Asserts(w, policy.ActionUpdate)

coderd/database/dbfake/dbfake.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,6 @@ func (b WorkspaceBuildBuilder) doInTX() WorkspaceResponse {
297297
b.seed.ID = uuid.New()
298298
b.seed.JobID = jobID
299299

300-
if b.taskAppID != uuid.Nil {
301-
b.seed.HasAITask = sql.NullBool{
302-
Bool: true,
303-
Valid: true,
304-
}
305-
}
306-
307300
resp := WorkspaceResponse{
308301
AgentToken: b.agentToken,
309302
Agents: make([]database.WorkspaceAgent, 0),

coderd/database/dbgen/dbgen.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,6 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
936936

937937
buildID := takeFirst(orig.ID, uuid.New())
938938
jobID := takeFirst(orig.JobID, uuid.New())
939-
hasAITask := takeFirst(orig.HasAITask, sql.NullBool{})
940939
hasExternalAgent := takeFirst(orig.HasExternalAgent, sql.NullBool{})
941940
var build database.WorkspaceBuild
942941
err := db.InTx(func(db database.Store) error {
@@ -971,10 +970,9 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
971970
require.NoError(t, err)
972971
}
973972

974-
if hasAITask.Valid || hasExternalAgent.Valid {
973+
if hasExternalAgent.Valid {
975974
require.NoError(t, db.UpdateWorkspaceBuildFlagsByID(genCtx, database.UpdateWorkspaceBuildFlagsByIDParams{
976975
ID: buildID,
977-
HasAITask: hasAITask,
978976
HasExternalAgent: hasExternalAgent,
979977
UpdatedAt: dbtime.Now(),
980978
}))
@@ -1592,7 +1590,6 @@ func ExternalAuthLink(t testing.TB, db database.Store, orig database.ExternalAut
15921590

15931591
func TemplateVersion(t testing.TB, db database.Store, orig database.TemplateVersion) database.TemplateVersion {
15941592
var version database.TemplateVersion
1595-
hasAITask := takeFirst(orig.HasAITask, sql.NullBool{})
15961593
hasExternalAgent := takeFirst(orig.HasExternalAgent, sql.NullBool{})
15971594
jobID := takeFirst(orig.JobID, uuid.New())
15981595
err := db.InTx(func(db database.Store) error {
@@ -1614,10 +1611,9 @@ func TemplateVersion(t testing.TB, db database.Store, orig database.TemplateVers
16141611
return err
16151612
}
16161613

1617-
if hasAITask.Valid || hasExternalAgent.Valid {
1614+
if hasExternalAgent.Valid {
16181615
require.NoError(t, db.UpdateTemplateVersionFlagsByJobID(genCtx, database.UpdateTemplateVersionFlagsByJobIDParams{
16191616
JobID: jobID,
1620-
HasAITask: hasAITask,
16211617
HasExternalAgent: hasExternalAgent,
16221618
UpdatedAt: dbtime.Now(),
16231619
}))

coderd/database/dump.sql

Lines changed: 1 addition & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
-- Drop views before modifying underlying tables and columns.
2+
DROP VIEW IF EXISTS template_version_with_user;
3+
DROP VIEW IF EXISTS workspace_build_with_user;
4+
5+
-- Recreate has_ai_task columns and index. The dropped values are not
6+
-- recoverable, so backfill false to satisfy older migrations that restore
7+
-- NOT NULL on the way further down.
8+
ALTER TABLE template_versions ADD COLUMN has_ai_task boolean DEFAULT false;
9+
ALTER TABLE template_versions ALTER COLUMN has_ai_task DROP DEFAULT;
10+
CREATE INDEX idx_template_versions_has_ai_task ON template_versions USING btree (has_ai_task);
11+
ALTER TABLE workspace_builds ADD COLUMN has_ai_task boolean DEFAULT false;
12+
ALTER TABLE workspace_builds ALTER COLUMN has_ai_task DROP DEFAULT;
13+
14+
-- Recreate build_reason enum with task values.
15+
ALTER TYPE build_reason RENAME TO build_reason_old;
16+
17+
CREATE TYPE build_reason AS ENUM (
18+
'initiator',
19+
'autostart',
20+
'autostop',
21+
'dormancy',
22+
'failedstop',
23+
'autodelete',
24+
'dashboard',
25+
'cli',
26+
'ssh_connection',
27+
'vscode_connection',
28+
'jetbrains_connection',
29+
'task_auto_pause',
30+
'task_manual_pause',
31+
'task_resume'
32+
);
33+
34+
ALTER TABLE workspace_builds ALTER COLUMN reason DROP DEFAULT;
35+
ALTER TABLE workspace_builds ALTER COLUMN reason TYPE build_reason USING (reason::text::build_reason);
36+
ALTER TABLE workspace_builds ALTER COLUMN reason SET DEFAULT 'initiator'::build_reason;
37+
38+
ALTER TABLE workspace_build_orchestrations ALTER COLUMN child_reason TYPE build_reason USING (child_reason::text::build_reason);
39+
40+
DROP TYPE build_reason_old;
41+
42+
-- Recreate views.
43+
CREATE VIEW template_version_with_user AS
44+
SELECT template_versions.id,
45+
template_versions.template_id,
46+
template_versions.organization_id,
47+
template_versions.created_at,
48+
template_versions.updated_at,
49+
template_versions.name,
50+
template_versions.readme,
51+
template_versions.job_id,
52+
template_versions.created_by,
53+
template_versions.external_auth_providers,
54+
template_versions.message,
55+
template_versions.archived,
56+
template_versions.source_example_id,
57+
template_versions.has_ai_task,
58+
template_versions.has_external_agent,
59+
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
60+
COALESCE(visible_users.username, ''::text) AS created_by_username,
61+
COALESCE(visible_users.name, ''::text) AS created_by_name
62+
FROM (template_versions
63+
LEFT JOIN visible_users ON ((template_versions.created_by = visible_users.id)));
64+
65+
COMMENT ON VIEW template_version_with_user IS 'Joins in the username + avatar url of the created by user.';
66+
67+
CREATE VIEW workspace_build_with_user AS
68+
SELECT workspace_builds.id,
69+
workspace_builds.created_at,
70+
workspace_builds.updated_at,
71+
workspace_builds.workspace_id,
72+
workspace_builds.template_version_id,
73+
workspace_builds.build_number,
74+
workspace_builds.transition,
75+
workspace_builds.initiator_id,
76+
workspace_builds.job_id,
77+
workspace_builds.deadline,
78+
workspace_builds.reason,
79+
workspace_builds.daily_cost,
80+
workspace_builds.max_deadline,
81+
workspace_builds.template_version_preset_id,
82+
workspace_builds.has_ai_task,
83+
workspace_builds.has_external_agent,
84+
workspace_builds.notified_autostop_deadline,
85+
COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
86+
COALESCE(visible_users.username, ''::text) AS initiator_by_username,
87+
COALESCE(visible_users.name, ''::text) AS initiator_by_name
88+
FROM (workspace_builds
89+
LEFT JOIN visible_users ON ((workspace_builds.initiator_id = visible_users.id)));
90+
91+
COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
DROP VIEW IF EXISTS template_version_with_user;
2+
DROP VIEW IF EXISTS workspace_build_with_user;
3+
4+
-- Drop has_ai_task index and columns.
5+
DROP INDEX IF EXISTS idx_template_versions_has_ai_task;
6+
ALTER TABLE template_versions DROP COLUMN IF EXISTS has_ai_task;
7+
ALTER TABLE workspace_builds DROP COLUMN IF EXISTS has_ai_task;
8+
9+
-- Remove task-related build reasons from build_reason enum. Automatic
10+
-- pauses stay system-attributed; manual pauses and resumes were created by
11+
-- authenticated user requests, so they keep user attribution as initiator.
12+
UPDATE workspace_builds
13+
SET reason = 'autostop'
14+
WHERE reason::text = 'task_auto_pause';
15+
16+
UPDATE workspace_builds
17+
SET reason = 'initiator'
18+
WHERE reason::text IN ('task_manual_pause', 'task_resume');
19+
20+
UPDATE workspace_build_orchestrations
21+
SET child_reason = 'autostop'
22+
WHERE child_reason::text = 'task_auto_pause';
23+
24+
UPDATE workspace_build_orchestrations
25+
SET child_reason = 'initiator'
26+
WHERE child_reason::text IN ('task_manual_pause', 'task_resume');
27+
28+
ALTER TYPE build_reason RENAME TO build_reason_old;
29+
30+
CREATE TYPE build_reason AS ENUM (
31+
'initiator',
32+
'autostart',
33+
'autostop',
34+
'dormancy',
35+
'failedstop',
36+
'autodelete',
37+
'dashboard',
38+
'cli',
39+
'ssh_connection',
40+
'vscode_connection',
41+
'jetbrains_connection'
42+
);
43+
44+
ALTER TABLE workspace_builds ALTER COLUMN reason DROP DEFAULT;
45+
ALTER TABLE workspace_builds ALTER COLUMN reason TYPE build_reason USING (reason::text::build_reason);
46+
ALTER TABLE workspace_builds ALTER COLUMN reason SET DEFAULT 'initiator'::build_reason;
47+
48+
ALTER TABLE workspace_build_orchestrations ALTER COLUMN child_reason TYPE build_reason USING (child_reason::text::build_reason);
49+
50+
DROP TYPE build_reason_old;
51+
52+
-- Recreate views without task columns.
53+
CREATE VIEW template_version_with_user AS
54+
SELECT template_versions.id,
55+
template_versions.template_id,
56+
template_versions.organization_id,
57+
template_versions.created_at,
58+
template_versions.updated_at,
59+
template_versions.name,
60+
template_versions.readme,
61+
template_versions.job_id,
62+
template_versions.created_by,
63+
template_versions.external_auth_providers,
64+
template_versions.message,
65+
template_versions.archived,
66+
template_versions.source_example_id,
67+
template_versions.has_external_agent,
68+
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
69+
COALESCE(visible_users.username, ''::text) AS created_by_username,
70+
COALESCE(visible_users.name, ''::text) AS created_by_name
71+
FROM (template_versions
72+
LEFT JOIN visible_users ON ((template_versions.created_by = visible_users.id)));
73+
74+
COMMENT ON VIEW template_version_with_user IS 'Joins in the username + avatar url of the created by user.';
75+
76+
CREATE VIEW workspace_build_with_user AS
77+
SELECT workspace_builds.id,
78+
workspace_builds.created_at,
79+
workspace_builds.updated_at,
80+
workspace_builds.workspace_id,
81+
workspace_builds.template_version_id,
82+
workspace_builds.build_number,
83+
workspace_builds.transition,
84+
workspace_builds.initiator_id,
85+
workspace_builds.job_id,
86+
workspace_builds.deadline,
87+
workspace_builds.reason,
88+
workspace_builds.daily_cost,
89+
workspace_builds.max_deadline,
90+
workspace_builds.template_version_preset_id,
91+
workspace_builds.has_external_agent,
92+
workspace_builds.notified_autostop_deadline,
93+
COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
94+
COALESCE(visible_users.username, ''::text) AS initiator_by_username,
95+
COALESCE(visible_users.name, ''::text) AS initiator_by_name
96+
FROM (workspace_builds
97+
LEFT JOIN visible_users ON ((workspace_builds.initiator_id = visible_users.id)));
98+
99+
COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';

0 commit comments

Comments
 (0)