feat: remove workspace_actions experiment (#11427)

This commit is contained in:
Jon Ayers 2024-01-10 16:19:39 -06:00 committed by GitHub
parent 04afb88e6f
commit 9b437032e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 26 additions and 119 deletions

View File

@ -49,18 +49,6 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
isTemplateSchedulingOptionsSet := failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 || maxTTL != 0
if isTemplateSchedulingOptionsSet || requireActiveVersion {
if failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 {
// This call can be removed when workspace_actions is no longer experimental
experiments, exErr := client.Experiments(inv.Context())
if exErr != nil {
return xerrors.Errorf("get experiments: %w", exErr)
}
if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) {
return xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
}
}
entitlements, err := client.Entitlements(inv.Context())
if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusNotFound {
return xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set enterprise-only flags")

View File

@ -47,18 +47,6 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
),
Short: "Edit the metadata of a template by name.",
Handler: func(inv *clibase.Invocation) error {
// This clause can be removed when workspace_actions is no longer experimental
if failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 {
experiments, exErr := client.Experiments(inv.Context())
if exErr != nil {
return xerrors.Errorf("get experiments: %w", exErr)
}
if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) {
return xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.")
}
}
unsetAutostopRequirementDaysOfWeek := len(autostopRequirementDaysOfWeek) == 1 && autostopRequirementDaysOfWeek[0] == "none"
requiresScheduling := (len(autostopRequirementDaysOfWeek) > 0 && !unsetAutostopRequirementDaysOfWeek) ||
autostopRequirementWeeks > 0 ||

2
coderd/apidoc/docs.go generated
View File

@ -9108,11 +9108,9 @@ const docTemplate = `{
"codersdk.Experiment": {
"type": "string",
"enum": [
"workspace_actions",
"deployment_health_page"
],
"x-enum-varnames": [
"ExperimentWorkspaceActions",
"ExperimentDeploymentHealthPage"
]
},

View File

@ -8153,11 +8153,8 @@
},
"codersdk.Experiment": {
"type": "string",
"enum": ["workspace_actions", "deployment_health_page"],
"x-enum-varnames": [
"ExperimentWorkspaceActions",
"ExperimentDeploymentHealthPage"
]
"enum": ["deployment_health_page"],
"x-enum-varnames": ["ExperimentDeploymentHealthPage"]
},
"codersdk.ExternalAuth": {
"type": "object",

View File

@ -2077,9 +2077,6 @@ func (c *Client) BuildInfo(ctx context.Context) (BuildInfoResponse, error) {
type Experiment string
const (
// https://github.com/coder/coder/milestone/19
ExperimentWorkspaceActions Experiment = "workspace_actions"
// Deployment health page
ExperimentDeploymentHealthPage Experiment = "deployment_health_page"

4
docs/api/general.md generated
View File

@ -563,7 +563,7 @@ curl -X GET http://coder-server:8080/api/v2/experiments \
> 200 Response
```json
["workspace_actions"]
["deployment_health_page"]
```
### Responses
@ -600,7 +600,7 @@ curl -X GET http://coder-server:8080/api/v2/experiments/available \
> 200 Response
```json
["workspace_actions"]
["deployment_health_page"]
```
### Responses

3
docs/api/schemas.md generated
View File

@ -2869,7 +2869,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
## codersdk.Experiment
```json
"workspace_actions"
"deployment_health_page"
```
### Properties
@ -2878,7 +2878,6 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
| Value |
| ------------------------ |
| `workspace_actions` |
| `deployment_health_page` |
## codersdk.ExternalAuth

View File

@ -62,11 +62,6 @@ func TestTemplateCreate(t *testing.T) {
t.Run("WorkspaceCleanup", func(t *testing.T) {
t.Parallel()
dv := coderdtest.DeploymentValues(t)
dv.Experiments = []string{
string(codersdk.ExperimentWorkspaceActions),
}
client, user := coderdenttest.New(t, &coderdenttest.Options{
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
@ -74,7 +69,6 @@ func TestTemplateCreate(t *testing.T) {
},
},
Options: &coderdtest.Options{
DeploymentValues: dv,
IncludeProvisionerDaemon: true,
},
})

View File

@ -89,11 +89,6 @@ func TestTemplateEdit(t *testing.T) {
t.Run("WorkspaceCleanup", func(t *testing.T) {
t.Parallel()
dv := coderdtest.DeploymentValues(t)
dv.Experiments = []string{
string(codersdk.ExperimentWorkspaceActions),
}
ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
@ -101,7 +96,6 @@ func TestTemplateEdit(t *testing.T) {
},
},
Options: &coderdtest.Options{
DeploymentValues: dv,
IncludeProvisionerDaemon: true,
},
})

View File

@ -1813,11 +1813,8 @@ export const Entitlements: Entitlement[] = [
];
// From codersdk/deployment.go
export type Experiment = "deployment_health_page" | "workspace_actions";
export const Experiments: Experiment[] = [
"deployment_health_page",
"workspace_actions",
];
export type Experiment = "deployment_health_page";
export const Experiments: Experiment[] = ["deployment_health_page"];
// From codersdk/deployment.go
export type FeatureName =

View File

@ -113,11 +113,6 @@ export const useDashboard = (): DashboardProviderValue => {
};
export const useIsWorkspaceActionsEnabled = (): boolean => {
const { entitlements, experiments } = useDashboard();
const allowAdvancedScheduling =
entitlements.features["advanced_template_scheduling"].enabled;
// This check can be removed when https://github.com/coder/coder/milestone/19
// is merged up
const allowWorkspaceActions = experiments.includes("workspace_actions");
return allowWorkspaceActions && allowAdvancedScheduling;
const { entitlements } = useDashboard();
return entitlements.features["advanced_template_scheduling"].enabled;
};

View File

@ -10,20 +10,13 @@ interface DormantDeletionTextProps {
export const DormantDeletionText: FC<DormantDeletionTextProps> = ({
workspace,
}) => {
const { entitlements, experiments } = useDashboard();
const { entitlements } = useDashboard();
const allowAdvancedScheduling =
entitlements.features["advanced_template_scheduling"].enabled;
// This check can be removed when https://github.com/coder/coder/milestone/19
// is merged up
const allowWorkspaceActions = experiments.includes("workspace_actions");
if (
!displayDormantDeletion(
workspace,
allowAdvancedScheduling,
allowWorkspaceActions,
)
) {
if (!displayDormantDeletion(workspace, allowAdvancedScheduling)) {
return null;
}

View File

@ -54,7 +54,6 @@ export interface TemplateScheduleForm {
isSubmitting: boolean;
error?: unknown;
allowAdvancedScheduling: boolean;
allowWorkspaceActions: boolean;
// Helpful to show field errors on Storybook
initialTouched?: FormikTouched<UpdateTemplateMeta>;
}
@ -65,7 +64,6 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
onCancel,
error,
allowAdvancedScheduling,
allowWorkspaceActions,
isSubmitting,
initialTouched,
}) => {
@ -562,7 +560,7 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
</Stack>
</Stack>
</FormSection>
{allowAdvancedScheduling && allowWorkspaceActions && (
{allowAdvancedScheduling && (
<>
<FormSection
title="Failure Cleanup"

View File

@ -139,9 +139,6 @@ describe("TemplateSchedulePage", () => {
jest
.spyOn(API, "getEntitlements")
.mockResolvedValue(MockEntitlementsWithScheduling);
// remove when https://github.com/coder/coder/milestone/19 is completed.
jest.spyOn(API, "getExperiments").mockResolvedValue(["workspace_actions"]);
});
it("Calls the API when user fills in and submits a form", async () => {

View File

@ -18,12 +18,9 @@ const TemplateSchedulePage: FC = () => {
const queryClient = useQueryClient();
const orgId = useOrganizationId();
const { template } = useTemplateSettings();
const { entitlements, experiments } = useDashboard();
const { entitlements } = useDashboard();
const allowAdvancedScheduling =
entitlements.features["advanced_template_scheduling"].enabled;
// This check can be removed when https://github.com/coder/coder/milestone/19
// is merged up
const allowWorkspaceActions = experiments.includes("workspace_actions");
const { clearLocal } = useLocalStorage();
const {
@ -52,7 +49,6 @@ const TemplateSchedulePage: FC = () => {
</Helmet>
<TemplateSchedulePageView
allowAdvancedScheduling={allowAdvancedScheduling}
allowWorkspaceActions={allowWorkspaceActions}
isSubmitting={isSubmitting}
template={template}
submitError={submitError}

View File

@ -31,7 +31,6 @@ type Story = StoryObj<typeof TemplateSchedulePageView>;
const defaultArgs = {
allowAdvancedScheduling: true,
allowWorkspaceActions: true,
template: MockTemplate,
onSubmit: action("onSubmit"),
onCancel: action("cancel"),

View File

@ -13,7 +13,6 @@ export interface TemplateSchedulePageViewProps {
typeof TemplateScheduleForm
>["initialTouched"];
allowAdvancedScheduling: boolean;
allowWorkspaceActions: boolean;
}
export const TemplateSchedulePageView: FC<TemplateSchedulePageViewProps> = ({
@ -22,7 +21,6 @@ export const TemplateSchedulePageView: FC<TemplateSchedulePageViewProps> = ({
onSubmit,
isSubmitting,
allowAdvancedScheduling,
allowWorkspaceActions,
submitError,
initialTouched,
}) => {
@ -34,7 +32,6 @@ export const TemplateSchedulePageView: FC<TemplateSchedulePageViewProps> = ({
<TemplateScheduleForm
allowAdvancedScheduling={allowAdvancedScheduling}
allowWorkspaceActions={allowWorkspaceActions}
initialTouched={initialTouched}
isSubmitting={isSubmitting}
template={template}

View File

@ -24,7 +24,6 @@ const meta: Meta<typeof WorkspaceTopbar> = {
parameters: {
layout: "fullscreen",
features: ["advanced_template_scheduling"],
experiments: ["workspace_actions"],
},
};

View File

@ -88,16 +88,14 @@ export const WorkspaceTopbar = (props: WorkspaceProps) => {
});
// Dormant
const { entitlements, experiments } = useDashboard();
const { entitlements } = useDashboard();
const allowAdvancedScheduling =
entitlements.features["advanced_template_scheduling"].enabled;
// This check can be removed when https://github.com/coder/coder/milestone/19
// is merged up
const allowWorkspaceActions = experiments.includes("workspace_actions");
const shouldDisplayDormantData = displayDormantDeletion(
workspace,
allowAdvancedScheduling,
allowWorkspaceActions,
);
return (

View File

@ -2047,7 +2047,9 @@ export const MockEntitlementsWithUserLimit: TypesGen.Entitlements = {
}),
};
export const MockExperiments: TypesGen.Experiment[] = ["workspace_actions"];
export const MockExperiments: TypesGen.Experiment[] = [
"deployment_health_page",
];
export const MockAuditLog: TypesGen.AuditLog = {
id: "fbd2116a-8961-4954-87ae-e4575bd29ce0",

View File

@ -4,53 +4,39 @@ import { displayDormantDeletion } from "./dormant";
describe("displayDormantDeletion", () => {
const today = new Date();
it.each<[string, boolean, boolean, boolean]>([
it.each<[string, boolean, boolean]>([
[
new Date(new Date().setDate(today.getDate() + 15)).toISOString(),
true,
true,
false,
], // today + 15 days out
[
new Date(new Date().setDate(today.getDate() + 14)).toISOString(),
true,
true,
true,
], // today + 14
[
new Date(new Date().setDate(today.getDate() + 13)).toISOString(),
true,
true,
true,
], // today + 13
[
new Date(new Date().setDate(today.getDate() + 1)).toISOString(),
true,
true,
true,
], // today + 1
[new Date().toISOString(), true, true, true], // today + 0
[new Date().toISOString(), false, true, false], // Advanced Scheduling off
[new Date().toISOString(), true, false, false], // Workspace Actions off
[new Date().toISOString(), true, true], // today + 0
[new Date().toISOString(), false, false], // Advanced Scheduling off
])(
`deleting_at=%p, allowAdvancedScheduling=%p, AllowWorkspaceActions=%p, shouldDisplay=%p`,
(
deleting_at,
allowAdvancedScheduling,
allowWorkspaceActions,
shouldDisplay,
) => {
`deleting_at=%p, allowAdvancedScheduling=%p, shouldDisplay=%p`,
(deleting_at, allowAdvancedScheduling, shouldDisplay) => {
const workspace: TypesGen.Workspace = {
...Mocks.MockWorkspace,
deleting_at,
};
expect(
displayDormantDeletion(
workspace,
allowAdvancedScheduling,
allowWorkspaceActions,
),
).toBe(shouldDisplay);
expect(displayDormantDeletion(workspace, allowAdvancedScheduling)).toBe(
shouldDisplay,
);
},
);
});

View File

@ -14,14 +14,9 @@ const IMPENDING_DELETION_DISPLAY_THRESHOLD = 14; // 14 days
export const displayDormantDeletion = (
workspace: Workspace,
allowAdvancedScheduling: boolean,
allowWorkspaceActions: boolean,
) => {
const today = new Date();
if (
!workspace.deleting_at ||
!allowAdvancedScheduling ||
!allowWorkspaceActions
) {
if (!workspace.deleting_at || !allowAdvancedScheduling) {
return false;
}
return (