Skip to content

chore: remove dynamic-parameters experiment #18290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Jun 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/testdata/coder_list_--output_json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"template_allow_user_cancel_workspace_jobs": false,
"template_active_version_id": "============[version ID]============",
"template_require_active_version": false,
"template_use_classic_parameter_flow": false,
"template_use_classic_parameter_flow": true,
"latest_build": {
"id": "========[workspace build ID]========",
"created_at": "====[timestamp]=====",
Expand Down
3 changes: 0 additions & 3 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -1153,9 +1153,6 @@ func New(options *Options) *API {
})

r.Group(func(r chi.Router) {
r.Use(
httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentDynamicParameters),
)
r.Route("/dynamic-parameters", func(r chi.Router) {
r.Post("/evaluate", api.templateVersionDynamicParametersEvaluate)
r.Get("/", api.templateVersionDynamicParametersWebsocket)
Expand Down
1 change: 1 addition & 0 deletions coderd/database/dbmem/dbmem.go
Original file line number Diff line number Diff line change
Expand Up @@ -9345,6 +9345,7 @@ func (q *FakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTempl
AllowUserAutostart: true,
AllowUserAutostop: true,
MaxPortSharingLevel: arg.MaxPortSharingLevel,
UseClassicParameterFlow: true,
}
q.templates = append(q.templates, template)
return nil
Expand Down
2 changes: 1 addition & 1 deletion coderd/database/dump.sql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE templates ALTER COLUMN use_classic_parameter_flow SET DEFAULT false;

UPDATE templates SET use_classic_parameter_flow = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- All templates should opt out of dynamic parameters by default.
ALTER TABLE templates ALTER COLUMN use_classic_parameter_flow SET DEFAULT true;

UPDATE templates SET use_classic_parameter_flow = true
13 changes: 7 additions & 6 deletions coderd/parameters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ import (
func TestDynamicParametersOwnerSSHPublicKey(t *testing.T) {
t.Parallel()

cfg := coderdtest.DeploymentValues(t)
cfg.Experiments = []string{string(codersdk.ExperimentDynamicParameters)}
ownerClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, DeploymentValues: cfg})
ownerClient := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, ownerClient)
templateAdmin, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())

Expand Down Expand Up @@ -354,14 +352,11 @@ type dynamicParamsTest struct {
}

func setupDynamicParamsTest(t *testing.T, args setupDynamicParamsTestParams) dynamicParamsTest {
cfg := coderdtest.DeploymentValues(t)
cfg.Experiments = []string{string(codersdk.ExperimentDynamicParameters)}
ownerClient, _, api := coderdtest.NewWithAPI(t, &coderdtest.Options{
Database: args.db,
Pubsub: args.ps,
IncludeProvisionerDaemon: true,
ProvisionerDaemonVersion: args.provisionerDaemonVersion,
DeploymentValues: cfg,
})

owner := coderdtest.CreateFirstUser(t, ownerClient)
Expand All @@ -384,6 +379,12 @@ func setupDynamicParamsTest(t *testing.T, args setupDynamicParamsTestParams) dyn
coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdmin, version.ID)
tpl := coderdtest.CreateTemplate(t, templateAdmin, owner.OrganizationID, version.ID)

var err error
tpl, err = templateAdmin.UpdateTemplateMeta(t.Context(), tpl.ID, codersdk.UpdateTemplateMeta{
UseClassicParameterFlow: ptr.Ref(false),
})
require.NoError(t, err)

ctx := testutil.Context(t, testutil.WaitShort)
stream, err := templateAdmin.TemplateVersionDynamicParameters(ctx, version.ID)
if args.expectWebsocketError {
Expand Down
2 changes: 1 addition & 1 deletion coderd/templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1548,7 +1548,7 @@ func TestPatchTemplateMeta(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
require.False(t, template.UseClassicParameterFlow, "default is false")
require.True(t, template.UseClassicParameterFlow, "default is true")

bTrue := true
bFalse := false
Expand Down
16 changes: 2 additions & 14 deletions coderd/workspacebuilds.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,20 +384,8 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
builder = builder.State(createBuild.ProvisionerState)
}

// Only defer to dynamic parameters if the experiment is enabled.
if api.Experiments.Enabled(codersdk.ExperimentDynamicParameters) {
if createBuild.EnableDynamicParameters != nil {
// Explicit opt-in
builder = builder.DynamicParameters(*createBuild.EnableDynamicParameters)
}
} else {
if createBuild.EnableDynamicParameters != nil {
api.Logger.Warn(ctx, "ignoring dynamic parameter field sent by request, the experiment is not enabled",
slog.F("field", *createBuild.EnableDynamicParameters),
slog.F("user", apiKey.UserID.String()),
slog.F("transition", string(createBuild.Transition)),
)
}
if createBuild.EnableDynamicParameters != nil {
builder = builder.DynamicParameters(*createBuild.EnableDynamicParameters)
}

workspaceBuild, provisionerJob, provisionerDaemons, err = builder.Build(
Expand Down
2 changes: 1 addition & 1 deletion coderd/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ func createWorkspace(
builder = builder.MarkPrebuiltWorkspaceClaim()
}

if req.EnableDynamicParameters && api.Experiments.Enabled(codersdk.ExperimentDynamicParameters) {
if req.EnableDynamicParameters {
builder = builder.DynamicParameters(req.EnableDynamicParameters)
}

Expand Down
21 changes: 10 additions & 11 deletions coderd/wsbuilder/wsbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1042,8 +1042,15 @@ func (b *Builder) checkRunningBuild() error {
}

func (b *Builder) usingDynamicParameters() bool {
if !b.experiments.Enabled(codersdk.ExperimentDynamicParameters) {
// Experiment required
if b.dynamicParametersEnabled != nil {
return *b.dynamicParametersEnabled
}

tpl, err := b.getTemplate()
if err != nil {
return false // Let another part of the code get this error
}
if tpl.UseClassicParameterFlow {
return false
}

Expand All @@ -1056,15 +1063,7 @@ func (b *Builder) usingDynamicParameters() bool {
return false
}

if b.dynamicParametersEnabled != nil {
return *b.dynamicParametersEnabled
}

tpl, err := b.getTemplate()
if err != nil {
return false // Let another part of the code get this error
}
return !tpl.UseClassicParameterFlow
return true
}

func ProvisionerVersionSupportsDynamicParameters(version string) bool {
Expand Down
9 changes: 5 additions & 4 deletions coderd/wsbuilder/wsbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -894,10 +894,11 @@ func withTemplate(mTx *dbmock.MockStore) {
mTx.EXPECT().GetTemplateByID(gomock.Any(), templateID).
Times(1).
Return(database.Template{
ID: templateID,
OrganizationID: orgID,
Provisioner: database.ProvisionerTypeTerraform,
ActiveVersionID: activeVersionID,
ID: templateID,
OrganizationID: orgID,
Provisioner: database.ProvisionerTypeTerraform,
ActiveVersionID: activeVersionID,
UseClassicParameterFlow: true,
}, nil)
}

Expand Down
1 change: 0 additions & 1 deletion codersdk/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3356,7 +3356,6 @@ const (
ExperimentNotifications Experiment = "notifications" // Sends notifications via SMTP and webhooks following certain events.
ExperimentWorkspaceUsage Experiment = "workspace-usage" // Enables the new workspace usage tracking.
ExperimentWebPush Experiment = "web-push" // Enables web push notifications through the browser.
ExperimentDynamicParameters Experiment = "dynamic-parameters" // Enables dynamic parameters when creating a workspace.
ExperimentWorkspacePrebuilds Experiment = "workspace-prebuilds" // Enables the new workspace prebuilds feature.
ExperimentAgenticChat Experiment = "agentic-chat" // Enables the new agentic AI chat feature.
ExperimentAITasks Experiment = "ai-tasks" // Enables the new AI tasks feature.
Expand Down
1 change: 0 additions & 1 deletion docs/reference/api/schemas.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions enterprise/coderd/parameters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@ import (
func TestDynamicParametersOwnerGroups(t *testing.T) {
t.Parallel()

cfg := coderdtest.DeploymentValues(t)
cfg.Experiments = []string{string(codersdk.ExperimentDynamicParameters)}
ownerClient, owner := coderdenttest.New(t,
&coderdenttest.Options{
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
},
Options: &coderdtest.Options{IncludeProvisionerDaemon: true, DeploymentValues: cfg},
Options: &coderdtest.Options{IncludeProvisionerDaemon: true},
},
)
templateAdmin, templateAdminUser := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())
Expand Down
8 changes: 7 additions & 1 deletion enterprise/coderd/workspaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ func TestWorkspaceTemplateParamsChange(t *testing.T) {

logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: false})
dv := coderdtest.DeploymentValues(t)
dv.Experiments = []string{string(codersdk.ExperimentDynamicParameters)}

client, owner := coderdenttest.New(t, &coderdenttest.Options{
Options: &coderdtest.Options{
Logger: &logger,
Expand Down Expand Up @@ -1736,6 +1736,12 @@ func TestWorkspaceTemplateParamsChange(t *testing.T) {
require.NoError(t, err, "failed to create template version")
coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdmin, tv.ID)
tpl := coderdtest.CreateTemplate(t, templateAdmin, owner.OrganizationID, tv.ID)

// Set to dynamic params
tpl, err = client.UpdateTemplateMeta(ctx, tpl.ID, codersdk.UpdateTemplateMeta{
UseClassicParameterFlow: ptr.Ref(false),
})
require.NoError(t, err, "failed to update template meta")
require.False(t, tpl.UseClassicParameterFlow, "template to use dynamic parameters")

// When: we create a workspace build using the above template but with
Expand Down
1 change: 0 additions & 1 deletion site/src/api/typesGenerated.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,8 @@ export const useDynamicParametersOptOut = ({
const localStorageKey = optOutKey(templateId);
const storedOptOutString = localStorage.getItem(localStorageKey);

let optedOut: boolean;

if (storedOptOutString !== null) {
optedOut = storedOptOutString === "true";
} else {
optedOut = Boolean(templateUsesClassicParameters);
}
// Since the dynamic-parameters experiment was removed, always use classic parameters
const optedOut = true;

return {
templateId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
SettingsIcon,
TrashIcon,
} from "lucide-react";
import { useDashboard } from "modules/dashboard/useDashboard";
import { useDynamicParametersOptOut } from "modules/workspaces/DynamicParameter/useDynamicParametersOptOut";
import { type FC, useEffect, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "react-query";
Expand All @@ -43,14 +42,12 @@ export const WorkspaceMoreActions: FC<WorkspaceMoreActionsProps> = ({
disabled,
}) => {
const queryClient = useQueryClient();
const { experiments } = useDashboard();
const isDynamicParametersEnabled = experiments.includes("dynamic-parameters");

const optOutQuery = useDynamicParametersOptOut({
templateId: workspace.template_id,
templateUsesClassicParameters:
workspace.template_use_classic_parameter_flow,
enabled: isDynamicParametersEnabled,
enabled: true,
});

// Permissions
Expand Down Expand Up @@ -154,7 +151,7 @@ export const WorkspaceMoreActions: FC<WorkspaceMoreActionsProps> = ({
onClose={() => setIsDownloadDialogOpen(false)}
/>

{!isDynamicParametersEnabled || optOutQuery.data?.optedOut ? (
{optOutQuery.data?.optedOut ? (
<UpdateBuildParametersDialog
missedParameters={
changeVersionMutation.error instanceof MissingBuildParameters
Expand Down
16 changes: 4 additions & 12 deletions site/src/modules/workspaces/WorkspaceUpdateDialogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
import { Loader } from "components/Loader/Loader";
import { MemoizedInlineMarkdown } from "components/Markdown/Markdown";
import { useDashboard } from "modules/dashboard/useDashboard";
import { useDynamicParametersOptOut } from "modules/workspaces/DynamicParameter/useDynamicParametersOptOut";
import { UpdateBuildParametersDialog } from "modules/workspaces/WorkspaceMoreActions/UpdateBuildParametersDialog";
import { UpdateBuildParametersDialogExperimental } from "modules/workspaces/WorkspaceMoreActions/UpdateBuildParametersDialogExperimental";
Expand Down Expand Up @@ -56,14 +55,11 @@ export const useWorkspaceUpdate = ({
setIsConfirmingUpdate(true);
};

const { experiments } = useDashboard();
const isDynamicParametersEnabled = experiments.includes("dynamic-parameters");

const optOutQuery = useDynamicParametersOptOut({
templateId: workspace.template_id,
templateUsesClassicParameters:
workspace.template_use_classic_parameter_flow,
enabled: isDynamicParametersEnabled,
enabled: true,
});

const confirmUpdate = (buildParameters: WorkspaceBuildParameter[] = []) => {
Expand Down Expand Up @@ -164,13 +160,11 @@ const MissingBuildParametersDialog: FC<MissingBuildParametersDialogProps> = ({
error,
...dialogProps
}) => {
const { experiments } = useDashboard();
const isDynamicParametersEnabled = experiments.includes("dynamic-parameters");
const optOutQuery = useDynamicParametersOptOut({
templateId: workspace.template_id,
templateUsesClassicParameters:
workspace.template_use_classic_parameter_flow,
enabled: isDynamicParametersEnabled,
enabled: true,
});

const missedParameters =
Expand All @@ -182,13 +176,11 @@ const MissingBuildParametersDialog: FC<MissingBuildParametersDialogProps> = ({
if (optOutQuery.isError) {
return <ErrorAlert error={optOutQuery.error} />;
}
if (isDynamicParametersEnabled && !optOutQuery.data) {
if (!optOutQuery.data) {
return <Loader />;
}

// If dynamic parameters experiment is not enabled, or if opted out, use classic dialog
const shouldUseClassicDialog =
!isDynamicParametersEnabled || optOutQuery.data?.optedOut;
const shouldUseClassicDialog = optOutQuery.data?.optedOut;

return shouldUseClassicDialog ? (
<UpdateBuildParametersDialog
Expand Down
Loading
Loading