Skip to content

feat(site): display build logs on workspace transitioning statuses #8397

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 10 commits into from
Jul 10, 2023
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
6 changes: 4 additions & 2 deletions coderd/apidoc/docs.go

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

6 changes: 4 additions & 2 deletions coderd/apidoc/swagger.json

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

5 changes: 4 additions & 1 deletion codersdk/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,7 @@ const (
// oidc.
ExperimentConvertToOIDC Experiment = "convert-to-oidc"

ExperimentWorkspaceBuildLogsUI Experiment = "workspace_build_logs_ui"
// Add new experiments here!
// ExperimentExample Experiment = "example"
)
Expand All @@ -1771,7 +1772,9 @@ const (
// users to opt-in to via --experimental='*'.
// Experiments that are not ready for consumption by all users should
// not be included here and will be essentially hidden.
var ExperimentsAll = Experiments{}
var ExperimentsAll = Experiments{
ExperimentWorkspaceBuildLogsUI,
}

// Experiments is a list of experiments that are enabled for the deployment.
// Multiple experiments may be enabled at the same time.
Expand Down
13 changes: 7 additions & 6 deletions docs/api/schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -2531,12 +2531,13 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in

#### Enumerated Values

| Value |
| ------------------------ |
| `moons` |
| `workspace_actions` |
| `tailnet_pg_coordinator` |
| `convert-to-oidc` |
| Value |
| ------------------------- |
| `moons` |
| `workspace_actions` |
| `tailnet_pg_coordinator` |
| `convert-to-oidc` |
| `workspace_build_logs_ui` |

## codersdk.Feature

Expand Down
8 changes: 8 additions & 0 deletions site/.storybook/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { HelmetProvider } from "react-helmet-async"
import { dark } from "../src/theme"
import "../src/theme/globalFonts"
import "../src/i18n"
import { LocalPreferencesProvider } from "../src/contexts/LocalPreferencesContext"

export const decorators = [
(Story) => (
Expand All @@ -23,6 +24,13 @@ export const decorators = [
</HelmetProvider>
)
},
(Story) => {
return (
<LocalPreferencesProvider>
<Story />
</LocalPreferencesProvider>
)
},
]

export const parameters = {
Expand Down
2 changes: 2 additions & 0 deletions site/src/api/typesGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1416,11 +1416,13 @@ export type Experiment =
| "moons"
| "tailnet_pg_coordinator"
| "workspace_actions"
| "workspace_build_logs_ui"
export const Experiments: Experiment[] = [
"convert-to-oidc",
"moons",
"tailnet_pg_coordinator",
"workspace_actions",
"workspace_build_logs_ui",
]

// From codersdk/deployment.go
Expand Down
25 changes: 14 additions & 11 deletions site/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { GlobalSnackbar } from "./components/GlobalSnackbar/GlobalSnackbar"
import { dark } from "./theme"
import "./theme/globalFonts"
import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles"
import { LocalPreferencesProvider } from "contexts/LocalPreferencesContext"

const queryClient = new QueryClient({
defaultOptions: {
Expand All @@ -25,17 +26,19 @@ export const AppProviders: FC<PropsWithChildren> = ({ children }) => {
return (
<HelmetProvider>
<StyledEngineProvider injectFirst>
<ThemeProvider theme={dark}>
<CssBaseline enableColorScheme />
<ErrorBoundary>
<QueryClientProvider client={queryClient}>
<AuthProvider>
{children}
<GlobalSnackbar />
</AuthProvider>
</QueryClientProvider>
</ErrorBoundary>
</ThemeProvider>
<LocalPreferencesProvider>
<ThemeProvider theme={dark}>
<CssBaseline enableColorScheme />
<ErrorBoundary>
<QueryClientProvider client={queryClient}>
<AuthProvider>
{children}
<GlobalSnackbar />
</AuthProvider>
</QueryClientProvider>
</ErrorBoundary>
</ThemeProvider>
</LocalPreferencesProvider>
</StyledEngineProvider>
</HelmetProvider>
)
Expand Down
3 changes: 2 additions & 1 deletion site/src/components/Logs/Logs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,11 @@ const useStyles = makeStyles<
>((theme) => ({
root: {
minHeight: 156,
padding: theme.spacing(2, 0),
padding: theme.spacing(1, 0),
borderRadius: theme.shape.borderRadius,
overflowX: "auto",
background: theme.palette.background.default,
borderBottom: `1px solid ${theme.palette.divider}`,
},
scrollWrapper: {
minWidth: "fit-content",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({

{buildLogs && buildLogs.length > 0 && (
<WorkspaceBuildLogs
templateEditorPane
sx={{ borderRadius: 0 }}
hideTimestamps
logs={buildLogs}
/>
Expand Down
6 changes: 4 additions & 2 deletions site/src/components/Workspace/Workspace.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { withReactContext } from "storybook-react-context"
import EventSource from "eventsourcemock"
import { ProxyContext, getPreferredProxy } from "contexts/ProxyContext"
import { DashboardProviderContext } from "components/Dashboard/DashboardProvider"
import { WorkspaceBuildLogsSection } from "pages/WorkspacePage/WorkspaceBuildLogsSection"

const MockedAppearance = {
config: Mocks.MockAppearance,
Expand Down Expand Up @@ -152,7 +153,7 @@ export const FailedWithLogs: Story = {
},
},
},
failedBuildLogs: makeFailedBuildLogs(),
buildLogs: <WorkspaceBuildLogsSection logs={makeFailedBuildLogs()} />,
},
}

Expand All @@ -170,8 +171,8 @@ export const FailedWithRetry: Story = {
},
},
},
failedBuildLogs: makeFailedBuildLogs(),
canRetryDebugMode: true,
buildLogs: <WorkspaceBuildLogsSection logs={makeFailedBuildLogs()} />,
},
}

Expand Down Expand Up @@ -229,6 +230,7 @@ export const CancellationError: Story = {
message: "Job could not be canceled.",
}),
},
buildLogs: <WorkspaceBuildLogsSection logs={makeFailedBuildLogs()} />,
},
}

Expand Down
54 changes: 29 additions & 25 deletions site/src/components/Workspace/Workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Button from "@mui/material/Button"
import { makeStyles } from "@mui/styles"
import { Avatar } from "components/Avatar/Avatar"
import { AgentRow } from "components/Resources/AgentRow"
import { WorkspaceBuildLogs } from "components/WorkspaceBuildLogs/WorkspaceBuildLogs"
import {
ActiveTransition,
WorkspaceBuildProgress,
Expand Down Expand Up @@ -70,8 +69,10 @@ export interface WorkspaceProps {
sshPrefix?: string
template?: TypesGen.Template
quota_budget?: number
failedBuildLogs: TypesGen.ProvisionerJobLog[] | undefined
handleBuildRetry: () => void
buildLogs?: React.ReactNode
canChangeBuildLogsVisibility: boolean
isWorkspaceBuildLogsUIActive: boolean
}

/**
Expand Down Expand Up @@ -102,9 +103,11 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
sshPrefix,
template,
quota_budget,
failedBuildLogs,
handleBuildRetry,
templateWarnings,
buildLogs,
canChangeBuildLogsVisibility,
isWorkspaceBuildLogsUIActive,
}) => {
const styles = useStyles()
const navigate = useNavigate()
Expand Down Expand Up @@ -208,6 +211,8 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
canChangeVersions={canChangeVersions}
isUpdating={isUpdating}
isRestarting={isRestarting}
canChangeBuildLogsVisibility={canChangeBuildLogsVisibility}
isWorkspaceBuildLogsUIActive={isWorkspaceBuildLogsUIActive}
/>
</PageHeaderActions>
</FullWidthPageHeader>
Expand Down Expand Up @@ -259,28 +264,25 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
</Alert>
</Maybe>

{failedBuildLogs && (
<Stack>
<Alert
severity="error"
actions={
canRetryDebugMode && (
<Button
key={0}
onClick={handleBuildRetry}
variant="text"
size="small"
>
{t("actionButton.retryDebugMode")}
</Button>
)
}
>
<AlertTitle>Workspace build failed</AlertTitle>
<AlertDetail>{workspace.latest_build.job.error}</AlertDetail>
</Alert>
<WorkspaceBuildLogs logs={failedBuildLogs} />
</Stack>
{workspace.latest_build.job.error && (
<Alert
severity="error"
actions={
canRetryDebugMode && (
<Button
key={0}
onClick={handleBuildRetry}
variant="text"
size="small"
>
{t("actionButton.retryDebugMode")}
</Button>
)
}
>
<AlertTitle>Workspace build failed</AlertTitle>
<AlertDetail>{workspace.latest_build.job.error}</AlertDetail>
</Alert>
)}

{transitionStats !== undefined && (
Expand All @@ -290,6 +292,8 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
/>
)}

{buildLogs}

{typeof resources !== "undefined" && resources.length > 0 && (
<Resources
resources={resources}
Expand Down
44 changes: 44 additions & 0 deletions site/src/components/WorkspaceActions/WorkspaceActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import SettingsOutlined from "@mui/icons-material/SettingsOutlined"
import HistoryOutlined from "@mui/icons-material/HistoryOutlined"
import DeleteOutlined from "@mui/icons-material/DeleteOutlined"
import IconButton from "@mui/material/IconButton"
import Divider from "@mui/material/Divider"
import VisibilityOffOutlined from "@mui/icons-material/VisibilityOffOutlined"
import VisibilityOutlined from "@mui/icons-material/VisibilityOutlined"
import { useLocalPreferences } from "contexts/LocalPreferencesContext"

export interface WorkspaceActionsProps {
workspaceStatus: WorkspaceStatus
Expand All @@ -38,6 +42,8 @@ export interface WorkspaceActionsProps {
isRestarting: boolean
children?: ReactNode
canChangeVersions: boolean
canChangeBuildLogsVisibility: boolean
isWorkspaceBuildLogsUIActive: boolean
}

export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
Expand All @@ -54,6 +60,8 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
isUpdating,
isRestarting,
canChangeVersions,
canChangeBuildLogsVisibility,
isWorkspaceBuildLogsUIActive,
}) => {
const styles = useStyles()
const {
Expand All @@ -64,6 +72,9 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
const canBeUpdated = isOutdated && canAcceptJobs
const menuTriggerRef = useRef<HTMLButtonElement>(null)
const [isMenuOpen, setIsMenuOpen] = useState(false)
const localPreferences = useLocalPreferences()
const isBuildLogsVisible =
localPreferences.getPreference("buildLogsVisibility") === "visible"

// A mapping of button type to the corresponding React component
const buttonMapping: ButtonMapping = {
Expand Down Expand Up @@ -140,6 +151,39 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
<DeleteOutlined />
Delete
</MenuItem>

{isWorkspaceBuildLogsUIActive && (
<>
<Divider sx={{ borderColor: (theme) => theme.palette.divider }} />
{isBuildLogsVisible ? (
<MenuItem
disabled={!canChangeBuildLogsVisibility}
onClick={onMenuItemClick(() => {
localPreferences.setPreference(
"buildLogsVisibility",
"hide",
)
})}
>
<VisibilityOffOutlined />
Hide build logs
</MenuItem>
) : (
<MenuItem
disabled={!canChangeBuildLogsVisibility}
onClick={onMenuItemClick(() => {
localPreferences.setPreference(
"buildLogsVisibility",
"visible",
)
})}
>
<VisibilityOutlined />
Show build logs
</MenuItem>
)}
</>
)}
</Menu>
</div>
</div>
Expand Down
Loading