Skip to content

Commit f9f2d5c

Browse files
authored
Merge pull request #9 from zenml-io/feature/various-tutorial-fixes
Improve tutorial presentation and user experience
2 parents 693ce80 + eda4ab0 commit f9f2d5c

File tree

24 files changed

+182
-116
lines changed

24 files changed

+182
-116
lines changed

.claude/settings.local.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(rg:*)",
5+
"Bash(grep:*)",
6+
"Bash(npm run compile:*)"
7+
],
8+
"deny": []
9+
}
10+
}

.github/workflows/build-extensions.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ jobs:
4141
- name: Build theme extension
4242
run: |
4343
echo "Building theme extension..."
44-
cd themes && npx @vscode/vsce package --out ../zenml-color-theme.vsix
44+
cd themes && npx @vscode/vsce package --out ./zenml-color-theme-0.0.1.vsix
4545
46-
- name: Verify extensions were built
46+
- name: Verify extensions were builts
4747
run: |
4848
echo "Checking built extensions..."
4949
if [ -d ".devcontainer/extensions" ]; then
@@ -54,11 +54,11 @@ jobs:
5454
exit 1
5555
fi
5656
57-
if [ -f "zenml-color-theme.vsix" ]; then
57+
if [ -f "themes/zenml-color-theme-0.0.1.vsix" ]; then
5858
echo "Theme extension built successfully:"
59-
ls -la zenml-color-theme.vsix
59+
ls -la themes/zenml-color-theme-0.0.1.vsix
6060
else
61-
echo "ERROR: zenml-color-theme.vsix not found"
61+
echo "ERROR: zenml-color-theme-0.0.1.vsix not found"
6262
exit 1
6363
fi
6464
@@ -72,7 +72,7 @@ jobs:
7272
uses: actions/upload-artifact@v4
7373
with:
7474
name: theme-extension
75-
path: zenml-color-theme.vsix
75+
path: themes/zenml-color-theme-0.0.1.vsix
7676

7777
- name: Commit and push built extensions
7878
# Only commit on push to main/develop branches, not on PRs
@@ -83,7 +83,7 @@ jobs:
8383
8484
# Add the built extensions to git
8585
git add .devcontainer/extensions/zenml-codespace-tutorial-*.vsix
86-
git add zenml-color-theme.vsix
86+
git add themes/zenml-color-theme-0.0.1.vsix
8787
8888
# Check if there are any changes to commit
8989
if git diff --staged --quiet; then

assets/main.css

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ header {
319319
}
320320

321321
.tutorial-title h2 {
322-
font-size: 1rem;
322+
font-size: 1.25rem;
323323
font-weight: 600;
324324
color: var(--zenml-dark);
325325
margin: 0;
@@ -448,13 +448,68 @@ footer .run-pipeline-button.running {
448448
footer .run-pipeline-button.completed {
449449
background: var(--zenml-green);
450450
color: white;
451+
cursor: default;
452+
}
453+
454+
footer .run-pipeline-button.completed:hover {
455+
background: var(--zenml-green);
456+
transform: none;
457+
box-shadow: none;
451458
}
452459

453460
footer .run-pipeline-button.failed {
454461
background: var(--zenml-red);
455462
color: white;
456463
}
457464

465+
466+
/* Pipeline button group */
467+
.pipeline-button-group {
468+
display: flex;
469+
gap: 8px;
470+
align-items: center;
471+
}
472+
473+
/* Dashboard button styling - smaller variant */
474+
.dashboard-button-small {
475+
background: var(--vscode-button-secondaryBackground);
476+
border: 1px solid var(--vscode-sideBar-border);
477+
color: var(--vscode-button-secondaryForeground);
478+
padding: 9px 16px;
479+
border-radius: 6px;
480+
font-size: 14px;
481+
font-weight: 500;
482+
cursor: pointer;
483+
transition: all 0.3s ease;
484+
display: flex;
485+
align-items: center;
486+
gap: 6px;
487+
justify-content: center;
488+
font-family: "Inter", sans-serif;
489+
margin: 0;
490+
height: 38px;
491+
text-decoration: none;
492+
flex-shrink: 0;
493+
white-space: nowrap;
494+
box-sizing: border-box;
495+
}
496+
497+
.dashboard-button-small:hover {
498+
background: var(--vscode-button-secondaryHoverBackground);
499+
transform: translateY(-1px);
500+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
501+
color: var(--vscode-button-secondaryForeground);
502+
text-decoration: none;
503+
}
504+
505+
.dashboard-button-small:active {
506+
transform: translateY(0);
507+
}
508+
509+
.dashboard-button-small .codicon {
510+
font-size: 14px;
511+
}
512+
458513
#progress {
459514
height: 4px;
460515
background-color: var(--vscode-progressBar-background);

assets/main.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,8 @@
476476
} else if (status === "completed" || status === "cached") {
477477
runButton.innerHTML = `<i class="checkmark">✓</i> ${buttonTexts[status]}`;
478478
//@ts-ignore
479-
runButton.disabled = false;
479+
runButton.disabled = true;
480+
runButton.style.cursor = "default";
480481
} else if (status === "failed") {
481482
runButton.innerHTML = `<i class="codicon codicon-error"></i> ${buttonTexts[status]}`;
482483
//@ts-ignore
@@ -493,14 +494,18 @@
493494
}
494495

495496
function showDashboardUrl(url) {
496-
const dashboardLink = document.getElementById("dashboard-link");
497-
const dashboardUrl = document.getElementById("dashboard-url");
497+
const dashboardButton = document.getElementById("dashboard-button");
498498

499-
if (dashboardLink && dashboardUrl) {
499+
if (dashboardButton) {
500500
//@ts-ignore
501-
dashboardUrl.href = url;
502-
dashboardUrl.textContent = "View Pipeline in Dashboard";
503-
dashboardLink.style.display = "flex";
501+
dashboardButton.href = url;
502+
dashboardButton.style.display = "flex";
503+
504+
// Add click handler to open in external browser
505+
dashboardButton.addEventListener('click', function(e) {
506+
e.preventDefault();
507+
vscode.postMessage({ type: "openDashboard", url: url });
508+
});
504509
}
505510
}
506511

pipelines/caching/cache_pipeline.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111

1212
@step(enable_cache=True)
1313
def slow_step() -> Annotated[int, "answer"]:
14-
logger.info("Starting slow computation (3 seconds)...")
14+
logger.info("🔄 Actually computing result... (sleeping 3 seconds)")
1515
time.sleep(3)
16-
logger.info("Computation completed!")
1716
return 42
1817

1918

@@ -23,10 +22,17 @@ def cache_pipeline():
2322

2423

2524
if __name__ == "__main__":
26-
logger.info("First run - will take ~3 seconds")
27-
cache_pipeline() # first run ~3 s
28-
29-
logger.info("Second run - should be instant (cache hit)")
30-
cache_pipeline() # second run instant (cache hit)
25+
logger.info("\n" + "="*60)
26+
logger.info(">>> RUN 1: First execution (no cache available)")
27+
logger.info("="*60)
28+
cache_pipeline()
29+
30+
logger.info("\n" + "="*60)
31+
logger.info(">>> RUN 2: Second execution (cache should be used)")
32+
logger.info("="*60)
33+
cache_pipeline()
34+
35+
logger.info("\n💡 Notice: The step's log message only appears in Run 1!")
36+
logger.info(" In Run 2, the step was skipped entirely due to caching.")
3137

3238
log_dashboard_urls("cache_pipeline")

pipelines/caching/caching.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# Caching - Smart Re-runs
2-
3-
Learn how ZenML's caching system can save you time by avoiding redundant computations.
4-
51
## What you'll learn
62

73
- How to enable caching on steps
@@ -28,4 +24,5 @@ def slow_step() -> Annotated[int, "answer"]:
2824

2925
## Try it yourself
3026

31-
Run this pipeline twice! The first run takes ~3 seconds, the second is instant thanks to caching.
27+
Run this pipeline twice! The first run takes ~3 seconds, the second is instant
28+
thanks to caching.

pipelines/completion/completion.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
You Completed the Tutorial
1616

17-
You've successfully completed the **ZenML Interactive Tutorial** and mastered the fundamentals of MLOps with ZenML!
17+
You've successfully completed the **ZenML Interactive Tutorial** and mastered the fundamentals of using ZenML for MLOps!
1818

1919
</div>
2020
<div class="right-column">

pipelines/fanOut/fanOut.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# Fan-out/Fan-in - Parallel Processing
2-
3-
Learn how to create parallel workflows that split work across multiple steps and then combine the results.
4-
51
## What you'll learn
62

73
- How to create parallel processing patterns
@@ -29,4 +25,5 @@ def fan_pipeline(parallel: int = 4):
2925

3026
## Try it yourself
3127

32-
Run this pipeline to see how it processes data in parallel across multiple steps, then combines the results!
28+
Run this pipeline to see how it processes data in parallel across multiple
29+
steps, then combines the results!

pipelines/fanOut/fan_pipeline.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
"""
2-
Shows parallel fan-out (multiple identical steps) and a fan-in step that
3-
gathers all their outputs via the Client API.
4-
5-
Run it once and observe the printed summary. Re-run: cache is OFF so you
6-
see the steps execute every time.
7-
"""
8-
91
from typing_extensions import Annotated
102
from zenml import get_step_context, pipeline, step
113
from zenml.client import Client

pipelines/helloWorld/helloWorld.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# Hello World - Steps & Pipelines
2-
31
Welcome to your first ZenML pipeline! This tutorial introduces the fundamental concepts of **steps** and **pipelines**.
42

53
## What you'll learn
@@ -30,4 +28,5 @@ def hello_pipeline():
3028

3129
## Try it yourself
3230

33-
Click the **Run Pipeline** button to execute your first ZenML pipeline and see the output!
31+
Click the **Run Pipeline** button to execute your first ZenML pipeline and see
32+
the output!

0 commit comments

Comments
 (0)