chore: make has_ai_task fields on workspace builds and template versions nullable (#18403)

The fields must be nullable because there’s a period of time between
inserting a row into the database and finishing the “plan” provisioner
job when the final value of the field is unknown.
This commit is contained in:
Hugo Dutka
2025-06-17 16:08:34 +02:00
committed by GitHub
parent d6df1f23a9
commit ebc769f328
7 changed files with 27 additions and 10 deletions

View File

@ -1555,7 +1555,7 @@ CREATE TABLE template_versions (
message character varying(1048576) DEFAULT ''::character varying NOT NULL,
archived boolean DEFAULT false NOT NULL,
source_example_id text,
has_ai_task boolean DEFAULT false NOT NULL
has_ai_task boolean
);
COMMENT ON COLUMN template_versions.external_auth_providers IS 'IDs of External auth providers for a specific template version';
@ -2084,7 +2084,7 @@ CREATE TABLE workspace_builds (
daily_cost integer DEFAULT 0 NOT NULL,
max_deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
template_version_preset_id uuid,
has_ai_task boolean DEFAULT false NOT NULL,
has_ai_task boolean,
ai_tasks_sidebar_app_id uuid
);

View File

@ -0,0 +1,4 @@
ALTER TABLE template_versions ALTER COLUMN has_ai_task SET DEFAULT false;
ALTER TABLE template_versions ALTER COLUMN has_ai_task SET NOT NULL;
ALTER TABLE workspace_builds ALTER COLUMN has_ai_task SET DEFAULT false;
ALTER TABLE workspace_builds ALTER COLUMN has_ai_task SET NOT NULL;

View File

@ -0,0 +1,7 @@
-- The fields must be nullable because there's a period of time between
-- inserting a row into the database and finishing the "plan" provisioner job
-- when the final value of the field is unknown.
ALTER TABLE template_versions ALTER COLUMN has_ai_task DROP DEFAULT;
ALTER TABLE template_versions ALTER COLUMN has_ai_task DROP NOT NULL;
ALTER TABLE workspace_builds ALTER COLUMN has_ai_task DROP DEFAULT;
ALTER TABLE workspace_builds ALTER COLUMN has_ai_task DROP NOT NULL;

View File

@ -3358,7 +3358,7 @@ type TemplateVersion struct {
Message string `db:"message" json:"message"`
Archived bool `db:"archived" json:"archived"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
CreatedByAvatarURL string `db:"created_by_avatar_url" json:"created_by_avatar_url"`
CreatedByUsername string `db:"created_by_username" json:"created_by_username"`
CreatedByName string `db:"created_by_name" json:"created_by_name"`
@ -3435,7 +3435,7 @@ type TemplateVersionTable struct {
Message string `db:"message" json:"message"`
Archived bool `db:"archived" json:"archived"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
}
type TemplateVersionTerraformValue struct {
@ -3850,7 +3850,7 @@ type WorkspaceBuild struct {
DailyCost int32 `db:"daily_cost" json:"daily_cost"`
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"`
InitiatorByAvatarUrl string `db:"initiator_by_avatar_url" json:"initiator_by_avatar_url"`
InitiatorByUsername string `db:"initiator_by_username" json:"initiator_by_username"`
@ -3881,7 +3881,7 @@ type WorkspaceBuildTable struct {
DailyCost int32 `db:"daily_cost" json:"daily_cost"`
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
AITasksSidebarAppID uuid.NullUUID `db:"ai_tasks_sidebar_app_id" json:"ai_tasks_sidebar_app_id"`
}

View File

@ -11828,7 +11828,7 @@ type InsertTemplateVersionParams struct {
JobID uuid.UUID `db:"job_id" json:"job_id"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
}
func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) error {
@ -17546,7 +17546,7 @@ type InsertWorkspaceBuildParams struct {
MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
Reason BuildReason `db:"reason" json:"reason"`
TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
HasAITask bool `db:"has_ai_task" json:"has_ai_task"`
HasAITask sql.NullBool `db:"has_ai_task" json:"has_ai_task"`
}
func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) error {

View File

@ -1732,7 +1732,10 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
},
// appease the exhaustruct linter
// TODO: set this to whether the template version defines a `coder_ai_task` tf resource
HasAITask: false,
HasAITask: sql.NullBool{
Bool: false,
Valid: false,
},
})
if err != nil {
if database.IsUniqueViolation(err, database.UniqueTemplateVersionsTemplateIDNameKey) {

View File

@ -427,7 +427,10 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object
},
// appease the exhaustruct linter
// TODO: set this to whether the build included a `coder_ai_task` tf resource
HasAITask: false,
HasAITask: sql.NullBool{
Bool: false,
Valid: false,
},
})
if err != nil {
code := http.StatusInternalServerError