Skip to content

[pull] main from coder:main #194

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 5 commits into from
May 6, 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
9 changes: 7 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,8 @@ jobs:
touch ~/.bash_profile && echo "export BASH_SILENCE_DEPRECATION_WARNING=1" >> ~/.bash_profile
fi
export TS_DEBUG_DISCO=true
gotestsum --junitfile="gotests.xml" --jsonfile="gotests.json" \
--packages="./..." -- $PARALLEL_FLAG -short -failfast
gotestsum --junitfile="gotests.xml" --jsonfile="gotests.json" --rerun-fails=2 \
--packages="./..." -- $PARALLEL_FLAG -short

- name: Upload Test Cache
uses: ./.github/actions/test-cache/upload
Expand Down Expand Up @@ -436,6 +436,7 @@ jobs:
TS_DEBUG_DISCO: "true"
LC_CTYPE: "en_US.UTF-8"
LC_ALL: "en_US.UTF-8"
TEST_RETRIES: 2
shell: bash
run: |
# By default Go will use the number of logical CPUs, which
Expand Down Expand Up @@ -499,6 +500,7 @@ jobs:
TS_DEBUG_DISCO: "true"
LC_CTYPE: "en_US.UTF-8"
LC_ALL: "en_US.UTF-8"
TEST_RETRIES: 2
shell: bash
run: |
# By default Go will use the number of logical CPUs, which
Expand Down Expand Up @@ -560,6 +562,7 @@ jobs:
env:
POSTGRES_VERSION: "16"
TS_DEBUG_DISCO: "true"
TEST_RETRIES: 2
run: |
make test-postgres

Expand Down Expand Up @@ -784,6 +787,7 @@ jobs:
if: ${{ !matrix.variant.premium }}
env:
DEBUG: pw:api
CODER_E2E_TEST_RETRIES: 2
working-directory: site

# Run all of the tests with a premium license
Expand All @@ -793,6 +797,7 @@ jobs:
DEBUG: pw:api
CODER_E2E_LICENSE: ${{ secrets.CODER_E2E_LICENSE }}
CODER_E2E_REQUIRE_PREMIUM_TESTS: "1"
CODER_E2E_TEST_RETRIES: 2
working-directory: site

- name: Upload Playwright Failed Tests
Expand Down
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -875,12 +875,19 @@ provisioner/terraform/testdata/version:
fi
.PHONY: provisioner/terraform/testdata/version

# Set the retry flags if TEST_RETRIES is set
ifdef TEST_RETRIES
GOTESTSUM_RETRY_FLAGS := --rerun-fails=$(TEST_RETRIES)
else
GOTESTSUM_RETRY_FLAGS :=
endif

test:
$(GIT_FLAGS) gotestsum --format standard-quiet -- -v -short -count=1 ./... $(if $(RUN),-run $(RUN))
$(GIT_FLAGS) gotestsum --format standard-quiet $(GOTESTSUM_RETRY_FLAGS) --packages="./..." -- -v -short -count=1 $(if $(RUN),-run $(RUN))
.PHONY: test

test-cli:
$(GIT_FLAGS) gotestsum --format standard-quiet -- -v -short -count=1 ./cli/...
$(GIT_FLAGS) gotestsum --format standard-quiet $(GOTESTSUM_RETRY_FLAGS) --packages="./cli/..." -- -v -short -count=1
.PHONY: test-cli

# sqlc-cloud-is-setup will fail if no SQLc auth token is set. Use this as a
Expand Down Expand Up @@ -919,9 +926,9 @@ test-postgres: test-postgres-docker
$(GIT_FLAGS) DB=ci gotestsum \
--junitfile="gotests.xml" \
--jsonfile="gotests.json" \
$(GOTESTSUM_RETRY_FLAGS) \
--packages="./..." -- \
-timeout=20m \
-failfast \
-count=1
.PHONY: test-postgres

Expand Down
4 changes: 3 additions & 1 deletion site/e2e/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,9 @@ export async function openTerminalWindow(
): Promise<Page> {
// Wait for the web terminal to open in a new tab
const pagePromise = context.waitForEvent("page");
await page.getByTestId("terminal").click({ timeout: 60_000 });
await page
.getByRole("link", { name: /terminal/i })
.click({ timeout: 60_000 });
const terminal = await pagePromise;
await terminal.waitForLoadState("domcontentloaded");

Expand Down
18 changes: 18 additions & 0 deletions site/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,30 @@ import {
} from "./constants";

export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT;
export const retries = (() => {
if (process.env.CODER_E2E_TEST_RETRIES === undefined) {
return undefined;
}
const count = Number.parseInt(process.env.CODER_E2E_TEST_RETRIES, 10);
if (Number.isNaN(count)) {
throw new Error(
`CODER_E2E_TEST_RETRIES is not a number: ${process.env.CODER_E2E_TEST_RETRIES}`,
);
}
if (count < 0) {
throw new Error(
`CODER_E2E_TEST_RETRIES is less than 0: ${process.env.CODER_E2E_TEST_RETRIES}`,
);
}
return count;
})();

const localURL = (port: number, path: string): string => {
return `http://localhost:${port}${path}`;
};

export default defineConfig({
retries,
globalSetup: require.resolve("./setup/preflight"),
projects: [
{
Expand Down
11 changes: 5 additions & 6 deletions site/src/api/queries/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,9 @@ function workspacesKey(config: WorkspacesRequest = {}) {
}

export function workspaces(config: WorkspacesRequest = {}) {
// Duplicates some of the work from workspacesKey, but that felt better than
// letting invisible properties sneak into the query logic
const { q, limit } = config;

return {
queryKey: workspacesKey(config),
queryFn: () => API.getWorkspaces({ q, limit }),
queryFn: () => API.getWorkspaces(config),
} as const satisfies QueryOptions<WorkspacesResponse>;
}

Expand Down Expand Up @@ -281,7 +277,10 @@ const updateWorkspaceBuild = async (
build.workspace_owner_name,
build.workspace_name,
);
const previousData = queryClient.getQueryData(workspaceKey) as Workspace;
const previousData = queryClient.getQueryData<Workspace>(workspaceKey);
if (!previousData) {
return;
}

// Check if the build returned is newer than the previous build that could be
// updated from web socket
Expand Down
12 changes: 7 additions & 5 deletions site/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ const buttonVariants = cva(
text-sm font-semibold font-medium cursor-pointer no-underline
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-content-link
disabled:pointer-events-none disabled:text-content-disabled
[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:p-0.5`,
[&:is(a):not([href])]:pointer-events-none [&:is(a):not([href])]:text-content-disabled
[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:p-0.5
[&>img]:pointer-events-none [&>img]:shrink-0 [&>img]:p-0.5`,
{
variants: {
variant: {
Expand All @@ -28,11 +30,11 @@ const buttonVariants = cva(
},

size: {
lg: "min-w-20 h-10 px-3 py-2 [&_svg]:size-icon-lg",
sm: "min-w-20 h-8 px-2 py-1.5 text-xs [&_svg]:size-icon-sm",
lg: "min-w-20 h-10 px-3 py-2 [&_svg]:size-icon-lg [&>img]:size-icon-lg",
sm: "min-w-20 h-8 px-2 py-1.5 text-xs [&_svg]:size-icon-sm [&>img]:size-icon-sm",
xs: "min-w-8 py-1 px-2 text-2xs rounded-md",
icon: "size-8 px-1.5 [&_svg]:size-icon-sm",
"icon-lg": "size-10 px-2 [&_svg]:size-icon-lg",
icon: "size-8 px-1.5 [&_svg]:size-icon-sm [&>img]:size-icon-sm",
"icon-lg": "size-10 px-2 [&_svg]:size-icon-lg [&>img]:size-icon-lg",
},
},
defaultVariants: {
Expand Down
9 changes: 8 additions & 1 deletion site/src/components/Dialogs/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ export const DialogActionButtons: FC<DialogActionButtonsProps> = ({
return (
<>
{onCancel && (
<Button disabled={confirmLoading} onClick={onCancel} variant="outline">
<Button
disabled={confirmLoading}
onClick={(e) => {
e.stopPropagation();
onCancel();
}}
variant="outline"
>
{cancelText}
</Button>
)}
Expand Down
8 changes: 4 additions & 4 deletions site/src/components/ExternalImage/ExternalImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { getExternalImageStylesFromUrl } from "theme/externalImages";
export const ExternalImage = forwardRef<
HTMLImageElement,
ImgHTMLAttributes<HTMLImageElement>
>((attrs, ref) => {
>((props, ref) => {
const theme = useTheme();

return (
// biome-ignore lint/a11y/useAltText: no reasonable alt to provide
// biome-ignore lint/a11y/useAltText: alt should be passed in as a prop
<img
ref={ref}
css={getExternalImageStylesFromUrl(theme.externalImages, attrs.src)}
{...attrs}
css={getExternalImageStylesFromUrl(theme.externalImages, props.src)}
{...props}
/>
);
});
6 changes: 5 additions & 1 deletion site/src/hooks/usePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const usePagination = ({
const [searchParams, setSearchParams] = searchParamsResult;
const page = searchParams.get("page") ? Number(searchParams.get("page")) : 1;
const limit = DEFAULT_RECORDS_PER_PAGE;
const offset = page <= 0 ? 0 : (page - 1) * limit;
const offset = calcOffset(page, limit);

const goToPage = (page: number) => {
searchParams.set("page", page.toString());
Expand All @@ -23,3 +23,7 @@ export const usePagination = ({
offset,
};
};

export const calcOffset = (page: number, limit: number) => {
return page <= 0 ? 0 : (page - 1) * limit;
};
25 changes: 9 additions & 16 deletions site/src/modules/dashboard/Navbar/ProxyMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,32 +81,25 @@ export const ProxyMenu: FC<ProxyMenuProps> = ({ proxyContextValue }) => {
</span>

{selectedProxy ? (
<div css={{ display: "flex", gap: 8, alignItems: "center" }}>
<div css={{ width: 16, height: 16, lineHeight: 0 }}>
<img
// Empty alt text used because we don't want to double up on
// screen reader announcements from visually-hidden span
alt=""
src={selectedProxy.icon_url}
css={{
objectFit: "contain",
width: "100%",
height: "100%",
}}
/>
</div>
<>
<img
// Empty alt text used because we don't want to double up on
// screen reader announcements from visually-hidden span
alt=""
src={selectedProxy.icon_url}
/>

<Latency
latency={latencies?.[selectedProxy.id]?.latencyMS}
isLoading={proxyLatencyLoading(selectedProxy)}
size={24}
/>
</div>
</>
) : (
"Select Proxy"
)}

<ChevronDownIcon className="text-content-primary !size-icon-xs" />
<ChevronDownIcon className="text-content-primary !size-icon-sm" />
</Button>

<Menu
Expand Down
34 changes: 16 additions & 18 deletions site/src/modules/management/OrganizationSidebarView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,23 @@ export const OrganizationSidebarView: FC<
<Button
variant="outline"
aria-expanded={isPopoverOpen}
className="w-60 justify-between p-2 h-11"
className="w-60 gap-2 justify-start"
>
<div className="flex flex-row gap-2 items-center p-2 truncate">
{activeOrganization ? (
<>
<Avatar
size="sm"
src={activeOrganization.icon}
fallback={activeOrganization.display_name}
/>
<span className="truncate">
{activeOrganization.display_name || activeOrganization.name}
</span>
</>
) : (
<span className="truncate">No organization selected</span>
)}
</div>
<ChevronDown />
{activeOrganization ? (
<>
<Avatar
size="sm"
src={activeOrganization.icon}
fallback={activeOrganization.display_name}
/>
<span className="truncate">
{activeOrganization.display_name || activeOrganization.name}
</span>
</>
) : (
<span className="truncate">No organization selected</span>
)}
<ChevronDown className="ml-auto !size-icon-sm" />
</Button>
</PopoverTrigger>
<PopoverContent align="start" className="w-60">
Expand Down
27 changes: 2 additions & 25 deletions site/src/modules/resources/AgentButton.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,8 @@
import Button, { type ButtonProps } from "@mui/material/Button";
import { Button, type ButtonProps } from "components/Button/Button";
import { forwardRef } from "react";

export const AgentButton = forwardRef<HTMLButtonElement, ButtonProps>(
(props, ref) => {
const { children, ...buttonProps } = props;

return (
<Button
{...buttonProps}
color="neutral"
size="xlarge"
variant="contained"
ref={ref}
css={(theme) => ({
padding: "12px 20px",
color: theme.palette.text.primary,
// Making them smaller since those icons don't have a padding around them
"& .MuiButton-startIcon, & .MuiButton-endIcon": {
width: 16,
height: 16,

"& svg, & img": { width: "100%", height: "100%" },
},
})}
>
{children}
</Button>
);
return <Button variant="outline" ref={ref} {...props} />;
},
);
Loading
Loading