Skip to content

Commit 56adcce

Browse files
Merge pull request #959 from zenml-io/staging
Release 0.39.2
2 parents e666215 + dd7007d commit 56adcce

File tree

53 files changed

+624
-418
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+624
-418
lines changed

.github/workflows/claude-code-review.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
needs.check-team-member.outputs.is-team-member == 'true' &&
3131
github.actor != 'github-actions[bot]' &&
3232
github.event.issue.pull_request &&
33-
contains(github.event.comment.body, '@claude /full-review')
33+
contains(github.event.comment.body, '/claude /full-review')
3434
runs-on: ubuntu-latest
3535
timeout-minutes: 10
3636
concurrency:
@@ -127,11 +127,11 @@ jobs:
127127
- If component APIs changed, check for updates to JSDoc comments or usage examples.
128128
- If new environment variables added, ensure .env.example is updated.
129129
- If OpenAPI types changed (src/types/core.ts), verify it was generated not hand-edited.
130-
- Testing requirements:
131-
- Unit tests (*.spec.ts) for new utilities in src/lib/
132-
- E2E tests (e2e-tests/) for new user flows
133-
- Suggest test coverage for critical business logic
134-
- Verify test commands: pnpm test:unit, pnpm test:e2e, pnpm lint, pnpm build
130+
- Testing guidance (keep concise—avoid verbose or generic suggestions):
131+
- Only suggest tests directly relevant to the specific changes in this PR
132+
- Briefly note if new utilities in src/lib/ lack a *.spec.ts file
133+
- For UI changes, suggest 1-2 specific manual testing steps the author can perform
134+
- Do NOT suggest comprehensive test suites or generic test patterns unrelated to the PR scope
135135
- If migration or breaking changes are introduced, recommend adding explicit notes.
136136
137137
Review Format:

.github/workflows/claude.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ jobs:
3636
needs.check-team-member.outputs.is-team-member == 'true' &&
3737
github.actor != 'github-actions[bot]' &&
3838
(
39-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && !contains(github.event.comment.body, '/full-review')) ||
40-
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && !contains(github.event.comment.body, '/full-review')) ||
41-
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && !contains(github.event.review.body, '/full-review')) ||
42-
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
39+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '/claude') && !contains(github.event.comment.body, '/full-review')) ||
40+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '/claude') && !contains(github.event.comment.body, '/full-review')) ||
41+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '/claude') && !contains(github.event.review.body, '/full-review')) ||
42+
(github.event_name == 'issues' && (contains(github.event.issue.body, '/claude') || contains(github.event.issue.title, '/claude')))
4343
)
4444
runs-on: ubuntu-latest
4545
timeout-minutes: 10

.github/workflows/codex-comment.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
if: |
1616
github.event.issue.pull_request &&
17-
contains(github.event.comment.body, '@codex') &&
17+
contains(github.event.comment.body, '/codex') &&
1818
github.actor != 'github-actions[bot]'
1919
outputs:
2020
is-team-member: ${{ steps.check.outputs.is-member }}
@@ -62,7 +62,7 @@ jobs:
6262
id: mode
6363
run: |
6464
COMMENT="${{ github.event.comment.body }}"
65-
if echo "$COMMENT" | grep -qi '@codex /full-review'; then
65+
if echo "$COMMENT" | grep -qi '/codex /full-review'; then
6666
echo "mode=full-review" >> "$GITHUB_OUTPUT"
6767
else
6868
echo "mode=comment" >> "$GITHUB_OUTPUT"
@@ -126,7 +126,10 @@ jobs:
126126
Documentation & Testing:
127127
- Cross-check docs (README, CLAUDE.md, AGENTS.md) when user flows/components change.
128128
- Confirm env vars and OpenAPI types are updated where applicable.
129-
- Recommend test coverage (unit/e2e) for critical flows.
129+
- Testing (keep concise—avoid verbose or generic suggestions):
130+
* Only suggest tests directly relevant to the specific changes in this PR
131+
* For UI changes, suggest 1-2 specific manual testing steps
132+
* Do NOT recommend comprehensive test suites or patterns unrelated to the PR scope
130133
131134
Output Instructions:
132135
- Start with a summary of what the PR achieves.
@@ -163,4 +166,4 @@ jobs:
163166
repo: context.repo.repo,
164167
issue_number: context.issue.number,
165168
body
166-
});
169+
});

src/app/components/columns.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { DisplayDate } from "@/components/DisplayDate";
33
import { InlineAvatar } from "@/components/InlineAvatar";
44
import { ComponentSheet } from "@/components/stack-components/component-sheet";
55
import { ComponentBadge } from "@/components/stack-components/ComponentBadge";
6+
import { ActionCell } from "@/components/tables/action-cell";
67
import { snakeCaseToTitleCase } from "@/lib/strings";
78
import { sanitizeUrl } from "@/lib/url";
89
import { StackComponent } from "@/types/components";
@@ -89,9 +90,9 @@ export function getComponentList(): ColumnDef<StackComponent>[] {
8990
{
9091
id: "flavor",
9192
header: "Flavor",
92-
accessorFn: (row) => row.body?.flavor_name,
93+
accessorFn: (row) => row.resources?.flavor?.body?.display_name,
9394
cell: ({ row }) => {
94-
const flavor = row.original.body?.flavor_name;
95+
const flavor = row.original.resources?.flavor?.body?.display_name;
9596
return (
9697
<Tag
9798
rounded={false}
@@ -140,7 +141,11 @@ export function getComponentList(): ColumnDef<StackComponent>[] {
140141
id: "admin_actions",
141142
header: "",
142143
cell: ({ row }) => {
143-
return <ComponentDropdown id={row.original.id} />;
144+
return (
145+
<ActionCell>
146+
<ComponentDropdown id={row.original.id} />
147+
</ActionCell>
148+
);
144149
}
145150
}
146151
];

src/app/components/component-dropdown.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import DotsIcon from "@/assets/icons/dots-horizontal.svg?react";
21
import Edit from "@/assets/icons/edit.svg?react";
32
import Trash from "@/assets/icons/trash.svg?react";
43
import { DeleteStackComponentAlert } from "@/components/stack-components/delete-component/delete-alert";
4+
import { DropdownTriggerButton } from "@/components/dropdown-trigger-button";
55
import { routes } from "@/router/routes";
66
import {
77
DropdownMenu,
88
DropdownMenuContent,
99
DropdownMenuItem,
1010
DropdownMenuTrigger
1111
} from "@zenml-io/react-component-library/components/client";
12-
import { Button } from "@zenml-io/react-component-library/components/server";
1312
import { useState } from "react";
1413
import { useNavigate } from "react-router-dom";
1514
import { useComponentBulkDelete } from "./selector-context";
@@ -36,13 +35,9 @@ export function ComponentDropdown({ id }: Props) {
3635
/>
3736
<DropdownMenu>
3837
<DropdownMenuTrigger asChild>
39-
<Button
40-
intent="secondary"
41-
emphasis="minimal"
42-
className="flex aspect-square items-center justify-center p-0"
43-
>
44-
<DotsIcon className="h-4 w-4 shrink-0 fill-theme-text-tertiary" />
45-
</Button>
38+
<DropdownTriggerButton>
39+
<span className="sr-only">Open component actions</span>
40+
</DropdownTriggerButton>
4641
</DropdownMenuTrigger>
4742
<DropdownMenuContent align="end" sideOffset={7}>
4843
<DropdownMenuItem

src/app/components/create/config-step.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export function ConfiguratinStep({ flavor, type, handleBack }: Props) {
2323
navigate(routes.components.detail(id));
2424
}
2525

26+
const flavorName = flavor.body?.display_name ?? snakeCaseToTitleCase(flavor.name);
27+
2628
return (
2729
<>
2830
<Wizard.Header className="flex items-center gap-2">
@@ -36,7 +38,7 @@ export function ConfiguratinStep({ flavor, type, handleBack }: Props) {
3638
<span className="sr-only">Go step back</span>
3739
</Button>
3840
<span>
39-
Configure your {snakeCaseToTitleCase(flavor.name)} {snakeCaseToTitleCase(type)}
41+
Configure your {flavorName} {snakeCaseToTitleCase(type)}
4042
</span>
4143
</Wizard.Header>
4244
<Wizard.Body className="p-0">

src/app/onboarding/Setup/Items.tsx

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import Help from "@/assets/icons/help.svg?react";
21
import { Codesnippet } from "@/components/CodeSnippet";
32
import { HelpBox } from "@/components/fallback-pages/Helpbox";
43
import { ChecklistItem } from "@/components/onboarding/ChecklistItem";
54
import { useServerInfo } from "@/data/server/info-query";
65
import { getLoginCommand } from "@/lib/login-command";
76
import { OnboardingStep } from "@/types/onboarding";
8-
import { Box, Skeleton, buttonVariants } from "@zenml-io/react-component-library";
7+
import { Skeleton } from "@zenml-io/react-component-library";
8+
import { OnboardingHelpBox } from "./helpbox";
99
import { PipelineSnippet } from "./pipeline-snippet";
1010
import { SetProject } from "./set-project";
1111

@@ -23,7 +23,7 @@ export function ConnectZenMLStep({ completed, hasDownstreamStep, active }: Onboa
2323
<div>
2424
<p className="mb-1 text-text-sm text-theme-text-secondary">Install ZenML</p>
2525
<Codesnippet
26-
code={`pip install "zenml==${data ? data.version : <Skeleton className="w-7" />}"`}
26+
code={`uv pip install "zenml==${data ? data.version : <Skeleton className="w-7" />}"`}
2727
/>
2828
</div>
2929
<div>
@@ -51,32 +51,30 @@ export function RunFirstPipeline({ active, completed, hasDownstreamStep }: Onboa
5151
<p className="mb-1 text-text-sm text-theme-text-secondary">Run the training pipeline.</p>
5252
<Codesnippet code="python run.py" />
5353
</div>
54-
<Box className="flex w-full flex-wrap items-center justify-between gap-y-1 p-2">
55-
<div className="flex items-center gap-[10px]">
56-
<div className="flex h-7 w-7 items-center justify-center rounded-sm bg-teal-25">
57-
<Help className="h-5 w-5 fill-teal-400" />
58-
</div>
59-
<p>Do you need help?</p>
60-
</div>
61-
<div className="flex items-center gap-1">
62-
<a
63-
target="_blank"
64-
rel="noopener noreferrer"
65-
className={buttonVariants({ intent: "secondary", emphasis: "subtle", size: "md" })}
66-
href="https://github.com/zenml-io/zenml/blob/main/examples/quickstart/README.md"
67-
>
68-
Open the Readme
69-
</a>
70-
<a
71-
target="_blank"
72-
rel="noopener noreferrer"
73-
className={buttonVariants({ intent: "primary", emphasis: "subtle", size: "md" })}
74-
href="https://docs.zenml.io/user-guides/starter-guide/create-an-ml-pipeline"
75-
>
76-
Browse our docs
77-
</a>
78-
</div>
79-
</Box>
54+
<OnboardingHelpBox href="https://docs.zenml.io/user-guides/starter-guide/create-an-ml-pipeline" />
55+
</div>
56+
</ChecklistItem>
57+
);
58+
}
59+
60+
export function DeployPipeline({ active, completed, hasDownstreamStep }: OnboardingStep) {
61+
return (
62+
<ChecklistItem
63+
active={active}
64+
hasDownstream={hasDownstreamStep}
65+
completed={completed}
66+
title="Deploy your pipeline (2 min)"
67+
>
68+
<div className="flex flex-col gap-5">
69+
<div className="space-y-1">
70+
<p>Deploy the pipeline</p>
71+
<p className="text-text-sm text-theme-text-secondary">
72+
Deploying your pipeline provides you with an API endpoint that you can call to trigger a
73+
pipeline run.
74+
</p>
75+
</div>
76+
<Codesnippet code="zenml pipeline deploy run.hello_pipeline" />
77+
<OnboardingHelpBox href="https://docs.zenml.io/concepts/deployment" />
8078
</div>
8179
</ChecklistItem>
8280
);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Help from "@/assets/icons/help.svg?react";
2+
import { Box, buttonVariants } from "@zenml-io/react-component-library";
3+
4+
type OnboardingHelpBoxProps = {
5+
href: string;
6+
};
7+
8+
export function OnboardingHelpBox({ href }: OnboardingHelpBoxProps) {
9+
return (
10+
<Box className="flex w-full flex-wrap items-center justify-between gap-y-1 p-2">
11+
<div className="flex items-center gap-[10px]">
12+
<div className="flex h-7 w-7 items-center justify-center rounded-sm bg-teal-25">
13+
<Help className="h-5 w-5 fill-teal-400" />
14+
</div>
15+
<p>Do you need help?</p>
16+
</div>
17+
<a
18+
target="_blank"
19+
rel="noopener noreferrer"
20+
className={buttonVariants({ intent: "primary", emphasis: "subtle", size: "md" })}
21+
href={href}
22+
>
23+
Browse our docs
24+
</a>
25+
</Box>
26+
);
27+
}

src/app/onboarding/Setup/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { OnboardingResponse } from "@/types/onboarding";
77
import { Skeleton } from "@zenml-io/react-component-library";
88
import { useEffect, useRef } from "react";
99
import { useNavigate } from "react-router-dom";
10-
import { ConnectZenMLStep, RunFirstPipeline } from "./Items";
10+
import { ConnectZenMLStep, DeployPipeline, RunFirstPipeline } from "./Items";
1111

1212
export function OnboardingSetupList() {
1313
const onboarding = useOnboarding({ refetchInterval: 5000 });
@@ -32,6 +32,7 @@ function OnboardingSetupListContent({ onboarding, isLocalServer }: Props) {
3232
const { getItem, isFinished } = getOnboardingSetup(onboarding, isLocalServer);
3333
const connectStep = getItem("device_verified");
3434
const pipelineStep = getItem("pipeline_run");
35+
const deployStep = getItem("pipeline_deployed");
3536
const isInitialFinished = useRef(isFinished);
3637

3738
useEffect(() => {
@@ -58,6 +59,13 @@ function OnboardingSetupListContent({ onboarding, isLocalServer }: Props) {
5859
hasDownstreamStep={pipelineStep.hasDownStreamStep}
5960
/>
6061
</li>
62+
<li>
63+
<DeployPipeline
64+
active={deployStep.isActive}
65+
completed={deployStep.isCompleted}
66+
hasDownstreamStep={deployStep.hasDownStreamStep}
67+
/>
68+
</li>
6169
</ul>
6270
);
6371
}

src/app/pipelines/[pipelineId]/runs/RunsTable.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export function PipelineRunsTable({ params, columns }: Props) {
3636
<DataTable
3737
rowSelection={rowSelection}
3838
onRowSelectionChange={setRowSelection}
39+
getRowId={(row) => row.id}
3940
columns={columns}
4041
data={data.items}
4142
/>

0 commit comments

Comments
 (0)