From 396a025a69033aff43baf9d6594ad5e8eaffb45c Mon Sep 17 00:00:00 2001 From: Tianyao Wu Date: Wed, 30 Sep 2026 14:09:52 +0800 Subject: [PATCH] docs: build a documentation site with MkDocs and deploy it to Pages The site is built from the Markdown files already in the repository and keeps their repository paths, so relative links work on the site as they do on GitHub. The Docs workflow builds it with --strict on pull requests and deploys it to GitHub Pages from main. Part of #45. Signed-off-by: Tianyao Wu --- .github/workflows/docs.yml | 49 ++++++++++++++++++++++++++++++++ .gitignore | 4 +++ CONTRIBUTING.md | 19 +++++++++++++ README.md | 2 ++ docs/hooks.py | 58 ++++++++++++++++++++++++++++++++++++++ docs/requirements.txt | 3 ++ mkdocs.yml | 53 ++++++++++++++++++++++++++++++++++ 7 files changed, 188 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/hooks.py create mode 100644 docs/requirements.txt create mode 100644 mkdocs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..be0b08c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,49 @@ +name: Docs + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: docs-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-python@v7 + with: + python-version: "3.13" + - name: Install + run: pip install -r docs/requirements.txt + - name: Build + run: mkdocs build --strict + - if: github.ref == 'refs/heads/main' + uses: actions/upload-pages-artifact@v5 + with: + path: site + + # Pull requests only build the site; main also deploys it. + deploy: + if: github.ref == 'refs/heads/main' && github.repository == 'ThinkFlowLab/system1-omni' + needs: build + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v5 diff --git a/.gitignore b/.gitignore index 3857937..fd0f343 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,7 @@ target .venv/ __pycache__/ .DS_Store + +# Documentation site build and environment +/site/ +.venv-docs/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b06c929..53fa46c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,3 +49,22 @@ A coding agent can help review the diff and identify issues, but contributors remain responsible for understanding the changes and verifying the results. Self-review helps maintainers focus on design and correctness; it does not replace maintainer review. + +## Documentation site + +The site at is built with MkDocs +from the README, this guide, the frontend README and the Markdown files under +`recipe/` and `docs/`. `mkdocs.yml` sets the navigation and, in `exclude_docs`, +the published files. Pages keep their repository paths, so write links as +relative paths that work on GitHub; links to files that are not published go to +GitHub. Put images in `docs/assets/`. + +To run the check from the Docs workflow and preview the site, with Python 3.10 or +later: + +```sh +python3 -m venv .venv-docs +.venv-docs/bin/pip install -r docs/requirements.txt +.venv-docs/bin/mkdocs build --strict +.venv-docs/bin/mkdocs serve # http://127.0.0.1:8001/system1-omni/ +``` diff --git a/README.md b/README.md index 76944aa..3d00ab3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # System1-Omni +Documentation: + A community-maintained inference engine for prefill-only System1-Omni models, designed around a Rust frontend, model-owned execution, and high-performance CUDA and Metal backends. The Rust frontend forwards requests to a separately running model worker. In-repository model engines and GPU backends are not implemented yet. diff --git a/docs/hooks.py b/docs/hooks.py new file mode 100644 index 0000000..7f86b2d --- /dev/null +++ b/docs/hooks.py @@ -0,0 +1,58 @@ +"""MkDocs hooks that build the site from the repository root. + +MkDocs rejects `docs_dir: .`, so the root is set here, after the config is +checked, and `exclude_docs` in mkdocs.yml picks the published files. Pages keep +their repository paths, so relative links work as they do on GitHub. Inline +links to files that are not published, or to directories without a README, go +to GitHub. +""" + +import logging +import posixpath +import re +from pathlib import Path + +log = logging.getLogger("mkdocs.hooks") +ROOT = Path(__file__).resolve().parent.parent +IMAGES = (".gif", ".jpeg", ".jpg", ".png", ".svg", ".webp") +# The target of an inline link that is a relative path: ](path#anchor) +LINK = re.compile(r"\]\((?![a-z][a-z0-9+.-]*:|#|/)([^)\s#]+)(#[^)\s]*)?\)") + + +def on_config(config): + config.docs_dir = str(ROOT) + return config + + +def on_serve(server, config, builder): + # Watch the published sources only, not target/ or virtual environments. + server.unwatch(config.docs_dir) + for name in ("README.md", "CONTRIBUTING.md", "docs", "recipe", "src"): + server.watch(str(ROOT / name)) + return server + + +def on_page_markdown(markdown, page, config, files): + base = posixpath.dirname(page.file.src_uri) + github = config.repo_url.rstrip("/") + + def published(path): + file = files.get_file_from_path(path) + return file is not None and file.inclusion.is_included() + + def fix(m): + target, anchor = m[1], m[2] or "" + path = posixpath.normpath(posixpath.join(base, target)) + if path.split("/")[0] == ".." or not (ROOT / path).exists() or published(path): + return m[0] # a page, or a missing file for MkDocs to report + if (ROOT / path).is_dir(): + if published(posixpath.join(path, "README.md")): + return f"]({posixpath.join(target, 'README.md')}{anchor})" + return f"]({github}/tree/main/{path}{anchor})" + if path.lower().endswith(IMAGES): + # A GitHub page is not an image; the image has to be published. + log.warning("%s: %s is not published, see exclude_docs", page.file.src_uri, target) + return m[0] + return f"]({github}/blob/main/{path}{anchor})" + + return LINK.sub(fix, markdown) diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..4d732ea --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,3 @@ +mkdocs==1.6.1 +mkdocs-material==9.7.7 +pymdown-extensions==12.1 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..2d63d2e --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,53 @@ +site_name: System1-Omni +site_url: https://thinkflowlab.github.io/system1-omni/ +repo_url: https://github.com/ThinkFlowLab/system1-omni +edit_uri: edit/main/ +# The recipes run their workers on port 8000. +dev_addr: 127.0.0.1:8001 + +theme: + name: material + features: + - content.action.edit + - content.code.copy + - navigation.indexes + - navigation.sections + - search.highlight + +# docs/hooks.py builds the site from the repository root, so each page keeps its +# repository path and relative links work here as they do on GitHub. +hooks: + - docs/hooks.py +# The published files; assets/ is the theme's. Nothing in hidden directories. +exclude_docs: | + * + !/README.md + !/CONTRIBUTING.md + !/docs/**/*.md + !/docs/assets/** + !/recipe/**/*.md + !/src/frontend/README.md + !/assets/** + **/.*/** + +validation: + absolute_links: warn + unrecognized_links: warn + anchors: warn + +markdown_extensions: + - toc: + permalink: true + # Heading anchors as GitHub makes them. + slugify: !!python/object/apply:pymdownx.slugs.slugify + kwds: + case: lower + - pymdownx.superfences + +nav: + - Overview: README.md + - Frontend: src/frontend/README.md + - Recipes: + - recipe/README.md + - Laya text worker: recipe/laya/README.md + - Contributing: CONTRIBUTING.md