From caac302ff3593cbc0f41f36135c034c68de067fd Mon Sep 17 00:00:00 2001 From: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> Date: Mon, 2 Jun 2025 20:59:41 +0000 Subject: [PATCH 1/7] update deployments experiments --- codersdk/deployment.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 696e6bda52682..c2150829930db 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -3340,9 +3340,6 @@ const ( // Add new experiments here! ExperimentExample Experiment = "example" // This isn't used for anything. ExperimentAutoFillParameters Experiment = "auto-fill-parameters" // This should not be taken out of experiments until we have redesigned the feature. - 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. From 18b7766a651c92c78df6da67a21dd17a59cc40be Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 01:56:38 +0000 Subject: [PATCH 2/7] fix: remove deprecated experiments and enable features by default - Remove ExperimentWorkspaceUsage, ExperimentNotifications, and ExperimentWebPush - Enable workspace usage tracking by default in telemetry and metrics - Enable web push notifications by default - Update all references throughout codebase including tests - Remove experiment checks that were causing compilation errors Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> --- cli/server.go | 33 ++++++++++++--------------------- cli/ssh_test.go | 22 +++++++++------------- cli/vscodessh_test.go | 2 +- coderd/agentapi/stats.go | 14 +++++--------- coderd/agentapi/stats_test.go | 4 +--- coderd/coderd.go | 2 +- coderd/telemetry/telemetry.go | 28 +++++++++------------------- coderd/webpush.go | 15 +++------------ coderd/webpush_test.go | 2 +- coderd/workspaces.go | 6 +----- coderd/workspaces_test.go | 2 +- 11 files changed, 44 insertions(+), 86 deletions(-) diff --git a/cli/server.go b/cli/server.go index 62b430cf22781..1378946853245 100644 --- a/cli/server.go +++ b/cli/server.go @@ -259,8 +259,8 @@ func enablePrometheus( afterCtx(ctx, closeInsightsMetricsCollector) if vals.Prometheus.CollectAgentStats { - experiments := coderd.ReadExperiments(options.Logger, options.DeploymentValues.Experiments.Value()) - closeAgentStatsFunc, err := prometheusmetrics.AgentStats(ctx, logger, options.PrometheusRegistry, options.Database, time.Now(), 0, options.DeploymentValues.Prometheus.AggregateAgentStatsBy.Value(), experiments.Enabled(codersdk.ExperimentWorkspaceUsage)) + + closeAgentStatsFunc, err := prometheusmetrics.AgentStats(ctx, logger, options.PrometheusRegistry, options.Database, time.Now(), 0, options.DeploymentValues.Prometheus.AggregateAgentStatsBy.Value(), true) if err != nil { return nil, xerrors.Errorf("register agent stats prometheus metric: %w", err) } @@ -814,27 +814,18 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. } // Manage push notifications. - experiments := coderd.ReadExperiments(options.Logger, options.DeploymentValues.Experiments.Value()) - if experiments.Enabled(codersdk.ExperimentWebPush) { - if !strings.HasPrefix(options.AccessURL.String(), "https://") { - options.Logger.Warn(ctx, "access URL is not HTTPS, so web push notifications may not work on some browsers", slog.F("access_url", options.AccessURL.String())) - } - webpusher, err := webpush.New(ctx, ptr.Ref(options.Logger.Named("webpush")), options.Database, options.AccessURL.String()) - if err != nil { - options.Logger.Error(ctx, "failed to create web push dispatcher", slog.Error(err)) - options.Logger.Warn(ctx, "web push notifications will not work until the VAPID keys are regenerated") - webpusher = &webpush.NoopWebpusher{ - Msg: "Web Push notifications are disabled due to a system error. Please contact your Coder administrator.", - } - } - options.WebPushDispatcher = webpusher - } else { - options.WebPushDispatcher = &webpush.NoopWebpusher{ - // Users will likely not see this message as the endpoints return 404 - // if not enabled. Just in case... - Msg: "Web Push notifications are an experimental feature and are disabled by default. Enable the 'web-push' experiment to use this feature.", + if !strings.HasPrefix(options.AccessURL.String(), "https://") { + options.Logger.Warn(ctx, "access URL is not HTTPS, so web push notifications may not work on some browsers", slog.F("access_url", options.AccessURL.String())) + } + webpusher, err := webpush.New(ctx, ptr.Ref(options.Logger.Named("webpush")), options.Database, options.AccessURL.String()) + if err != nil { + options.Logger.Error(ctx, "failed to create web push dispatcher", slog.Error(err)) + options.Logger.Warn(ctx, "web push notifications will not work until the VAPID keys are regenerated") + webpusher = &webpush.NoopWebpusher{ + Msg: "Web Push notifications are disabled due to a system error. Please contact your Coder administrator.", } } + options.WebPushDispatcher = webpusher githubOAuth2ConfigParams, err := getGithubOAuth2ConfigParams(ctx, options.Database, vals) if err != nil { diff --git a/cli/ssh_test.go b/cli/ssh_test.go index 8845200273697..f661b4e8ca521 100644 --- a/cli/ssh_test.go +++ b/cli/ssh_test.go @@ -1588,7 +1588,7 @@ func TestSSH(t *testing.T) { type testCase struct { name string - experiment bool + usageAppName string expectedCalls int expectedCountSSH int @@ -1596,46 +1596,44 @@ func TestSSH(t *testing.T) { expectedCountVscode int } tcs := []testCase{ - { - name: "NoExperiment", - }, + { name: "Empty", - experiment: true, + expectedCalls: 1, expectedCountSSH: 1, }, { name: "SSH", - experiment: true, + usageAppName: "ssh", expectedCalls: 1, expectedCountSSH: 1, }, { name: "Jetbrains", - experiment: true, + usageAppName: "jetbrains", expectedCalls: 1, expectedCountJetbrains: 1, }, { name: "Vscode", - experiment: true, + usageAppName: "vscode", expectedCalls: 1, expectedCountVscode: 1, }, { name: "InvalidDefaultsToSSH", - experiment: true, + usageAppName: "invalid", expectedCalls: 1, expectedCountSSH: 1, }, { name: "Disable", - experiment: true, + usageAppName: "disable", }, } @@ -1646,9 +1644,7 @@ func TestSSH(t *testing.T) { t.Parallel() dv := coderdtest.DeploymentValues(t) - if tc.experiment { - dv.Experiments = []string{string(codersdk.ExperimentWorkspaceUsage)} - } + batcher := &workspacestatstest.StatsBatcher{ LastStats: &agentproto.Stats{}, } diff --git a/cli/vscodessh_test.go b/cli/vscodessh_test.go index 70037664c407d..64ede93d98b1f 100644 --- a/cli/vscodessh_test.go +++ b/cli/vscodessh_test.go @@ -27,7 +27,7 @@ func TestVSCodeSSH(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitLong) dv := coderdtest.DeploymentValues(t) - dv.Experiments = []string{string(codersdk.ExperimentWorkspaceUsage)} + batcher := &workspacestatstest.StatsBatcher{ LastStats: &agentproto.Stats{}, } diff --git a/coderd/agentapi/stats.go b/coderd/agentapi/stats.go index 3108d17f75b14..53fda0ae6edcf 100644 --- a/coderd/agentapi/stats.go +++ b/coderd/agentapi/stats.go @@ -57,15 +57,11 @@ func (a *StatsAPI) UpdateStats(ctx context.Context, req *agentproto.UpdateStatsR slog.F("payload", req), ) - if a.Experiments.Enabled(codersdk.ExperimentWorkspaceUsage) { - // while the experiment is enabled we will not report - // session stats from the agent. This is because it is - // being handled by the CLI and the postWorkspaceUsage route. - req.Stats.SessionCountSsh = 0 - req.Stats.SessionCountJetbrains = 0 - req.Stats.SessionCountVscode = 0 - req.Stats.SessionCountReconnectingPty = 0 - } + // Session stats are now handled by the CLI and the postWorkspaceUsage route. + req.Stats.SessionCountSsh = 0 + req.Stats.SessionCountJetbrains = 0 + req.Stats.SessionCountVscode = 0 + req.Stats.SessionCountReconnectingPty = 0 err = a.StatsReporter.ReportAgentStats( ctx, diff --git a/coderd/agentapi/stats_test.go b/coderd/agentapi/stats_test.go index 3ebf99aa6bc4b..dd33b1a2296d2 100644 --- a/coderd/agentapi/stats_test.go +++ b/coderd/agentapi/stats_test.go @@ -478,9 +478,7 @@ func TestUpdateStates(t *testing.T) { TimeNowFn: func() time.Time { return now }, - Experiments: codersdk.Experiments{ - codersdk.ExperimentWorkspaceUsage, - }, + Experiments: codersdk.Experiments{}, } // Workspace gets fetched. diff --git a/coderd/coderd.go b/coderd/coderd.go index 0b8a13befde56..7a6228335a4dc 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -444,7 +444,7 @@ func New(options *Options) *API { TemplateBuildTimes: options.MetricsCacheRefreshInterval, DeploymentStats: options.AgentStatsRefreshInterval, }, - experiments.Enabled(codersdk.ExperimentWorkspaceUsage), + true, ) oauthConfigs := &httpmw.OAuth2Configs{ diff --git a/coderd/telemetry/telemetry.go b/coderd/telemetry/telemetry.go index 5fa5bb3fbbd04..66369dcc3ea61 100644 --- a/coderd/telemetry/telemetry.go +++ b/coderd/telemetry/telemetry.go @@ -14,7 +14,7 @@ import ( "os" "regexp" "runtime" - "slices" + "strconv" "strings" "sync" @@ -605,24 +605,14 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) { return nil }) eg.Go(func() error { - if r.options.DeploymentConfig != nil && slices.Contains(r.options.DeploymentConfig.Experiments, string(codersdk.ExperimentWorkspaceUsage)) { - agentStats, err := r.options.Database.GetWorkspaceAgentUsageStats(ctx, createdAfter) - if err != nil { - return xerrors.Errorf("get workspace agent stats: %w", err) - } - snapshot.WorkspaceAgentStats = make([]WorkspaceAgentStat, 0, len(agentStats)) - for _, stat := range agentStats { - snapshot.WorkspaceAgentStats = append(snapshot.WorkspaceAgentStats, ConvertWorkspaceAgentStat(database.GetWorkspaceAgentStatsRow(stat))) - } - } else { - agentStats, err := r.options.Database.GetWorkspaceAgentStats(ctx, createdAfter) - if err != nil { - return xerrors.Errorf("get workspace agent stats: %w", err) - } - snapshot.WorkspaceAgentStats = make([]WorkspaceAgentStat, 0, len(agentStats)) - for _, stat := range agentStats { - snapshot.WorkspaceAgentStats = append(snapshot.WorkspaceAgentStats, ConvertWorkspaceAgentStat(stat)) - } + // Use the usage stats version (previously behind ExperimentWorkspaceUsage) + agentStats, err := r.options.Database.GetWorkspaceAgentUsageStats(ctx, createdAfter) + if err != nil { + return xerrors.Errorf("get workspace agent stats: %w", err) + } + snapshot.WorkspaceAgentStats = make([]WorkspaceAgentStat, 0, len(agentStats)) + for _, stat := range agentStats { + snapshot.WorkspaceAgentStats = append(snapshot.WorkspaceAgentStats, ConvertWorkspaceAgentStat(database.GetWorkspaceAgentStatsRow(stat))) } return nil }) diff --git a/coderd/webpush.go b/coderd/webpush.go index 893401552df49..b5ec0ba3337c4 100644 --- a/coderd/webpush.go +++ b/coderd/webpush.go @@ -28,10 +28,7 @@ import ( func (api *API) postUserWebpushSubscription(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) - if !api.Experiments.Enabled(codersdk.ExperimentWebPush) { - httpapi.ResourceNotFound(rw) - return - } + var req codersdk.WebpushSubscription if !httpapi.Read(ctx, rw, r, &req) { @@ -77,10 +74,7 @@ func (api *API) deleteUserWebpushSubscription(rw http.ResponseWriter, r *http.Re ctx := r.Context() user := httpmw.UserParam(r) - if !api.Experiments.Enabled(codersdk.ExperimentWebPush) { - httpapi.ResourceNotFound(rw) - return - } + var req codersdk.DeleteWebpushSubscription if !httpapi.Read(ctx, rw, r, &req) { @@ -134,10 +128,7 @@ func (api *API) postUserPushNotificationTest(rw http.ResponseWriter, r *http.Req ctx := r.Context() user := httpmw.UserParam(r) - if !api.Experiments.Enabled(codersdk.ExperimentWebPush) { - httpapi.ResourceNotFound(rw) - return - } + // We need to authorize the user to send a push notification to themselves. if !api.Authorize(r, policy.ActionCreate, rbac.ResourceNotificationMessage.WithOwner(user.ID.String())) { diff --git a/coderd/webpush_test.go b/coderd/webpush_test.go index f41639b99e21d..7ccb91e647043 100644 --- a/coderd/webpush_test.go +++ b/coderd/webpush_test.go @@ -25,7 +25,7 @@ func TestWebpushSubscribeUnsubscribe(t *testing.T) { ctx := testutil.Context(t, testutil.WaitShort) dv := coderdtest.DeploymentValues(t) - dv.Experiments = []string{string(codersdk.ExperimentWebPush)} + client := coderdtest.New(t, &coderdtest.Options{ DeploymentValues: dv, }) diff --git a/coderd/workspaces.go b/coderd/workspaces.go index fe0c2d3f609a2..32541800cb785 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -1507,11 +1507,7 @@ func (api *API) postWorkspaceUsage(rw http.ResponseWriter, r *http.Request) { api.statsReporter.TrackUsage(workspace.ID) - if !api.Experiments.Enabled(codersdk.ExperimentWorkspaceUsage) { - // Continue previous behavior if the experiment is not enabled. - rw.WriteHeader(http.StatusNoContent) - return - } + if r.Body == http.NoBody { // Continue previous behavior if no body is present. diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index 018dd363bdee6..9ff65a8610654 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -4126,7 +4126,7 @@ func TestWorkspaceUsageTracking(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium) defer cancel() dv := coderdtest.DeploymentValues(t) - dv.Experiments = []string{string(codersdk.ExperimentWorkspaceUsage)} + client, db := coderdtest.NewWithDatabase(t, &coderdtest.Options{ DeploymentValues: dv, }) From fb6283f7c4ff788f477b0ab928592188197fb1f6 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 02:20:03 +0000 Subject: [PATCH 3/7] fix: remove extra empty line to fix linting error Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> --- cli/server.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/server.go b/cli/server.go index 846083555c4a2..f1a1378e41398 100644 --- a/cli/server.go +++ b/cli/server.go @@ -259,7 +259,6 @@ func enablePrometheus( afterCtx(ctx, closeInsightsMetricsCollector) if vals.Prometheus.CollectAgentStats { - closeAgentStatsFunc, err := prometheusmetrics.AgentStats(ctx, logger, options.PrometheusRegistry, options.Database, time.Now(), 0, options.DeploymentValues.Prometheus.AggregateAgentStatsBy.Value(), true) if err != nil { return nil, xerrors.Errorf("register agent stats prometheus metric: %w", err) From 8ce7d099048d2888c54bdc01fb73467f034885f0 Mon Sep 17 00:00:00 2001 From: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> Date: Tue, 10 Jun 2025 02:40:51 +0000 Subject: [PATCH 4/7] make --- cli/ssh_test.go | 15 +++++++-------- coderd/apidoc/docs.go | 11 +---------- coderd/apidoc/swagger.json | 11 +---------- coderd/telemetry/telemetry.go | 1 - coderd/webpush.go | 5 ----- coderd/workspaces.go | 2 -- coderd/workspaces_test.go | 2 +- docs/reference/api/schemas.md | 3 --- site/src/api/typesGenerated.ts | 5 +---- 9 files changed, 11 insertions(+), 44 deletions(-) diff --git a/cli/ssh_test.go b/cli/ssh_test.go index 8298b6f170384..a5149e8a180e4 100644 --- a/cli/ssh_test.go +++ b/cli/ssh_test.go @@ -1587,7 +1587,7 @@ func TestSSH(t *testing.T) { t.Parallel() type testCase struct { - name string + name string usageAppName string expectedCalls int @@ -1596,43 +1596,42 @@ func TestSSH(t *testing.T) { expectedCountVscode int } tcs := []testCase{ - { - name: "Empty", + name: "Empty", expectedCalls: 1, expectedCountSSH: 1, }, { - name: "SSH", + name: "SSH", usageAppName: "ssh", expectedCalls: 1, expectedCountSSH: 1, }, { - name: "Jetbrains", + name: "Jetbrains", usageAppName: "jetbrains", expectedCalls: 1, expectedCountJetbrains: 1, }, { - name: "Vscode", + name: "Vscode", usageAppName: "vscode", expectedCalls: 1, expectedCountVscode: 1, }, { - name: "InvalidDefaultsToSSH", + name: "InvalidDefaultsToSSH", usageAppName: "invalid", expectedCalls: 1, expectedCountSSH: 1, }, { - name: "Disable", + name: "Disable", usageAppName: "disable", }, diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index d11a0635d6f52..a8ea9441901d3 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -12742,9 +12742,6 @@ const docTemplate = `{ "enum": [ "example", "auto-fill-parameters", - "notifications", - "workspace-usage", - "web-push", "dynamic-parameters", "workspace-prebuilds", "agentic-chat", @@ -12756,17 +12753,11 @@ const docTemplate = `{ "ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.", "ExperimentDynamicParameters": "Enables dynamic parameters when creating a workspace.", "ExperimentExample": "This isn't used for anything.", - "ExperimentNotifications": "Sends notifications via SMTP and webhooks following certain events.", - "ExperimentWebPush": "Enables web push notifications through the browser.", - "ExperimentWorkspacePrebuilds": "Enables the new workspace prebuilds feature.", - "ExperimentWorkspaceUsage": "Enables the new workspace usage tracking." + "ExperimentWorkspacePrebuilds": "Enables the new workspace prebuilds feature." }, "x-enum-varnames": [ "ExperimentExample", "ExperimentAutoFillParameters", - "ExperimentNotifications", - "ExperimentWorkspaceUsage", - "ExperimentWebPush", "ExperimentDynamicParameters", "ExperimentWorkspacePrebuilds", "ExperimentAgenticChat", diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index aabe0b9b12672..054b4e4c01bf8 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -11435,9 +11435,6 @@ "enum": [ "example", "auto-fill-parameters", - "notifications", - "workspace-usage", - "web-push", "dynamic-parameters", "workspace-prebuilds", "agentic-chat", @@ -11449,17 +11446,11 @@ "ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.", "ExperimentDynamicParameters": "Enables dynamic parameters when creating a workspace.", "ExperimentExample": "This isn't used for anything.", - "ExperimentNotifications": "Sends notifications via SMTP and webhooks following certain events.", - "ExperimentWebPush": "Enables web push notifications through the browser.", - "ExperimentWorkspacePrebuilds": "Enables the new workspace prebuilds feature.", - "ExperimentWorkspaceUsage": "Enables the new workspace usage tracking." + "ExperimentWorkspacePrebuilds": "Enables the new workspace prebuilds feature." }, "x-enum-varnames": [ "ExperimentExample", "ExperimentAutoFillParameters", - "ExperimentNotifications", - "ExperimentWorkspaceUsage", - "ExperimentWebPush", "ExperimentDynamicParameters", "ExperimentWorkspacePrebuilds", "ExperimentAgenticChat", diff --git a/coderd/telemetry/telemetry.go b/coderd/telemetry/telemetry.go index 66369dcc3ea61..155077b0d689d 100644 --- a/coderd/telemetry/telemetry.go +++ b/coderd/telemetry/telemetry.go @@ -14,7 +14,6 @@ import ( "os" "regexp" "runtime" - "strconv" "strings" "sync" diff --git a/coderd/webpush.go b/coderd/webpush.go index b5ec0ba3337c4..435507e38fb65 100644 --- a/coderd/webpush.go +++ b/coderd/webpush.go @@ -29,7 +29,6 @@ func (api *API) postUserWebpushSubscription(rw http.ResponseWriter, r *http.Requ ctx := r.Context() user := httpmw.UserParam(r) - var req codersdk.WebpushSubscription if !httpapi.Read(ctx, rw, r, &req) { return @@ -74,8 +73,6 @@ func (api *API) deleteUserWebpushSubscription(rw http.ResponseWriter, r *http.Re ctx := r.Context() user := httpmw.UserParam(r) - - var req codersdk.DeleteWebpushSubscription if !httpapi.Read(ctx, rw, r, &req) { return @@ -128,8 +125,6 @@ func (api *API) postUserPushNotificationTest(rw http.ResponseWriter, r *http.Req ctx := r.Context() user := httpmw.UserParam(r) - - // We need to authorize the user to send a push notification to themselves. if !api.Authorize(r, policy.ActionCreate, rbac.ResourceNotificationMessage.WithOwner(user.ID.String())) { httpapi.Forbidden(rw) diff --git a/coderd/workspaces.go b/coderd/workspaces.go index 32541800cb785..bbe169a59ad52 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -1507,8 +1507,6 @@ func (api *API) postWorkspaceUsage(rw http.ResponseWriter, r *http.Request) { api.statsReporter.TrackUsage(workspace.ID) - - if r.Body == http.NoBody { // Continue previous behavior if no body is present. rw.WriteHeader(http.StatusNoContent) diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index 9ff65a8610654..04f8081994d8b 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -4126,7 +4126,7 @@ func TestWorkspaceUsageTracking(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium) defer cancel() dv := coderdtest.DeploymentValues(t) - + client, db := coderdtest.NewWithDatabase(t, &coderdtest.Options{ DeploymentValues: dv, }) diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index 4191ab8970e92..b6b8a34a0fc75 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -3509,9 +3509,6 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o |------------------------| | `example` | | `auto-fill-parameters` | -| `notifications` | -| `workspace-usage` | -| `web-push` | | `dynamic-parameters` | | `workspace-prebuilds` | | `agentic-chat` | diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index c662b27386401..a494fe3ba192e 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -832,10 +832,7 @@ export type Experiment = | "auto-fill-parameters" | "dynamic-parameters" | "example" - | "notifications" - | "web-push" - | "workspace-prebuilds" - | "workspace-usage"; + | "workspace-prebuilds"; // From codersdk/deployment.go export type Experiments = readonly Experiment[]; From 6c6a764649be9839da105c28024283fda0422eaa Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 02:49:39 +0000 Subject: [PATCH 5/7] fix: remove experiment references from frontend code - Remove web-push experiment check from useWebpushNotifications - Remove notifications experiment from storybook configurations - Enable web push and notifications by default in frontend Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> --- site/src/contexts/useWebpushNotifications.ts | 6 ++---- .../NotificationsPage/storybookUtils.ts | 2 +- .../NotificationsPage/NotificationsPage.stories.tsx | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/site/src/contexts/useWebpushNotifications.ts b/site/src/contexts/useWebpushNotifications.ts index 0f3949135c287..edfc18023d438 100644 --- a/site/src/contexts/useWebpushNotifications.ts +++ b/site/src/contexts/useWebpushNotifications.ts @@ -24,10 +24,8 @@ export const useWebpushNotifications = (): WebpushNotifications => { const [enabled, setEnabled] = useState(false); useEffect(() => { - // Check if the experiment is enabled. - if (enabledExperimentsQuery.data?.includes("web-push")) { - setEnabled(true); - } + // Web push is now enabled by default + setEnabled(true); // Check if browser supports push notifications if (!("Notification" in window) || !("serviceWorker" in navigator)) { diff --git a/site/src/pages/DeploymentSettingsPage/NotificationsPage/storybookUtils.ts b/site/src/pages/DeploymentSettingsPage/NotificationsPage/storybookUtils.ts index f27535d5b5397..03b0fd95b92c2 100644 --- a/site/src/pages/DeploymentSettingsPage/NotificationsPage/storybookUtils.ts +++ b/site/src/pages/DeploymentSettingsPage/NotificationsPage/storybookUtils.ts @@ -185,7 +185,7 @@ const mockNotificationsDeploymentOptions: SerpentOption[] = [ export const baseMeta = { parameters: { - experiments: ["notifications"], + experiments: [], queries: [ { key: systemNotificationTemplatesKey, data: MockNotificationTemplates }, { diff --git a/site/src/pages/UserSettingsPage/NotificationsPage/NotificationsPage.stories.tsx b/site/src/pages/UserSettingsPage/NotificationsPage/NotificationsPage.stories.tsx index e2ac02e773d2d..06cdff574e0d3 100644 --- a/site/src/pages/UserSettingsPage/NotificationsPage/NotificationsPage.stories.tsx +++ b/site/src/pages/UserSettingsPage/NotificationsPage/NotificationsPage.stories.tsx @@ -24,7 +24,7 @@ const meta = { title: "pages/UserSettingsPage/NotificationsPage", component: NotificationsPage, parameters: { - experiments: ["notifications"], + experiments: [], queries: [ { key: userNotificationPreferencesKey(MockUserOwner.id), From 923d25e00089e65b9985e9e7e03695cd8a7e81c0 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 03:09:15 +0000 Subject: [PATCH 6/7] fix: remove unnecessary dependency from useWebpushNotifications useEffect The enabledExperimentsQuery.data dependency was not used within the useEffect hook and was causing a linting error. The effect only sets enabled state, checks browser support, and verifies subscription status. Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> --- site/src/contexts/useWebpushNotifications.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/contexts/useWebpushNotifications.ts b/site/src/contexts/useWebpushNotifications.ts index edfc18023d438..5ef14a3539519 100644 --- a/site/src/contexts/useWebpushNotifications.ts +++ b/site/src/contexts/useWebpushNotifications.ts @@ -48,7 +48,7 @@ export const useWebpushNotifications = (): WebpushNotifications => { }; checkSubscription(); - }, [enabledExperimentsQuery.data]); + }, []); const subscribe = async (): Promise => { try { From 04edaec27887136c7e6320eef77b446ef5c32ec6 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 03:31:26 +0000 Subject: [PATCH 7/7] fix: resolve data race in TestCollectInsights The test was experiencing a data race where the collected map was being modified in the assert.Eventuallyf goroutine while being read by cmp.Diff. Fixed by creating a local map in each iteration and only assigning it to the shared variable when the comparison succeeds, eliminating concurrent access to the same map. Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com> --- .../insights/metricscollector_test.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/coderd/prometheusmetrics/insights/metricscollector_test.go b/coderd/prometheusmetrics/insights/metricscollector_test.go index 9382fa5013525..fcd2fee5017f9 100644 --- a/coderd/prometheusmetrics/insights/metricscollector_test.go +++ b/coderd/prometheusmetrics/insights/metricscollector_test.go @@ -182,7 +182,7 @@ func TestCollectInsights(t *testing.T) { err = json.Unmarshal(goldenFile, &golden) require.NoError(t, err) - collected := map[string]int{} + var collected map[string]int ok := assert.Eventuallyf(t, func() bool { // When metrics, err := registry.Gather() @@ -191,6 +191,7 @@ func TestCollectInsights(t *testing.T) { } // Then + currentCollected := map[string]int{} for _, metric := range metrics { t.Logf("metric: %s: %#v", metric.GetName(), metric) switch metric.GetName() { @@ -200,14 +201,18 @@ func TestCollectInsights(t *testing.T) { if len(m.Label) > 0 { key = key + "[" + metricLabelAsString(m) + "]" } - collected[key] = int(m.Gauge.GetValue()) + currentCollected[key] = int(m.Gauge.GetValue()) } default: assert.Failf(t, "unexpected metric collected", "metric: %s", metric.GetName()) } } - return assert.ObjectsAreEqualValues(golden, collected) + if assert.ObjectsAreEqualValues(golden, currentCollected) { + collected = currentCollected + return true + } + return false }, testutil.WaitMedium, testutil.IntervalFast, "template insights are inconsistent with golden files") if !ok { diff := cmp.Diff(golden, collected)