Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a955827
Tools: add knowledge indexing generator for an LLM-friendly docs index
deruyter92 Aug 12, 2026
053d694
fix default output dir: `_build`
deruyter92 Aug 26, 2026
ef5bf73
use full commit hash of repo
deruyter92 Aug 26, 2026
af711db
add duplicate check
deruyter92 Aug 26, 2026
83c8587
move knowledge index to JSONL + llms.txt
deruyter92 Aug 26, 2026
be6a384
add content hash and distinct `package_version` (in addition to docs …
deruyter92 Aug 26, 2026
fce810d
update pyproject.toml: fix missing `griffelib` dependency for knowled…
deruyter92 Aug 26, 2026
d41019e
allow separate adjustment of doc index and dev-docs api index
deruyter92 Aug 26, 2026
ee8e213
add CI workflows for knowlede-index deployment
deruyter92 Aug 26, 2026
58ac50b
update docstrings and readme
deruyter92 Aug 26, 2026
25d5594
separate dependencies for leaner CI build&deployment of knowledge-index
deruyter92 Aug 26, 2026
f2295f4
simplify llms.txt no per-page summary of doc sections. Prominent ref…
deruyter92 Aug 26, 2026
08080bd
Merge branch 'main' into jaap/add-llm-knowledge-index
deruyter92 Aug 26, 2026
8785d2d
update uv.lock
deruyter92 Aug 26, 2026
8badfd6
validate version labels + tighten manifest reading
deruyter92 Aug 27, 2026
922fa03
CI: harden reusable docs workflows against script injection
deruyter92 Aug 27, 2026
4e38fb9
fix delete version + refuse delete "main".
deruyter92 Aug 27, 2026
8f1cf8c
Fix bug in checkout from tag merging into pre-existing checkout
deruyter92 Aug 27, 2026
838eab7
knowledge-index Fix bug in checkout from tag merging into pre-existin…
deruyter92 Aug 27, 2026
baead09
check if dev-docs version is deployed before attempting a delete
deruyter92 Aug 27, 2026
24f1bc1
mark dev-docs and knowledge-index dependencies as dependecy-group (ra…
deruyter92 Aug 27, 2026
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
14 changes: 11 additions & 3 deletions .github/actions/setup-dev-docs/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@ runs:
sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev \
libjpeg-dev libpng-dev libz-dev

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.10.10"
enable-cache: true

# A group, not an extra: mkdocstrings reads deeplabcut from the checkout
# via `paths` in mkdocs.yml, so the package and its runtime (torch, CUDA
# wheels, ...) are never installed here.
# --system: setup-python provides no virtualenv to install into.
- name: Install dev-docs dependencies
shell: bash
run: |
python -m pip install --upgrade pip
python -m pip install ".[dev-docs]"
run: uv pip install --system --group dev-docs
98 changes: 69 additions & 29 deletions .github/workflows/deploy-dev-docs-mike.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,60 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
# Unsafe free-text inputs are read from the environment inside `run:`
# rather than spliced in as `${{ }}`.
env:
VERSION_LABEL: ${{ inputs.version_label }}
ALIASES: ${{ inputs.aliases }}
DEFAULT_LABEL: ${{ inputs.default_label }}
GIT_TAG: ${{ inputs.git_tag }}
CONFIG_FILE: ${{ inputs.config-file }}
DEPLOY_PREFIX: ${{ inputs.deploy-prefix }}

steps:
- name: Validate inputs
- name: Reject unknown action
if: inputs.action != 'deploy' && inputs.action != 'delete'
shell: bash
run: |
case "${{ inputs.action }}" in
deploy|delete)
;;
*)
echo "::error::Unsupported action '${{ inputs.action }}'. Expected 'deploy' or 'delete'."
exit 1
;;
esac

if [ "${{ inputs.action }}" = "deploy" ] && [ -z "${{ inputs.git_tag }}" ] && [ "${{ inputs.version_label }}" != "main" ]; then
echo "::error::git_tag is required when deploying non-'main' versions."
exit 1
fi
echo "::error::Unsupported action. Expected 'deploy' or 'delete'."
exit 1

- name: Require git_tag for release versions
if: inputs.action == 'deploy' && inputs.version_label != 'main' && inputs.git_tag == ''
shell: bash
run: |
echo "::error::git_tag is required when deploying a version other than main."
exit 1

- name: Refuse to delete the main version
if: inputs.action == 'delete' && inputs.version_label == 'main'
shell: bash
run: |
echo "::error::'main' tracks the repository's latest state and is redeployed on every push; it cannot be deleted."
exit 1

- uses: actions/checkout@v6
with:
fetch-depth: 0

# remove existing checkout to prevent merging a new version into it
- name: Check out tagged package source
if: inputs.git_tag != ''
shell: bash
run: |
git checkout "${{ inputs.git_tag }}" -- deeplabcut
rm -rf deeplabcut
git checkout "$GIT_TAG" -- deeplabcut

- name: Check the version is deployed before attempting a delete
if: inputs.action == 'delete'
shell: bash
run: |
git fetch --depth=1 origin gh-pages
versions=$(git show "origin/gh-pages:$DEPLOY_PREFIX/versions.json" | jq -r '.[].version')
if ! grep -qxF "$VERSION_LABEL" <<<"$versions"; then
echo "::error::'$VERSION_LABEL' is not deployed under $DEPLOY_PREFIX/. Deployed: $(tr '\n' ' ' <<<"$versions")"
exit 1
fi

- name: Set up dev-docs environment
uses: ./.github/actions/setup-dev-docs
Expand All @@ -99,31 +125,45 @@ jobs:
if: inputs.action == 'deploy'
shell: bash
run: |
if [ -n "${{ inputs.aliases }}" ]; then
if [ -n "$ALIASES" ]; then
# Unquoted on purpose: aliases is a space-separated list and each
# word becomes its own mike argument.
mike deploy --push \
--config-file "${{ inputs.config-file }}" \
--deploy-prefix "${{ inputs.deploy-prefix }}" \
--config-file "$CONFIG_FILE" \
--deploy-prefix "$DEPLOY_PREFIX" \
--update-aliases \
"${{ inputs.version_label }}" ${{ inputs.aliases }}
"$VERSION_LABEL" $ALIASES
else
mike deploy --push \
--config-file "${{ inputs.config-file }}" \
--deploy-prefix "${{ inputs.deploy-prefix }}" \
"${{ inputs.version_label }}"
--config-file "$CONFIG_FILE" \
--deploy-prefix "$DEPLOY_PREFIX" \
"$VERSION_LABEL"
fi

if [ -n "${{ inputs.default_label }}" ]; then
if [ -n "$DEFAULT_LABEL" ]; then
mike set-default --push \
--config-file "${{ inputs.config-file }}" \
--deploy-prefix "${{ inputs.deploy-prefix }}" \
"${{ inputs.default_label }}"
--config-file "$CONFIG_FILE" \
--deploy-prefix "$DEPLOY_PREFIX" \
"$DEFAULT_LABEL"
fi

- name: Delete dev-docs version
if: inputs.action == 'delete'
shell: bash
run: |
mike delete --push \
--config-file "${{ inputs.config-file }}" \
--deploy-prefix "${{ inputs.deploy-prefix }}" \
"${{ inputs.version_label }}"
--config-file "$CONFIG_FILE" \
--deploy-prefix "$DEPLOY_PREFIX" \
"$VERSION_LABEL"

knowledge-index:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may need a concurrency guard shared with other workflows operating on gh-pages, as having several workflows modifying concurrently may be a problem

# api.jsonl only; docs.jsonl/llms.txt are built by deploy-docs.yml instead.
needs: mike
uses: ./.github/workflows/deploy-knowledge-index.yml
with:
action: ${{ inputs.action }}
version_label: ${{ inputs.version_label }}
git_tag: ${{ inputs.git_tag }}
skip_docs: true
python-version: ${{ inputs.python-version }}
secrets: inherit
11 changes: 11 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,14 @@ jobs:
config-file: dev-docs/mkdocs.yml
deploy-prefix: dev
secrets: inherit

deploy-user-docs-knowledge-index:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may need a concurrency guard shared with other workflows operating on gh-pages, as having several workflows modifying concurrently may be a problem

# docs.jsonl/llms.txt only; api.jsonl is built by deploy-dev-docs-mike.yml instead.
needs: deploy-dev-docs-main
uses: ./.github/workflows/deploy-knowledge-index.yml
with:
action: deploy
version_label: main
skip_api: true
python-version: "3.10"
secrets: inherit
159 changes: 159 additions & 0 deletions .github/workflows/deploy-knowledge-index.yml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may need a concurrency guard shared with other workflows operating on gh-pages, as having several workflows modifying concurrently may be a problem

Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: Docs / Deploy knowledge index

on:
workflow_call:
inputs:
action:
description: "Action to perform: deploy or delete."
required: true
type: string

version_label:
description: "Version label to deploy/delete, e.g. main or 3.0."
required: true
type: string

git_tag:
description: "Git tag whose deeplabcut package should be checked out before deploying. Required for deploy when version_label isn't main."
required: false
default: ""
type: string

skip_api:
description: "Leave api.jsonl untouched. Deploy only; a delete always concerns the API index."
required: false
default: false
type: boolean

skip_docs:
description: "Leave docs.jsonl/llms.txt untouched. Deploy only; a delete never touches the user docs."
required: false
default: false
type: boolean

python-version:
description: Python version used to build the knowledge index.
required: false
default: "3.10"
type: string

jobs:
knowledge-index:
runs-on: ubuntu-latest
permissions:
contents: write
# Unsafe free-text inputs are read from the environment inside `run:`
# rather than spliced in as `${{ }}`.
env:
VERSION_LABEL: ${{ inputs.version_label }}
GIT_TAG: ${{ inputs.git_tag }}

steps:
- name: Reject unknown action
if: inputs.action != 'deploy' && inputs.action != 'delete'
shell: bash
run: |
echo "::error::Unsupported action. Expected 'deploy' or 'delete'."
exit 1

- name: Require git_tag for release versions
if: inputs.action == 'deploy' && inputs.version_label != 'main' && inputs.git_tag == ''
shell: bash
run: |
echo "::error::git_tag is required when deploying a version other than main."
exit 1

- uses: actions/checkout@v6
with:
fetch-depth: 0

# remove existing checkout to prevent merging a new version into it
- name: Check out tagged package source
if: inputs.action == 'deploy' && inputs.git_tag != ''
shell: bash
run: |
rm -rf deeplabcut
git checkout "$GIT_TAG" -- deeplabcut

- name: Resolve revision
if: inputs.action == 'deploy'
id: revision
shell: bash
run: |
if [ -n "$GIT_TAG" ]; then
echo "sha=$(git rev-parse "$GIT_TAG^{commit}")" >> "$GITHUB_OUTPUT"
else
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
fi

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version }}

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.10.10"
enable-cache: true

# --system: setup-python provides no virtualenv to install into.
- name: Install knowledge-index dependencies
shell: bash
run: uv pip install --system --group knowledge-index

- name: Check out published knowledge index
uses: actions/checkout@v6
with:
ref: gh-pages
path: gh-pages
sparse-checkout: |
knowledge

- name: Build knowledge index
if: inputs.action == 'deploy'
shell: bash
env:
REVISION: ${{ steps.revision.outputs.sha }}
run: |
mkdir -p _build/knowledge-index
if [ -d gh-pages/knowledge ]; then
cp -r gh-pages/knowledge _build/knowledge-index/
fi
python -m tools.knowledge_indexing \
--output _build/knowledge-index \
--version-label "$VERSION_LABEL" \
--revision "$REVISION" \
${{ inputs.skip_api && '--skip-api' || '' }} \
${{ inputs.skip_docs && '--skip-docs' || '' }}

- name: Deploy knowledge index
if: inputs.action == 'deploy'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: _build/knowledge-index
keep_files: true

- name: Delete version from knowledge index
if: inputs.action == 'delete'
shell: bash
run: |
python -m tools.knowledge_indexing --delete \
--output gh-pages \
--version-label "$VERSION_LABEL"

- name: Push deletion
if: inputs.action == 'delete'
shell: bash
working-directory: gh-pages
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add --all knowledge
if git diff --cached --quiet; then
echo "Nothing to delete."
else
git commit -m "Delete knowledge index for $VERSION_LABEL"
git push
fi
2 changes: 1 addition & 1 deletion .github/workflows/manage-dev-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
- delete-version

version_label:
description: "Version label to deploy or delete, e.g. 3.0"
description: "Version label to deploy or delete, e.g. 3.0. 'main' cannot be deleted."
required: true
type: string

Expand Down
27 changes: 17 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,6 @@ docs = [
"jupyter-book==1.0.4.post1",
"sphinxcontrib-mermaid",
]
dev-docs = [
"black>=24",
"mike>=2.1",
"mkdocs>=1.6",
"mkdocs-api-autonav>=0.1",
"mkdocs-autorefs>=1.2",
"mkdocs-jupyter>=0.25",
"mkdocs-material[imaging]>=9.5",
"mkdocstrings[python]>=0.27",
]
fmpose3d = [ "fmpose3d>=0.0.8" ]
# Use only one of [tf, tf-cu11, tf-cu12, tf-latest]. Do not combine extras.
tf = [
Expand Down Expand Up @@ -158,6 +148,7 @@ Repository = "https://github.com/DeepLabCut/DeepLabCut"
Documentation = "https://deeplabcut.github.io/DeepLabCut/README.html"

[dependency-groups]
# Groups, not extras: Install with `pip install --group <name>`
dev = [
"coverage",
"nbformat>5",
Expand All @@ -166,9 +157,25 @@ dev = [
"pytest-cov",
"ruff",
]
dev-docs = [
"black>=24",
"mike>=2.1",
"mkdocs>=1.6",
"mkdocs-api-autonav>=0.1",
"mkdocs-autorefs>=1.2",
"mkdocs-jupyter>=0.25",
"mkdocs-material[imaging]>=9.5",
"mkdocstrings[python]>=0.27",
]
gui-dev = [
"pytest-qt",
]
knowledge-index = [
"docutils",
"griffelib",
"markdown-it-py",
"pyyaml",
]

[tool.setuptools]
include-package-data = false
Expand Down
Loading
Loading