From a1dbd758bc682c1db03dda7c62c5853380e34294 Mon Sep 17 00:00:00 2001 From: Jeremy Ruppel Date: Mon, 11 May 2026 09:48:55 -0400 Subject: [PATCH] feat: add template builder deployment config and telemetry types (#25082) --- cli/testdata/coder_server_--help.golden | 9 ++++++ cli/testdata/server-config.yaml.golden | 9 ++++++ coderd/apidoc/docs.go | 14 +++++++++ coderd/apidoc/swagger.json | 14 +++++++++ coderd/coderd.go | 10 +++++++ coderd/telemetry/telemetry.go | 16 ++++++++++ codersdk/deployment.go | 29 +++++++++++++++++++ docs/reference/api/general.md | 4 +++ docs/reference/api/schemas.md | 25 ++++++++++++++++ docs/reference/cli/server.md | 21 ++++++++++++++ .../cli/testdata/coder_server_--help.golden | 9 ++++++ site/src/api/typesGenerated.ts | 7 +++++ 12 files changed, 167 insertions(+) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index e2bc1d1762..ee26cb9d66 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -847,6 +847,15 @@ when required by your organization's security policy. Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product. +TEMPLATE BUILDER OPTIONS: + --disable-template-builder bool, $CODER_DISABLE_TEMPLATE_BUILDER + Disable the template builder feature for guided template creation. + When disabled, all /api/v2/templatebuilder/* endpoints return 404. + + --template-builder-registry-url string, $CODER_TEMPLATE_BUILDER_REGISTRY_URL (default: https://registry.coder.com) + The base URL of the module registry used by the template builder for + module source paths. + USER QUIET HOURS SCHEDULE OPTIONS: Allow users to set quiet hours schedules each day for workspaces to avoid workspaces stopping during the day due to template scheduling. diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index ce49e08e68..0779b5a9d1 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -911,3 +911,12 @@ retention: # build are always retained. Set to 0 to disable automatic deletion. # (default: 7d, type: duration) workspace_agent_logs: 168h0m0s +templateBuilder: + # Disable the template builder feature for guided template creation. When + # disabled, all /api/v2/templatebuilder/* endpoints return 404. + # (default: , type: bool) + disabled: false + # The base URL of the module registry used by the template builder for module + # source paths. + # (default: https://registry.coder.com, type: string) + registryURL: https://registry.coder.com diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index dcc169292e..ffd0f9b1ce 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -17820,6 +17820,9 @@ const docTemplate = `{ "telemetry": { "$ref": "#/definitions/codersdk.TelemetryConfig" }, + "template_builder": { + "$ref": "#/definitions/codersdk.TemplateBuilderConfig" + }, "terms_of_service_url": { "type": "string" }, @@ -22480,6 +22483,17 @@ const docTemplate = `{ "$ref": "#/definitions/codersdk.TransitionStats" } }, + "codersdk.TemplateBuilderConfig": { + "type": "object", + "properties": { + "disabled": { + "type": "boolean" + }, + "registry_url": { + "type": "string" + } + } + }, "codersdk.TemplateExample": { "type": "object", "properties": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 2bbe7f6de9..83c1b1b577 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -16179,6 +16179,9 @@ "telemetry": { "$ref": "#/definitions/codersdk.TelemetryConfig" }, + "template_builder": { + "$ref": "#/definitions/codersdk.TemplateBuilderConfig" + }, "terms_of_service_url": { "type": "string" }, @@ -20668,6 +20671,17 @@ "$ref": "#/definitions/codersdk.TransitionStats" } }, + "codersdk.TemplateBuilderConfig": { + "type": "object", + "properties": { + "disabled": { + "type": "boolean" + }, + "registry_url": { + "type": "string" + } + } + }, "codersdk.TemplateExample": { "type": "object", "properties": { diff --git a/coderd/coderd.go b/coderd/coderd.go index 3db9bea92d..6af641bfcf 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -1541,6 +1541,16 @@ func New(options *Options) *API { }) }) }) + if !api.DeploymentValues.TemplateBuilder.Disabled.Value() { + r.Route("/templatebuilder", func(r chi.Router) { + r.Use( + apiKeyMiddleware, + ) + // Endpoints added by DEVEX-275 (bases), DEVEX-276 + // (modules), DEVEX-277/279 (compose). + }) + } + r.Route("/users", func(r chi.Router) { r.Get("/first", api.firstUser) r.Post("/first", api.postFirstUser) diff --git a/coderd/telemetry/telemetry.go b/coderd/telemetry/telemetry.go index 6ff96a6d37..7feeda1531 100644 --- a/coderd/telemetry/telemetry.go +++ b/coderd/telemetry/telemetry.go @@ -1610,6 +1610,7 @@ type Snapshot struct { ChatModelConfigs []ChatModelConfig `json:"chat_model_configs"` ChatDiffStatusSummary *ChatDiffStatusSummary `json:"chat_diff_status_summary"` UserSecretsSummary *UserSecretsSummary `json:"user_secrets_summary"` + TemplateBuilderSessions []TemplateBuilderSession `json:"template_builder_sessions"` } // Deployment contains information about the host running Coder. @@ -2497,6 +2498,21 @@ type UserSecretsSummary struct { SecretsPerUserP90 int64 `json:"secrets_per_user_p90"` } +// TemplateBuilderSession tracks a single event in the template builder +// wizard. Two events are emitted per session: one on wizard entry and +// one on compose completion. User-supplied variable values are never +// included. +type TemplateBuilderSession struct { + ID uuid.UUID `json:"id"` + EventType string `json:"event_type"` + UserID uuid.UUID `json:"user_id"` + BaseTemplateID string `json:"base_template_id,omitempty"` + ModuleIDs []string `json:"module_ids,omitempty"` + DurationSeconds float64 `json:"duration_seconds,omitempty"` + Success bool `json:"success,omitempty"` + CreatedAt time.Time `json:"created_at"` +} + func ConvertAIBridgeInterceptionsSummary(endTime time.Time, provider, model, client string, summary database.CalculateAIBridgeInterceptionsTelemetrySummaryRow) AIBridgeInterceptionsSummary { return AIBridgeInterceptionsSummary{ ID: uuid.New(), diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 9ece07b531..72eb37350a 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -645,6 +645,7 @@ type DeploymentValues struct { HideAITasks serpent.Bool `json:"hide_ai_tasks,omitempty" typescript:",notnull"` AI AIConfig `json:"ai,omitempty"` StatsCollection StatsCollectionConfig `json:"stats_collection,omitempty" typescript:",notnull"` + TemplateBuilder TemplateBuilderConfig `json:"template_builder,omitempty"` Config serpent.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"` WriteConfig serpent.Bool `json:"write_config,omitempty" typescript:",notnull"` @@ -1462,6 +1463,10 @@ func (c *DeploymentValues) Options() serpent.OptionSet { Description: "Configure data retention policies for various database tables. Retention policies automatically purge old data to reduce database size and improve performance. Setting a retention duration to 0 disables automatic purging for that data type.", YAML: "retention", } + deploymentGroupTemplateBuilder = serpent.Group{ + Name: "Template Builder", + YAML: "templateBuilder", + } ) httpAddress := serpent.Option{ @@ -4059,6 +4064,25 @@ Write out the current server config as YAML to stdout.`, // used externally. Hidden: true, }, + { + Name: "Disable Template Builder", + Description: "Disable the template builder feature for guided template creation. When disabled, all /api/v2/templatebuilder/* endpoints return 404.", + Flag: "disable-template-builder", + Env: "CODER_DISABLE_TEMPLATE_BUILDER", + Value: &c.TemplateBuilder.Disabled, + Group: &deploymentGroupTemplateBuilder, + YAML: "disabled", + }, + { + Name: "Template Builder Registry URL", + Description: "The base URL of the module registry used by the template builder for module source paths.", + Flag: "template-builder-registry-url", + Env: "CODER_TEMPLATE_BUILDER_REGISTRY_URL", + Value: &c.TemplateBuilder.RegistryURL, + Default: "https://registry.coder.com", + Group: &deploymentGroupTemplateBuilder, + YAML: "registryURL", + }, } return opts @@ -4168,6 +4192,11 @@ type AIConfig struct { Chat ChatConfig `json:"chat,omitempty" typescript:",notnull"` } +type TemplateBuilderConfig struct { + Disabled serpent.Bool `json:"disabled,omitempty"` + RegistryURL serpent.String `json:"registry_url,omitempty"` +} + type SupportConfig struct { Links serpent.Struct[[]LinkConfig] `json:"links" typescript:",notnull"` } diff --git a/docs/reference/api/general.md b/docs/reference/api/general.md index 48157d228e..d90eacc160 100644 --- a/docs/reference/api/general.md +++ b/docs/reference/api/general.md @@ -585,6 +585,10 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "user": {} } }, + "template_builder": { + "disabled": true, + "registry_url": "string" + }, "terms_of_service_url": "string", "tls": { "address": { diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index 0d5b3b2bb0..97807cfc21 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -5651,6 +5651,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "user": {} } }, + "template_builder": { + "disabled": true, + "registry_url": "string" + }, "terms_of_service_url": "string", "tls": { "address": { @@ -6243,6 +6247,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "user": {} } }, + "template_builder": { + "disabled": true, + "registry_url": "string" + }, "terms_of_service_url": "string", "tls": { "address": { @@ -6356,6 +6364,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o | `support` | [codersdk.SupportConfig](#codersdksupportconfig) | false | | | | `swagger` | [codersdk.SwaggerConfig](#codersdkswaggerconfig) | false | | | | `telemetry` | [codersdk.TelemetryConfig](#codersdktelemetryconfig) | false | | | +| `template_builder` | [codersdk.TemplateBuilderConfig](#codersdktemplatebuilderconfig) | false | | | | `terms_of_service_url` | string | false | | | | `tls` | [codersdk.TLSConfig](#codersdktlsconfig) | false | | | | `trace` | [codersdk.TraceConfig](#codersdktraceconfig) | false | | | @@ -11820,6 +11829,22 @@ Restarts will only happen on weekdays in this list on weeks which line up with W |------------------|------------------------------------------------------|----------|--------------|-------------| | `[any property]` | [codersdk.TransitionStats](#codersdktransitionstats) | false | | | +## codersdk.TemplateBuilderConfig + +```json +{ + "disabled": true, + "registry_url": "string" +} +``` + +### Properties + +| Name | Type | Required | Restrictions | Description | +|----------------|---------|----------|--------------|-------------| +| `disabled` | boolean | false | | | +| `registry_url` | string | false | | | + ## codersdk.TemplateExample ```json diff --git a/docs/reference/cli/server.md b/docs/reference/cli/server.md index 6350c5a836..ce8ddb1bd8 100644 --- a/docs/reference/cli/server.md +++ b/docs/reference/cli/server.md @@ -2046,3 +2046,24 @@ How long expired API keys are retained before being deleted. Keeping expired key | Default | 7d | How long workspace agent logs are retained. Logs from non-latest builds are deleted if the agent hasn't connected within this period. Logs from the latest build are always retained. Set to 0 to disable automatic deletion. + +### --disable-template-builder + +| | | +|-------------|----------------------------------------------| +| Type | bool | +| Environment | $CODER_DISABLE_TEMPLATE_BUILDER | +| YAML | templateBuilder.disabled | + +Disable the template builder feature for guided template creation. When disabled, all /api/v2/templatebuilder/* endpoints return 404. + +### --template-builder-registry-url + +| | | +|-------------|---------------------------------------------------| +| Type | string | +| Environment | $CODER_TEMPLATE_BUILDER_REGISTRY_URL | +| YAML | templateBuilder.registryURL | +| Default | https://registry.coder.com | + +The base URL of the module registry used by the template builder for module source paths. diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index 3702806593..8eb543f63a 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -848,6 +848,15 @@ when required by your organization's security policy. Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product. +TEMPLATE BUILDER OPTIONS: + --disable-template-builder bool, $CODER_DISABLE_TEMPLATE_BUILDER + Disable the template builder feature for guided template creation. + When disabled, all /api/v2/templatebuilder/* endpoints return 404. + + --template-builder-registry-url string, $CODER_TEMPLATE_BUILDER_REGISTRY_URL (default: https://registry.coder.com) + The base URL of the module registry used by the template builder for + module source paths. + USER QUIET HOURS SCHEDULE OPTIONS: Allow users to set quiet hours schedules each day for workspaces to avoid workspaces stopping during the day due to template scheduling. diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index bacba8a19d..b1720054d6 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -3761,6 +3761,7 @@ export interface DeploymentValues { readonly hide_ai_tasks?: boolean; readonly ai?: AIConfig; readonly stats_collection?: StatsCollectionConfig; + readonly template_builder?: TemplateBuilderConfig; readonly config?: string; readonly write_config?: boolean; /** @@ -7593,6 +7594,12 @@ export type TemplateBuildTimeStats = Record< TransitionStats >; +// From codersdk/deployment.go +export interface TemplateBuilderConfig { + readonly disabled?: boolean; + readonly registry_url?: string; +} + // From codersdk/insights.go /** * Enums define the display name of the builtin app reported.