From 2369a080e44a535c1413c542a0c20be4cd59a055 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 22 Apr 2026 10:10:12 -0400 Subject: [PATCH] fix(ci,api-server): fix control-plane build context and migration parameter mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change control-plane Docker build context from ./components/ambient-control-plane to ./components in both CI workflows (Dockerfile copies sibling dirs) - Replace GORM AutoMigrate in agentSchemaExpansionMigration with explicit ALTER TABLE statements to avoid PreferSimpleProtocol parameter binding mismatch - Replace GORM FirstOrCreate in role seed migrations with raw INSERT ON CONFLICT to avoid primary key inference causing parameter count errors 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .github/workflows/components-build-deploy.yml | 2 +- .github/workflows/prod-release-deploy.yaml | 2 +- .../plugins/agents/migration.go | 44 +++++++++---------- .../plugins/credentials/migration.go | 27 +++--------- .../plugins/roles/migration.go | 25 ++--------- 5 files changed, 32 insertions(+), 68 deletions(-) diff --git a/.github/workflows/components-build-deploy.yml b/.github/workflows/components-build-deploy.yml index 4e16edebf..d143ffe6d 100755 --- a/.github/workflows/components-build-deploy.yml +++ b/.github/workflows/components-build-deploy.yml @@ -59,7 +59,7 @@ jobs: {"name":"state-sync","context":"./components/runners/state-sync","image":"quay.io/ambient_code/vteam_state_sync","dockerfile":"./components/runners/state-sync/Dockerfile"}, {"name":"public-api","context":"./components/public-api","image":"quay.io/ambient_code/vteam_public_api","dockerfile":"./components/public-api/Dockerfile"}, {"name":"ambient-api-server","context":"./components/ambient-api-server","image":"quay.io/ambient_code/vteam_api_server","dockerfile":"./components/ambient-api-server/Dockerfile"}, - {"name":"ambient-control-plane","context":"./components/ambient-control-plane","image":"quay.io/ambient_code/vteam_control_plane","dockerfile":"./components/ambient-control-plane/Dockerfile"}, + {"name":"ambient-control-plane","context":"./components","image":"quay.io/ambient_code/vteam_control_plane","dockerfile":"./components/ambient-control-plane/Dockerfile"}, {"name":"ambient-mcp","context":"./components/ambient-mcp","image":"quay.io/ambient_code/vteam_mcp","dockerfile":"./components/ambient-mcp/Dockerfile"} ]' diff --git a/.github/workflows/prod-release-deploy.yaml b/.github/workflows/prod-release-deploy.yaml index 70b7ed19e..2c13b5384 100755 --- a/.github/workflows/prod-release-deploy.yaml +++ b/.github/workflows/prod-release-deploy.yaml @@ -237,7 +237,7 @@ jobs: {"name":"state-sync","context":"./components/runners/state-sync","image":"quay.io/ambient_code/vteam_state_sync","dockerfile":"./components/runners/state-sync/Dockerfile"}, {"name":"public-api","context":"./components/public-api","image":"quay.io/ambient_code/vteam_public_api","dockerfile":"./components/public-api/Dockerfile"}, {"name":"ambient-api-server","context":"./components/ambient-api-server","image":"quay.io/ambient_code/vteam_api_server","dockerfile":"./components/ambient-api-server/Dockerfile"}, - {"name":"ambient-control-plane","context":"./components/ambient-control-plane","image":"quay.io/ambient_code/vteam_control_plane","dockerfile":"./components/ambient-control-plane/Dockerfile"}, + {"name":"ambient-control-plane","context":"./components","image":"quay.io/ambient_code/vteam_control_plane","dockerfile":"./components/ambient-control-plane/Dockerfile"}, {"name":"ambient-mcp","context":"./components/ambient-mcp","image":"quay.io/ambient_code/vteam_mcp","dockerfile":"./components/ambient-mcp/Dockerfile"} ]' diff --git a/components/ambient-api-server/plugins/agents/migration.go b/components/ambient-api-server/plugins/agents/migration.go index 1f22cb4c4..247d2259c 100644 --- a/components/ambient-api-server/plugins/agents/migration.go +++ b/components/ambient-api-server/plugins/agents/migration.go @@ -42,32 +42,30 @@ func migration() *gormigrate.Migration { } func agentSchemaExpansionMigration() *gormigrate.Migration { - type Agent struct { - db.Model - ProjectId string - ParentAgentId *string `gorm:"index"` - OwnerUserId *string - Name string - DisplayName *string - Description *string - Prompt *string `gorm:"type:text"` - RepoUrl *string - WorkflowId *string - LlmModel *string - LlmTemperature *float64 - LlmMaxTokens *int32 - BotAccountName *string - ResourceOverrides *string - EnvironmentVariables *string - Labels *string - Annotations *string - CurrentSessionId *string - } - return &gormigrate.Migration{ ID: "202604181000", Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&Agent{}) + stmts := []string{ + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS parent_agent_id TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS owner_user_id TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS display_name TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS description TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS repo_url TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS workflow_id TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS llm_model TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS llm_temperature DOUBLE PRECISION`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS llm_max_tokens INTEGER`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS bot_account_name TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS resource_overrides TEXT`, + `ALTER TABLE agents ADD COLUMN IF NOT EXISTS environment_variables TEXT`, + `CREATE INDEX IF NOT EXISTS idx_agents_parent_agent_id ON agents(parent_agent_id)`, + } + for _, s := range stmts { + if err := tx.Exec(s).Error; err != nil { + return err + } + } + return nil }, Rollback: func(tx *gorm.DB) error { cols := []string{ diff --git a/components/ambient-api-server/plugins/credentials/migration.go b/components/ambient-api-server/plugins/credentials/migration.go index 72a7bb12d..94245a006 100644 --- a/components/ambient-api-server/plugins/credentials/migration.go +++ b/components/ambient-api-server/plugins/credentials/migration.go @@ -59,15 +59,6 @@ func removeCredentialReaderRoleMigration() *gormigrate.Migration { } func rolesMigration() *gormigrate.Migration { - type roleRow struct { - ID string - Name string - DisplayName string - Description string - Permissions string - BuiltIn bool - } - seed := []struct { name string displayName string @@ -96,18 +87,10 @@ func rolesMigration() *gormigrate.Migration { if err != nil { return err } - var row roleRow - if err := tx.Table("roles"). - Where("name = ?", r.name). - Attrs(roleRow{ - ID: api.NewID(), - Name: r.name, - DisplayName: r.displayName, - Description: r.description, - Permissions: string(permsJSON), - BuiltIn: true, - }). - FirstOrCreate(&row).Error; err != nil { + if err := tx.Exec( + `INSERT INTO roles (id, name, display_name, description, permissions, built_in) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT (name) DO NOTHING`, + api.NewID(), r.name, r.displayName, r.description, string(permsJSON), true, + ).Error; err != nil { return err } } @@ -118,7 +101,7 @@ func rolesMigration() *gormigrate.Migration { for i, r := range seed { names[i] = r.name } - return tx.Table("roles").Where("name IN ?", names).Delete(&roleRow{}).Error + return tx.Exec("DELETE FROM roles WHERE name IN ?", names).Error }, } } diff --git a/components/ambient-api-server/plugins/roles/migration.go b/components/ambient-api-server/plugins/roles/migration.go index 699a0bf2c..3efc922d2 100644 --- a/components/ambient-api-server/plugins/roles/migration.go +++ b/components/ambient-api-server/plugins/roles/migration.go @@ -35,15 +35,6 @@ func migration() *gormigrate.Migration { } func seedBuiltInRoles(tx *gorm.DB) error { - type roleRow struct { - ID string - Name string - DisplayName string - Description string - Permissions string - BuiltIn bool - } - builtInRoles := []struct { name string displayName string @@ -105,18 +96,10 @@ func seedBuiltInRoles(tx *gorm.DB) error { if err != nil { return err } - var row roleRow - if err := tx.Table("roles"). - Where("name = ?", r.name). - Attrs(roleRow{ - ID: api.NewID(), - Name: r.name, - DisplayName: r.displayName, - Description: r.description, - Permissions: string(permsJSON), - BuiltIn: true, - }). - FirstOrCreate(&row).Error; err != nil { + if err := tx.Exec( + `INSERT INTO roles (id, name, display_name, description, permissions, built_in) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT (name) DO NOTHING`, + api.NewID(), r.name, r.displayName, r.description, string(permsJSON), true, + ).Error; err != nil { return err } }