Skip to content

Commit 1f95bed

Browse files
tschmrenovate[bot]
andauthored
Comments and version update in deploy.yml (#4)
* ignore .idea * renovate for updates * deployment with comments * Update renovate.json * chore(deps): update astral-sh/setup-uv action to v6 * cleaning comments in deploy.yml * moving build script * build with comments now * Update build.py --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent a716404 commit 1f95bed

File tree

6 files changed

+247
-138
lines changed

6 files changed

+247
-138
lines changed

.github/renovate.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": [
3+
"config:recommended",
4+
":enablePreCommit",
5+
":dependencyDashboard",
6+
":semanticCommits",
7+
":pinVersions"
8+
],
9+
"enabledManagers": [
10+
"github-actions"
11+
]
12+
}

.github/scripts/build.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Build script for marimo notebooks.
4+
5+
This script exports marimo notebooks to HTML/WebAssembly format and generates
6+
an index.html file that lists all the notebooks. It handles both regular notebooks
7+
(from the notebooks/ directory) and apps (from the apps/ directory).
8+
9+
The script can be run from the command line with optional arguments:
10+
python .github/scripts/build.py [--output-dir OUTPUT_DIR]
11+
12+
The exported files will be placed in the specified output directory (default: _site).
13+
"""
14+
15+
import os
16+
import subprocess
17+
import argparse
18+
from typing import List, Optional, Dict, Any, Union
19+
from pathlib import Path
20+
21+
22+
def export_html_wasm(notebook_path: str, output_dir: str, as_app: bool = False) -> bool:
23+
"""Export a single marimo notebook to HTML/WebAssembly format.
24+
25+
This function takes a marimo notebook (.py file) and exports it to HTML/WebAssembly format.
26+
If as_app is True, the notebook is exported in "run" mode with code hidden, suitable for
27+
applications. Otherwise, it's exported in "edit" mode, suitable for interactive notebooks.
28+
29+
Args:
30+
notebook_path (str): Path to the marimo notebook (.py file) to export
31+
output_dir (str): Directory where the exported HTML file will be saved
32+
as_app (bool, optional): Whether to export as an app (run mode) or notebook (edit mode).
33+
Defaults to False.
34+
35+
Returns:
36+
bool: True if export succeeded, False otherwise
37+
"""
38+
# Convert .py extension to .html for the output file
39+
output_path: str = notebook_path.replace(".py", ".html")
40+
41+
# Base command for marimo export
42+
cmd: List[str] = ["marimo", "export", "html-wasm"]
43+
44+
# Configure export mode based on whether it's an app or a notebook
45+
if as_app:
46+
print(f"Exporting {notebook_path} to {output_path} as app")
47+
cmd.extend(["--mode", "run", "--no-show-code"]) # Apps run in "run" mode with hidden code
48+
else:
49+
print(f"Exporting {notebook_path} to {output_path} as notebook")
50+
cmd.extend(["--mode", "edit"]) # Notebooks run in "edit" mode
51+
52+
try:
53+
# Create full output path and ensure directory exists
54+
output_file: str = os.path.join(output_dir, output_path)
55+
os.makedirs(os.path.dirname(output_file), exist_ok=True)
56+
57+
# Add notebook path and output file to command
58+
cmd.extend([notebook_path, "-o", output_file])
59+
60+
# Run marimo export command
61+
print(cmd)
62+
subprocess.run(cmd, capture_output=True, text=True, check=True)
63+
return True
64+
except subprocess.CalledProcessError as e:
65+
# Handle marimo export errors
66+
print(f"Error exporting {notebook_path}:")
67+
print(e.stderr)
68+
return False
69+
except Exception as e:
70+
# Handle unexpected errors
71+
print(f"Unexpected error exporting {notebook_path}: {e}")
72+
return False
73+
74+
75+
def generate_index(all_notebooks: List[str], output_dir: str) -> None:
76+
"""Generate an index.html file that lists all the notebooks.
77+
78+
This function creates an HTML index page that displays links to all the exported
79+
notebooks. The index page includes the marimo logo and displays each notebook
80+
with a formatted title and a link to open it.
81+
82+
Args:
83+
all_notebooks (List[str]): List of paths to all the notebooks
84+
output_dir (str): Directory where the index.html file will be saved
85+
86+
Returns:
87+
None
88+
"""
89+
print("Generating index.html")
90+
91+
# Create the full path for the index.html file
92+
index_path: str = os.path.join(output_dir, "index.html")
93+
94+
# Ensure the output directory exists
95+
os.makedirs(output_dir, exist_ok=True)
96+
97+
try:
98+
# Open the index.html file for writing
99+
with open(index_path, "w") as f:
100+
# Write the HTML header and page structure
101+
f.write(
102+
"""<!DOCTYPE html>
103+
<html lang="en">
104+
<head>
105+
<meta charset="UTF-8" />
106+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
107+
<title>marimo</title>
108+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
109+
</head>
110+
<body class="font-sans max-w-2xl mx-auto p-8 leading-relaxed">
111+
<div class="mb-8">
112+
<img src="https://raw.githubusercontent.com/marimo-team/marimo/main/docs/_static/marimo-logotype-thick.svg" alt="marimo" class="h-20" />
113+
</div>
114+
<div class="grid gap-4">
115+
"""
116+
)
117+
# Process each notebook and create a card for it
118+
for notebook in all_notebooks:
119+
# Extract the notebook name from the path and remove the .py extension
120+
notebook_name: str = notebook.split("/")[-1].replace(".py", "")
121+
122+
# Format the display name by replacing underscores with spaces and capitalizing
123+
display_name: str = notebook_name.replace("_", " ").title()
124+
125+
# Write the HTML for the notebook card
126+
f.write(
127+
f' <div class="p-4 border border-gray-200 rounded">\n'
128+
f' <h3 class="text-lg font-semibold mb-2">{display_name}</h3>\n'
129+
f' <div class="flex gap-2">\n'
130+
f' <a href="{notebook.replace(".py", ".html")}" class="px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded">Open Notebook</a>\n'
131+
f" </div>\n"
132+
f" </div>\n"
133+
)
134+
# Write the HTML footer
135+
f.write(
136+
""" </div>
137+
</body>
138+
</html>"""
139+
)
140+
except IOError as e:
141+
# Handle file I/O errors
142+
print(f"Error generating index.html: {e}")
143+
144+
145+
def main() -> None:
146+
"""Main function to build marimo notebooks.
147+
148+
This function:
149+
1. Parses command line arguments
150+
2. Finds all marimo notebooks in the 'notebooks' and 'apps' directories
151+
3. Exports each notebook to HTML/WebAssembly format
152+
4. Generates an index.html file that lists all the notebooks
153+
154+
Command line arguments:
155+
--output-dir: Directory where the exported files will be saved (default: _site)
156+
157+
Returns:
158+
None
159+
"""
160+
# Set up command line argument parsing
161+
parser: argparse.ArgumentParser = argparse.ArgumentParser(description="Build marimo notebooks")
162+
parser.add_argument(
163+
"--output-dir", default="_site", help="Output directory for built files"
164+
)
165+
args: argparse.Namespace = parser.parse_args()
166+
167+
# Initialize empty list to store all notebook paths
168+
all_notebooks: List[str] = []
169+
170+
# Look for notebooks in both the notebooks/ and apps/ directories
171+
for directory in ["notebooks", "apps"]:
172+
dir_path: Path = Path(directory)
173+
if not dir_path.exists():
174+
print(f"Warning: Directory not found: {dir_path}")
175+
continue
176+
177+
# Find all Python files recursively in the directory
178+
all_notebooks.extend(str(path) for path in dir_path.rglob("*.py"))
179+
180+
# Exit if no notebooks were found
181+
if not all_notebooks:
182+
print("No notebooks found!")
183+
return
184+
185+
# Export each notebook to HTML/WebAssembly format
186+
# Files in the apps/ directory are exported as apps (run mode)
187+
# Files in the notebooks/ directory are exported as notebooks (edit mode)
188+
for nb in all_notebooks:
189+
export_html_wasm(nb, args.output_dir, as_app=nb.startswith("apps/"))
190+
191+
# Generate the index.html file that lists all notebooks
192+
generate_index(all_notebooks, args.output_dir)
193+
194+
195+
if __name__ == "__main__":
196+
main()

.github/workflows/deploy.yml

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,74 @@
1+
# This workflow builds and deploys marimo notebooks to GitHub Pages
2+
# It runs automatically when changes are pushed to the main branch or can be triggered manually
3+
14
name: Deploy to GitHub Pages
25

6+
# Defines when the workflow will run
37
on:
48
push:
5-
branches: ['main']
6-
workflow_dispatch:
9+
branches: ['main'] # Trigger on pushes to main branch
10+
workflow_dispatch: # Allow manual triggering from the GitHub UI
711

12+
# Concurrency settings to manage multiple workflow runs
813
concurrency:
9-
group: 'pages'
10-
cancel-in-progress: false
14+
group: 'pages' # Only one workflow in the 'pages' group can run at a time
15+
cancel-in-progress: false # Don't cancel in-progress runs when a new one is triggered
1116

17+
# Environment variables used by the workflow
1218
env:
13-
UV_SYSTEM_PYTHON: 1
19+
UV_SYSTEM_PYTHON: 1 # Use system Python with uv package manager
1420

1521
jobs:
22+
# The build job exports marimo notebooks to static HTML/WebAssembly
1623
build:
17-
runs-on: ubuntu-latest
24+
runs-on: ubuntu-latest # Use the latest Ubuntu runner
1825
steps:
26+
# Check out the repository code
1927
- uses: actions/checkout@v4
2028

29+
# Install uv package manager for faster Python package installation
2130
- name: 🚀 Install uv
22-
uses: astral-sh/setup-uv@v4
31+
uses: astral-sh/setup-uv@v6
2332

33+
# Set up Python environment
2434
- name: 🐍 Set up Python
2535
uses: actions/setup-python@v5
2636
with:
27-
python-version: 3.12
37+
python-version: 3.12 # Use Python 3.12 for the build
2838

39+
# Install marimo and other required dependencies
2940
- name: 📦 Install dependencies
3041
run: |
3142
uv pip install marimo
3243
44+
# Run the build script to export notebooks to WebAssembly
3345
- name: 🛠️ Export notebooks
3446
run: |
35-
python scripts/build.py
47+
python .github/scripts/build.py # This script exports all notebooks to the _site directory
3648
49+
# Upload the generated site as an artifact for the deploy job
3750
- name: 📤 Upload artifact
3851
uses: actions/upload-pages-artifact@v3
3952
with:
40-
path: _site
53+
path: _site # Directory containing the built site
4154

55+
# The deploy job publishes the built site to GitHub Pages
4256
deploy:
43-
needs: build
57+
needs: build # This job depends on the build job completing successfully
4458

59+
# Required permissions for the GitHub Pages deployment
4560
permissions:
46-
pages: write
47-
id-token: write
61+
pages: write # Permission to deploy to Pages
62+
id-token: write # Permission to verify the deployment
4863

64+
# Configure the deployment environment
4965
environment:
50-
name: github-pages
51-
url: ${{ steps.deployment.outputs.page_url }}
52-
runs-on: ubuntu-latest
66+
name: github-pages # Deploy to the github-pages environment
67+
url: ${{ steps.deployment.outputs.page_url }} # Use the URL from the deployment step
68+
69+
runs-on: ubuntu-latest # Use the latest Ubuntu runner
5370
steps:
71+
# Deploy the site to GitHub Pages using the official action
5472
- name: 🚀 Deploy to GitHub Pages
55-
id: deployment
56-
uses: actions/deploy-pages@v4
73+
id: deployment # ID used to reference this step's outputs
74+
uses: actions/deploy-pages@v4 # GitHub's official Pages deployment action

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ cython_debug/
167167
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
168168
# and can be added to the global gitignore or merged into this file. For a more nuclear
169169
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
170-
#.idea/
170+
.idea/
171171

172172
# PyPI configuration file
173173
.pypirc

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ df = pl.read_csv(mo.notebook_location() / "public" / "penguins.csv")
3737

3838
## 🧪 Testing
3939

40-
To test the export process, run `scripts/build.py` from the root directory.
40+
To test the export process, run `.github/scripts/build.py` from the root directory.
4141

4242
```bash
43-
python scripts/build.py
43+
python .github/scripts/build.py
4444
```
4545

4646
This will export all notebooks in a folder called `_site/` in the root directory. Then to serve the site, run:

0 commit comments

Comments
 (0)