Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
257e54b
feat: improved tutorial automation to work better with oso documentation
evanameyer1 May 29, 2025
e98e2e8
refactor: changed how commands are called to be more intuitive
evanameyer1 May 29, 2025
6933ed2
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
a91a25a
refactor: changed how commands are called to be more intuitive
evanameyer1 May 29, 2025
0b918a9
fix: incorrect filename
evanameyer1 May 29, 2025
a586b59
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
0714d73
fix: fixed problem with mdx sidebar
evanameyer1 May 29, 2025
58cb429
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
428c093
fix: fixed problem with locating notebook in temp directory
evanameyer1 May 29, 2025
13c2d9b
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
905fcf9
fix: run prettier over index.md too and make sure images are copied over
evanameyer1 May 29, 2025
ae7c49e
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
50e552a
fix: run prettier write on the tutorials folder in oso
evanameyer1 May 29, 2025
791bd53
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
7b44341
fix: more prettier errors
evanameyer1 May 29, 2025
ecd10d6
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
34c5a75
fix: more prettier errors
evanameyer1 May 29, 2025
89f9485
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
091c153
feat: CI checks
evanameyer1 May 29, 2025
648354b
Merge branch 'main' into tutorials
evanameyer1 May 29, 2025
fbee559
fix: fetch full history
evanameyer1 May 29, 2025
44d762a
test: testing CI checks
evanameyer1 May 29, 2025
2fc2a94
fix: requirements
evanameyer1 May 29, 2025
fbc8dd7
fix: CI checks fix
evanameyer1 May 29, 2025
128c786
fix: CI checks fix
evanameyer1 May 29, 2025
51d2992
fix: CI checks fix
evanameyer1 May 29, 2025
41dee98
fix: CI checks fix
evanameyer1 May 29, 2025
7c73f5d
fix: CI checks fix
evanameyer1 May 29, 2025
6cb24fb
feat: created readme outlining tutorial automation steps
evanameyer1 May 29, 2025
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
10 changes: 0 additions & 10 deletions .github/workflows/tutorial-automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,6 @@ jobs:
oso/apps/docs/docs/tutorials/
rsync -a mdx_build/apps/docs/docs/tutorials/index.* \
oso/apps/docs/docs/tutorials/

- name: Format new tutorials with Prettier
run: |
NEW_FILES=$(find mdx_build/apps/docs/docs/tutorials \
-type f \( -name '*.md' -o -name '*.mdx' \) \
-printf '%P\n')

for f in $NEW_FILES; do
npx prettier --write "oso/apps/docs/docs/tutorials/$f"
done

- name: Create or update PR
uses: peter-evans/create-pull-request@v5
Expand Down
92 changes: 92 additions & 0 deletions .github/workflows/tutorial-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Tutorial Checks
description: |
Runs checks on Jupyter notebooks in the tutorials/ directory:
- Ensures only .ipynb files are present
- Formats notebooks with Prettier
- Executes notebooks and fails on any errors
on:
pull_request:
paths:
- "tutorials/**"

jobs:
check-notebooks:
runs-on: ubuntu-latest

# list all files (in tutorials/) to ignore here
env:
IGNORED_FILES: |
tutorials/readme.md
steps:
- name: Check out PR branch
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Detect files added or modified in tutorials/
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
notebooks:
- added|modified: "tutorials/**"

- name: Enforce *.ipynb-only rule
if: steps.filter.outputs.notebooks == 'true'
run: |
# get everything under tutorials/ that changed
raw=$(git diff --name-only ${{github.event.pull_request.base.sha}} ${{github.sha}} -- tutorials/**/*.ipynb)

# filter out any ignored files
bad=$(printf "%s\n" "$not_ipynb" | grep -vFf <(echo "$IGNORED_FILES") || true)
if [ -n "$bad" ]; then
echo "::error::The following files are not allowed in tutorials/:"
echo "$bad"
exit 1
fi

- name: Export notebook list
if: steps.filter.outputs.notebooks == 'true'
id: list
run: |
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} -- tutorials/**/*.ipynb \
| paste -sd ' ' -)
echo "files=$files" >> "$GITHUB_OUTPUT"

- name: Set up Node & Prettier
if: steps.filter.outputs.notebooks == 'true'
uses: actions/setup-node@v4
with:
node-version: '20'

- run: npm install --global prettier
if: steps.filter.outputs.notebooks == 'true'

- name: Prettier --check
if: steps.filter.outputs.notebooks == 'true'
run: |
prettier --check ${{ steps.list.outputs.files }}

- name: Set up Python and Jupyter
if: steps.filter.outputs.notebooks == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install Jupyter tooling + kernel
if: steps.filter.outputs.notebooks == 'true'
run: |
pip install --quiet nbconvert ipykernel
python -m ipykernel install --name python3 --display-name "Python 3 (CI)" --user

- name: Execute notebooks
if: steps.filter.outputs.notebooks == 'true'
run: |
for nb in ${{ steps.list.outputs.files }}; do
echo "Running $nb"
jupyter nbconvert --execute \
--ExecutePreprocessor.kernel_name=python3 \
--to notebook "$nb" \
--output /tmp/out.ipynb
done

11 changes: 2 additions & 9 deletions tutorials/forecasting.ipynb
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Open in Colab](https://colab.research.google.com/drive/1zEDIOioIyvj7dGCPch9C9c5eGrKX5BDQ)\n"
]
},
{
"cell_type": "markdown",
"id": "ed162a68",
"metadata": {},
"source": [
"## TVL Forecasting with PyOSO\n",
"*A quick-start notebook guide on working with pyoso*"
"*A quickstart notebook guide on working with pyoso*"
]
},
{
Expand Down Expand Up @@ -1345,4 +1338,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
105 changes: 102 additions & 3 deletions tutorials/readme.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,108 @@
# Tutorials
# OSO Tutorials

Examples of applications and data science built on OSO's data platform. Each example is a notebook with you can fork and run yourself.
This folder contains runnable examples and data science tutorials built on OSO's data platform.

Each tutorial is a standalone Jupyter notebook (`.ipynb`) that can be viewed on Colab and is published to the OSO documentation site once approved.

---

## How to Add a New Tutorial

For complete documentation and to run the notebooks see: https://docs.opensource.observer/docs/tutorials/
Follow these steps to contribute your own tutorial to the platform:

### 1. Create & Upload Your Notebook

- Write your tutorial as a Jupyter notebook (`.ipynb`)
- Save it to the `tutorials/` folder in the **`insights`** repository (where this file lives)

### 2. Open a Pull Request

- Open a PR with your new tutorial notebook
- Use the title prefix: **`NEW TUTORIAL:`** so we can easily identify it
- Your PR will run automated checks defined in `.github/workflows/tutorial-checks.yml`. These checks **must pass**:
- The file is a valid `.ipynb`
- The notebook is formatted using Prettier
- **Every cell in the notebook runs successfully**

> ⚠️ **Make sure your tutorial is fully executable! CI will fail if any cell errors out.**

### 3. Add Reviewers

- Request review from [@evanameyer1](https://github.com/evanameyer1) or [@ccerv1](https://github.com/ccerv1)

Once your tutorial is approved and merged, continue to the next step.

---

## Publish Your Tutorial

If you are happy with your tutorial solely exist in our insights repo then you do not need to run either of these workflows. These simply offer ways to build more coverage of your tutorial.

We support two automation flows via `.github/workflows/tutorial-automation.yml`:

### 1. Generate a Colab Notebook

This creates a Colab link and inserts it into the notebook.

```bash
gh workflow run "Tutorial Automation" \
--ref main \
-f command=colab \
-f notebook="tutorials/your-notebook.ipynb" \
-f sidebar_position=0
````

* The Colab notebook will be auto-uploaded [here](https://drive.google.com/drive/u/2/folders/1ld_KWqNDMJl4NmzEFquNybCBph96hYDu)
* A line like `**[Open in Colab](https://...link...)**` will be added to the top of the notebook
* The changes are automatically committed and pushed to the same PR branch

### 2. Generate Docs Page (MDX)

This converts your notebook to a `.mdx` file for OSO's docs:

```bash
gh workflow run "Tutorial Automation" \
--ref main \
-f command=docs \
-f notebook="tutorials/your-notebook.ipynb" \
-f sidebar_position=10 # See below on how to pick this
```

* A new MDX page is created for your tutorial at [https://docs.opensource.observer/docs/tutorials/](https://docs.opensource.observer/docs/tutorials/)
* The tutorials index (`index.mdx`) is updated with an LLM-generated title and description that matches our existing docs style
* A PR will be created on the **`oso`** repo titled `"Add MDX tutorial(s)"`, which must pass OSO’s CI

---

## Sidebar Position Guide

The `sidebar_position` parameter controls where your tutorial appears in the docs sidebar:

* `0` = Top of the list (reserved for "Find a Tutorial")
* To **add your tutorial to the bottom**, find the bottommost tutorial in the docs sidebar:

* Click **“Edit this page”** on the tutorial
* Look for its `sidebar_position` in the frontmatter
* Use that number +1 for your new tutorial

> ⚠️ You **must** pass a `sidebar_position` even when running the `colab` workflow, but you can just use `0` there.

---

## Tip: Quoting Names in GitHub CLI

If you're using the workflow **name** instead of the workflow **ID**, wrap the name in quotes:

```bash
gh workflow run "Tutorial Automation" ...
```

Or, run this to find the workflow ID (recommended):

```bash
gh workflow list
```

---

Thanks for contributing to the OSO community! 🚀