Skip to content

style: format visual evidence files #165

style: format visual evidence files

style: format visual evidence files #165

Workflow file for this run

name: Deploy Visual Report to GitHub Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install system dependencies (OSMesa for headless rendering)
run: sudo apt-get update && sudo apt-get install -y libosmesa6-dev
- name: Install package with demo + WBC dependencies
run: uv pip install --system -e ".[demo,wbc]"
- name: Install unitree SDK, CPU PyTorch, and lerobot
run: |
# unitree-sdk2py is installed directly from the fork (not a pyproject
# extra — PyPI rejects packages with git-based direct references).
uv pip install --system "unitree-sdk2py @ git+https://github.com/MiaoDX-fork-and-pruning/unitree_sdk2_python_uv.git"
uv pip install --system torch --index-url https://download.pytorch.org/whl/cpu
uv pip install --system lerobot
uv pip install --system loguru pygame scipy pyyaml
- name: Cache HuggingFace models
uses: actions/cache@v4
with:
path: ~/.cache/huggingface/hub
key: hf-models-${{ runner.os }}-v1
- name: Run MuJoCo grasp example
env:
MUJOCO_GL: osmesa
run: python examples/demos/mujoco/grasp.py --report --output-dir ./harness_output
- name: Run G1 WBC reach example
env:
MUJOCO_GL: osmesa
run: python examples/demos/g1/wbc_reach.py --report --output-dir ./harness_output
- name: Run LeRobot G1 locomotion example
env:
MUJOCO_GL: osmesa
run: python examples/demos/g1/lerobot_locomotion.py --report --output-dir ./harness_output
- name: Run native LeRobot G1 (GR00T) example
env:
MUJOCO_GL: osmesa
run: python examples/demos/g1/lerobot_native.py --controller groot --report --output-dir ./harness_output
- name: Run native LeRobot G1 (SONIC) example
env:
MUJOCO_GL: osmesa
run: python examples/demos/g1/lerobot_native.py --controller sonic --report --output-dir ./harness_output
- name: Run SONIC planner example
env:
MUJOCO_GL: osmesa
run: python examples/demos/sonic/locomotion.py --report --assert-success --output-dir ./harness_output
- name: Run SONIC motion tracking example
env:
MUJOCO_GL: osmesa
run: python examples/demos/sonic/tracking.py --report --assert-success --output-dir ./harness_output
- name: Build static pages (landing)
run: |
mkdir -p _site
cp .github/pages/index.html _site/index.html
- name: Build demo reports
run: |
# --- Demo 1: Simple Grasp (with Meshcat 3D) ---
# The report's iframe src values are relative to the harness output
# root (e.g. mujoco_grasp/trial_001/<cp>/meshcat_scene.html), so the
# deployed checkpoint assets must preserve that nesting under
# _site/grasp/ or the 3D scenes 404.
mkdir -p _site/grasp
cp harness_output/report.html _site/grasp/index.html
for cp_dir in harness_output/mujoco_grasp/trial_001/*/; do
cp_name=$(basename "$cp_dir")
dest="_site/grasp/mujoco_grasp/trial_001/${cp_name}"
mkdir -p "$dest"
cp "${cp_dir}"*_rgb.png "$dest/" 2>/dev/null || true
cp "${cp_dir}"*_depth_viz.png "$dest/" 2>/dev/null || true
cp "${cp_dir}"meshcat_scene.html "$dest/" 2>/dev/null || true
cp "${cp_dir}"metadata.json "$dest/" 2>/dev/null || true
cp "${cp_dir}"state.json "$dest/" 2>/dev/null || true
done
cp harness_output/mujoco_grasp/trial_001/autonomous_report.json _site/grasp/ 2>/dev/null || true
cp harness_output/mujoco_grasp/trial_001/alarms.json _site/grasp/ 2>/dev/null || true
cp harness_output/mujoco_grasp/trial_001/phase_manifest.json _site/grasp/ 2>/dev/null || true
# --- Demo 2: G1 WBC Reach ---
# As with the grasp demo, the report references meshcat scenes by
# their output-relative path (g1_wbc_reach/trial_001/<cp>/...), so the
# deployed assets keep that nesting under _site/g1-reach/.
mkdir -p _site/g1-reach
cp harness_output/g1_wbc_reach_report.html _site/g1-reach/index.html
for cp_dir in harness_output/g1_wbc_reach/trial_001/*/; do
cp_name=$(basename "$cp_dir")
dest="_site/g1-reach/g1_wbc_reach/trial_001/${cp_name}"
mkdir -p "$dest"
cp "${cp_dir}"*_rgb.png "$dest/" 2>/dev/null || true
cp "${cp_dir}"*_depth_viz.png "$dest/" 2>/dev/null || true
cp "${cp_dir}"meshcat_scene.html "$dest/" 2>/dev/null || true
cp "${cp_dir}"metadata.json "$dest/" 2>/dev/null || true
cp "${cp_dir}"state.json "$dest/" 2>/dev/null || true
done
# --- Demo 3: LeRobot G1 Locomotion ---
mkdir -p _site/g1-loco
cp harness_output/lerobot_g1_report.html _site/g1-loco/index.html
for cp_dir in harness_output/lerobot_g1/trial_001/*/; do
cp_name=$(basename "$cp_dir")
mkdir -p "_site/g1-loco/${cp_name}"
cp "${cp_dir}"*_rgb.png "_site/g1-loco/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"metadata.json "_site/g1-loco/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"state.json "_site/g1-loco/${cp_name}/" 2>/dev/null || true
done
# --- Demo 4a: Native LeRobot G1 (GR00T) ---
mkdir -p _site/g1-native-groot
cp harness_output/lerobot_g1_native_groot_report.html _site/g1-native-groot/index.html
for cp_dir in harness_output/lerobot_g1_native_groot/trial_001/*/; do
cp_name=$(basename "$cp_dir")
mkdir -p "_site/g1-native-groot/${cp_name}"
cp "${cp_dir}"*_rgb.png "_site/g1-native-groot/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"metadata.json "_site/g1-native-groot/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"state.json "_site/g1-native-groot/${cp_name}/" 2>/dev/null || true
done
# --- Demo 4b: Native LeRobot G1 (SONIC) ---
mkdir -p _site/g1-native-sonic
cp harness_output/lerobot_g1_native_sonic_report.html _site/g1-native-sonic/index.html
for cp_dir in harness_output/lerobot_g1_native_sonic/trial_001/*/; do
cp_name=$(basename "$cp_dir")
mkdir -p "_site/g1-native-sonic/${cp_name}"
cp "${cp_dir}"*_rgb.png "_site/g1-native-sonic/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"metadata.json "_site/g1-native-sonic/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"state.json "_site/g1-native-sonic/${cp_name}/" 2>/dev/null || true
done
# --- Demo 5: SONIC Planner ---
mkdir -p _site/sonic-planner
cp harness_output/sonic_locomotion_report.html _site/sonic-planner/index.html
for cp_dir in harness_output/sonic_locomotion/trial_001/*/; do
cp_name=$(basename "$cp_dir")
mkdir -p "_site/sonic-planner/${cp_name}"
cp "${cp_dir}"*_rgb.png "_site/sonic-planner/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"metadata.json "_site/sonic-planner/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"state.json "_site/sonic-planner/${cp_name}/" 2>/dev/null || true
done
# --- Demo 6: SONIC Motion Tracking ---
mkdir -p _site/sonic
cp harness_output/sonic_tracking_report.html _site/sonic/index.html
for cp_dir in harness_output/sonic_tracking/trial_001/*/; do
cp_name=$(basename "$cp_dir")
mkdir -p "_site/sonic/${cp_name}"
cp "${cp_dir}"*_rgb.png "_site/sonic/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"metadata.json "_site/sonic/${cp_name}/" 2>/dev/null || true
cp "${cp_dir}"state.json "_site/sonic/${cp_name}/" 2>/dev/null || true
done
- name: Upload Pages artifact
if: always()
uses: actions/upload-pages-artifact@v3
with:
path: _site
- name: Upload site content for downstream workflows
if: always()
uses: actions/upload-artifact@v4
with:
name: site-content
path: _site
deploy:
needs: build
if: ${{ !cancelled() }}
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4