Skip to content

Latest commit

 

History

History
170 lines (119 loc) · 5.58 KB

File metadata and controls

170 lines (119 loc) · 5.58 KB

GitHub Pages Deployment

This repo deploys the marimo notebook suite as WebAssembly HTML exports.

Workflow

The GitHub Actions workflow at .github/workflows/pages.yml runs on pushes to dev or main, and on manual dispatch.

It:

  1. installs dependencies with uv
  2. lints src/, notebooks/, and scripts/
  3. validates each notebook with marimo check
  4. exports each notebook with marimo export html-wasm
  5. uploads the generated site/ directory as the GitHub Pages artifact

One-Go Redeploy

For a local rebuild and preview:

uv sync
uv run python scripts/build_pages.py
uv run python -m http.server --directory site 8010

If port 8010 is already busy, use the next available port:

uv run python -m http.server --directory site 8011

For GitHub Pages:

uv sync --frozen --extra dev
uv run ruff check src notebooks scripts
uv run python scripts/build_pages.py
git status --short
git add .github/workflows/pages.yml README.md docs notebooks scripts pyproject.toml uv.lock
git commit -m "Update marimo notebook suite"
git push origin main

The push triggers the Deploy GitHub Pages workflow automatically when Pages is set to GitHub Actions. Use the manual workflow button only for the first deployment or when you want to rerun a deploy without a new commit.

Repository Settings

In GitHub, set Pages to use GitHub Actions as the source:

Settings -> Pages -> Build and deployment -> Source -> GitHub Actions

The first deployment may need to be kicked manually:

Actions -> All workflows -> Deploy GitHub Pages -> Run workflow

After this, pushes to dev or main redeploy automatically.

Credentials

GitHub Pages is static, so the app must not contain the private CoRE Stack API key. Users paste their API key into the app at runtime. The key stays in their browser session and is not committed or stored by this repo.

CORS Requirement

Because the exported app runs in the user's browser, the CoRE Stack API must allow browser requests from the GitHub Pages origin.

The public API currently responds to an OPTIONS preflight, but does not include Access-Control-Allow-Origin or Access-Control-Allow-Headers for X-API-Key. If that remains true in production, the GitHub Pages app will load but browser requests to the API will be blocked before they reach Django.

Fix this by allowing the deployed Pages origin, for example:

  • https://amit-spatial.github.io
  • the final custom docs/webapps origin, once chosen

The backend also needs to allow the X-API-Key request header for public API routes.

For the current Django backend, this means setting CORS_ALLOWED_ORIGINS in production to include the Pages origin. X-API-Key is already present in CORS_ALLOW_HEADERS in nrm_app/settings.py.

How to apply

Add the above block to your settings.py (replace the existing else: branch for CORS_ALLOWED_ORIGINS).

  • Redeploy your Django backend.
  • Test from your GitHub Pages app:
  • Open DevTools → Network tab.
  • Make a request to your API.
  • Verify the response headers include:
  • Access-Control-Allow-Origin: https://amit-spatial.github.io
  • Access-Control-Allow-Headers: X-API-Key

MARK: CORS Settings

if DEBUG:
    CORS_ALLOW_ALL_ORIGINS = True
else:
    CORS_ALLOWED_ORIGINS = [
        "https://amit-spatial.github.io",   # GitHub Pages origin
        # Add your custom domain once chosen, e.g.:
        # "https://docs.core-stack.org",
    ]

CORS_ALLOWED_ORIGIN_REGEXES = [
    r"^http://localhost:\d+$",
    r"^http://127\.0\.0\.1:\d+$",
    r"^http://192\.168\.\d{1,3}\.\d{1,3}(:\d+)?$",
]

CORS_ALLOW_HEADERS = list(default_headers) + [
    "ngrok-skip-browser-warning",
    "content-disposition",
    "X-API-Key",
]

Local Export

uv run python scripts/build_pages.py
uv run python -m http.server --directory site 8010

Use port 8010 by default for local previews. If it is already in use, choose the next free port and keep the site/ directory the same.

The root site/index.html links to:

  • /public-data-browser/
  • /exploratory-layer-studio/
  • /mws-deep-dive/
  • /action-planner/
  • /guided-map-tour/

Adding A New Notebook

  1. Create a .py marimo notebook in notebooks/.
  2. Keep it browser-safe for WebAssembly export: no private secrets, no local-only paths, no server-only imports.
  3. Add the notebook to APPS in scripts/build_pages.py.
  4. Run uv run python scripts/build_pages.py.
  5. Preview at http://127.0.0.1:8010/.
  6. Commit and push to main.

The generated site/ directory is ignored and should not be committed.

Template Reference

The repo https://github.com/amit-spatial/marimo-gh-pages-template is a useful reference when this deployment needs to become more generic.

It demonstrates:

  • exporting app files from apps/ in run mode
  • exporting notebook files from notebooks/ in edit mode
  • generating the root index through Jinja templates
  • keeping notebook-local assets in public/

This project currently keeps all deployable experiences as run-mode apps, so scripts/build_pages.py is intentionally simpler. The template can still guide a future split between public apps, editable notebooks, reusable templates, and static assets.

Notes

  • GitHub Pages is static; API keys must be entered at runtime or loaded locally from .env.
  • The deployed app still needs backend CORS for API calls from https://amit-spatial.github.io.
  • The local server does not solve production CORS; it only previews the static export.
  • If a notebook uses new packages, add them to both pyproject.toml and the notebook PEP 723 block.
  • If the API shape changes, update notebook helper functions before redeploying.