Skip to content

Commit 644e565

Browse files
committed
Merge branch 'main' into quiet-hours-page
2 parents c600664 + 0e4d689 commit 644e565

File tree

17 files changed

+174
-130
lines changed

17 files changed

+174
-130
lines changed

coderd/coderdtest/coderdtest.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,15 +459,20 @@ func NewWithAPI(t testing.TB, options *Options) (*codersdk.Client, io.Closer, *c
459459
func NewProvisionerDaemon(t testing.TB, coderAPI *coderd.API) io.Closer {
460460
t.Helper()
461461

462+
// t.Cleanup runs in last added, first called order. t.TempDir() will delete
463+
// the directory on cleanup, so we want to make sure the echoServer is closed
464+
// before we go ahead an attempt to delete it's work directory.
465+
// seems t.TempDir() is not safe to call from a different goroutine
466+
workDir := t.TempDir()
467+
462468
echoClient, echoServer := provisionersdk.MemTransportPipe()
463469
ctx, cancelFunc := context.WithCancel(context.Background())
464470
t.Cleanup(func() {
465471
_ = echoClient.Close()
466472
_ = echoServer.Close()
467473
cancelFunc()
468474
})
469-
// seems t.TempDir() is not safe to call from a different goroutine
470-
workDir := t.TempDir()
475+
471476
go func() {
472477
err := echo.Serve(ctx, &provisionersdk.ServeOptions{
473478
Listener: echoServer,

provisionersdk/session.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ func (s *Session) extractArchive() error {
230230
if mode == 0 {
231231
mode = 0o600
232232
}
233+
234+
// Always check for context cancellation before reading the next header.
235+
// This is mainly important for unit tests, since a canceled context means
236+
// the underlying directory is going to be deleted. There still exists
237+
// the small race condition that the context is cancelled after this, and
238+
// before the disk write.
239+
if ctx.Err() != nil {
240+
return xerrors.Errorf("context canceled: %w", ctx.Err())
241+
}
233242
switch header.Typeflag {
234243
case tar.TypeDir:
235244
err = os.MkdirAll(headerPath, mode)

site/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
"@typescript-eslint/eslint-plugin": "6.7.0",
138138
"@typescript-eslint/parser": "6.7.0",
139139
"@xstate/cli": "0.5.2",
140-
"chromatic": "6.24.1",
140+
"chromatic": "7.1.0",
141141
"eslint": "8.49.0",
142142
"eslint-config-prettier": "9.0.0",
143143
"eslint-import-resolver-typescript": "3.6.0",

site/pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/api/queries/templates.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,38 @@
11
import * as API from "api/api";
2+
import { type Template, type AuthorizationResponse } from "api/typesGenerated";
3+
import { type QueryOptions } from "@tanstack/react-query";
4+
5+
export const templateByNameKey = (orgId: string, name: string) => [
6+
orgId,
7+
"template",
8+
name,
9+
"settings",
10+
];
11+
12+
export const templateByName = (
13+
orgId: string,
14+
name: string,
15+
): QueryOptions<{ template: Template; permissions: AuthorizationResponse }> => {
16+
return {
17+
queryKey: templateByNameKey(orgId, name),
18+
queryFn: async () => {
19+
const template = await API.getTemplateByName(orgId, name);
20+
const permissions = await API.checkAuthorization({
21+
checks: {
22+
canUpdateTemplate: {
23+
object: {
24+
resource_type: "template",
25+
resource_id: template.id,
26+
},
27+
action: "update",
28+
},
29+
},
30+
});
31+
32+
return { template, permissions };
33+
},
34+
};
35+
};
236

337
const getTemplatesQueryKey = (orgId: string) => [orgId, "templates"];
438

site/src/api/queries/workspace.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as API from "api/api";
2+
import { type Workspace } from "api/typesGenerated";
3+
import { type QueryOptions } from "@tanstack/react-query";
4+
5+
export const workspaceByOwnerAndNameKey = (owner: string, name: string) => [
6+
"workspace",
7+
owner,
8+
name,
9+
"settings",
10+
];
11+
12+
export const workspaceByOwnerAndName = (
13+
owner: string,
14+
name: string,
15+
): QueryOptions<Workspace> => {
16+
return {
17+
queryKey: workspaceByOwnerAndNameKey(owner, name),
18+
queryFn: () => API.getWorkspaceByOwnerAndName(owner, name),
19+
};
20+
};

site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPage.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ import { FC } from "react";
66
import { Helmet } from "react-helmet-async";
77
import { useNavigate, useParams } from "react-router-dom";
88
import { pageTitle } from "utils/page";
9-
import {
10-
getTemplateQuery,
11-
useTemplateSettingsContext,
12-
} from "../TemplateSettingsLayout";
9+
import { useTemplateSettings } from "../TemplateSettingsLayout";
1310
import { TemplateSettingsPageView } from "./TemplateSettingsPageView";
11+
import { templateByNameKey } from "api/queries/templates";
12+
import { useOrganizationId } from "hooks";
1413

1514
export const TemplateSettingsPage: FC = () => {
1615
const { template: templateName } = useParams() as { template: string };
1716
const navigate = useNavigate();
18-
const { template } = useTemplateSettingsContext();
17+
const orgId = useOrganizationId();
18+
const { template } = useTemplateSettings();
1919
const queryClient = useQueryClient();
2020
const {
2121
mutate: updateTemplate,
@@ -25,9 +25,9 @@ export const TemplateSettingsPage: FC = () => {
2525
(data: UpdateTemplateMeta) => updateTemplateMeta(template.id, data),
2626
{
2727
onSuccess: async () => {
28-
await queryClient.invalidateQueries({
29-
queryKey: getTemplateQuery(templateName),
30-
});
28+
await queryClient.invalidateQueries(
29+
templateByNameKey(orgId, templateName),
30+
);
3131
displaySuccess("Template updated successfully");
3232
},
3333
},

site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import { FC } from "react";
1111
import { Helmet } from "react-helmet-async";
1212
import { pageTitle } from "utils/page";
1313
import { templateACLMachine } from "xServices/template/templateACLXService";
14-
import { useTemplateSettingsContext } from "../TemplateSettingsLayout";
14+
import { useTemplateSettings } from "../TemplateSettingsLayout";
1515
import { TemplatePermissionsPageView } from "./TemplatePermissionsPageView";
1616
import { docs } from "utils/docs";
1717

1818
export const TemplatePermissionsPage: FC<
1919
React.PropsWithChildren<unknown>
2020
> = () => {
2121
const organizationId = useOrganizationId();
22-
const { template, permissions } = useTemplateSettingsContext();
22+
const { template, permissions } = useTemplateSettings();
2323
const { template_rbac: isTemplateRBACEnabled } = useFeatureVisibility();
2424
const [state, send] = useMachine(templateACLMachine, {
2525
context: { templateId: template.id },

site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
138138
}
139139
},
140140
initialTouched,
141+
enableReinitialize: true,
141142
});
142143

143144
const getFieldHelpers = getFormHelpers<TemplateScheduleFormValues>(

site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePage.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMutation } from "@tanstack/react-query";
1+
import { useMutation, useQueryClient } from "@tanstack/react-query";
22
import { updateTemplateMeta } from "api/api";
33
import { UpdateTemplateMeta } from "api/typesGenerated";
44
import { useDashboard } from "components/Dashboard/DashboardProvider";
@@ -7,14 +7,17 @@ import { FC } from "react";
77
import { Helmet } from "react-helmet-async";
88
import { useNavigate, useParams } from "react-router-dom";
99
import { pageTitle } from "utils/page";
10-
import { useTemplateSettingsContext } from "../TemplateSettingsLayout";
10+
import { useTemplateSettings } from "../TemplateSettingsLayout";
1111
import { TemplateSchedulePageView } from "./TemplateSchedulePageView";
12-
import { useLocalStorage } from "hooks";
12+
import { useLocalStorage, useOrganizationId } from "hooks";
13+
import { templateByNameKey } from "api/queries/templates";
1314

1415
const TemplateSchedulePage: FC = () => {
1516
const { template: templateName } = useParams() as { template: string };
1617
const navigate = useNavigate();
17-
const { template } = useTemplateSettingsContext();
18+
const queryClient = useQueryClient();
19+
const orgId = useOrganizationId();
20+
const { template } = useTemplateSettings();
1821
const { entitlements, experiments } = useDashboard();
1922
const allowAdvancedScheduling =
2023
entitlements.features["advanced_template_scheduling"].enabled;
@@ -32,7 +35,10 @@ const TemplateSchedulePage: FC = () => {
3235
} = useMutation(
3336
(data: UpdateTemplateMeta) => updateTemplateMeta(template.id, data),
3437
{
35-
onSuccess: () => {
38+
onSuccess: async () => {
39+
await queryClient.invalidateQueries(
40+
templateByNameKey(orgId, templateName),
41+
);
3642
displaySuccess("Template updated successfully");
3743
// clear browser storage of workspaces impending deletion
3844
clearLocal("dismissedWorkspaceList"); // workspaces page

0 commit comments

Comments
 (0)