Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 7 additions & 7 deletions .github/scripts/build_diff_payload.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Build the JSON payload sent to GraphRAG-UI's /api/admin/update-graph.

Invoked from .github/workflows/update-graph.yml after a push to main:
reads BASE_SHA + HEAD_SHA from env, computes the .md diff, reads file
reads BASE_SHA + HEAD_SHA from env, computes the .mdx diff, reads file
content for added+modified entries, and writes payload.json. Sets the
``skip`` step output to ``true`` when nothing ingestable changed so the
workflow can short-circuit before the network call.
Expand Down Expand Up @@ -51,10 +51,10 @@ def _read_at(head: str, path: str) -> str | None:
def _collect_md_changes(
diff_output: str, head: str,
) -> tuple[dict[str, str], dict[str, str], list[str]]:
"""Parse ``git diff --name-status`` and bucket .md changes.
"""Parse ``git diff --name-status`` and bucket .mdx changes.

Renames (``R``) are split into delete-old + add-new so the SDK
re-extracts the content under the new path. Non-.md files are
re-extracts the content under the new path. Non-.mdx files are
skipped. File content for added/modified entries is read from
the git object store at ``head``, not from disk.
"""
Expand All @@ -70,15 +70,15 @@ def _collect_md_changes(

if status == "R" and len(parts) >= 3:
old, new = parts[1], parts[2]
if old.endswith(".md"):
if old.endswith(".mdx"):
deleted.append(old)
if new.endswith(".md"):
if new.endswith(".mdx"):
content = _read_at(head, new)
if content is not None:
added[new] = content
continue

if len(parts) < 2 or not parts[1].endswith(".md"):
if len(parts) < 2 or not parts[1].endswith(".mdx"):
continue
path = parts[1]
if status == "A":
Expand Down Expand Up @@ -114,7 +114,7 @@ def main() -> int:
added, modified, deleted = _collect_md_changes(diff, head)

if not (added or modified or deleted):
print("::notice::No .md changes — skipping graph update.", file=sys.stderr)
print("::notice::No .mdx changes — skipping graph update.", file=sys.stderr)
_set_output("skip", "true")
return 0

Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/aggregate-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: aggregate docs

# Builds one Mintlify site from every FalkorDB documentation repository and
# publishes it to the `docs-site` branch, which is what Mintlify deploys. A
# single deployment means search and the AI assistant index all products
# together instead of once per product.

on:
push:
branches: [ "main" ]
workflow_dispatch:
repository_dispatch:
types: [ docs-updated ]
schedule:
# Safety net in case a source repository never sends a dispatch.
- cron: "0 4 * * *"

permissions:
# Pushing the built site to docs-site.
contents: write

concurrency:
group: aggregate-docs
cancel-in-progress: true

jobs:
aggregate:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup Node
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: lts/*

- name: Build aggregated site
env:
# Read-only access to the source repositories.
DOCS_TOKEN: ${{ secrets.DOCS_AGGREGATE_TOKEN }}
run: python3 scripts/aggregate_docs.py --output build

- name: Validate
working-directory: build
run: |
npx --yes mint@latest validate
npx --yes mint@latest broken-links

- name: Publish to docs-site
env:
# Write access to this repository only. The built-in token is enough
# unless the org caps workflow permissions at read-only.
DOCS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
working-directory: build
run: |
git init -q -b docs-site
git add -A
git -c user.name="FalkorDB Docs Bot" \
-c user.email="docs-bot@falkordb.com" \
commit -q -m "Aggregate docs from ${GITHUB_SHA::7} (run ${GITHUB_RUN_NUMBER})"
git push --force --quiet \
"https://x-access-token:${DOCS_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" docs-site
30 changes: 30 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: docs

permissions:
contents: read

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup Node
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: lts/*

- name: Check MDX syntax
run: |
npm install --no-save @mdx-js/mdx remark-gfm
node scripts/check_mdx.mjs

- name: Check internal links
run: npx --yes mint@latest broken-links
4 changes: 2 additions & 2 deletions .github/workflows/update-graph.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Incrementally updates the FalkorDB docs knowledge graph whenever .md
# Incrementally updates the FalkorDB docs knowledge graph whenever .mdx
# files change on main. Computes the diff against the previous HEAD,
# POSTs it to GraphRAG-UI's /api/admin/update-graph endpoint, which does
# the SDK ingestion + smoke test + atomic alias flip server-side.
Expand All @@ -10,7 +10,7 @@ on:
branches:
- main
paths:
- "**/*.md"
- "**/*.mdx"

# `github.ref_name` is "main"; all pushes to main share one queue.
concurrency:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
_site/
build/
*.dic
node_modules/
.mintlify/
.mint/
package-lock.json
6 changes: 6 additions & 0 deletions .mintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
README.md
AGENTS.md
existing_routes.txt
scripts/
build/
node_modules/
4 changes: 2 additions & 2 deletions .spellcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ matrix:
- 'pre'
- 'blockquote'
sources:
- '*.md'
- '**/*.md'
- '*.mdx'
- '**/*.mdx'
3 changes: 3 additions & 0 deletions .wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -944,3 +944,6 @@ uptime
allocator
RSS
OOM
Embeddable
reranking
Swappable
97 changes: 97 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Repository guidelines

This repository holds the **FalkorDB core documentation**, published with
[Mintlify](https://mintlify.com) at <https://docs.falkordb.com>.

FalkorDB documentation is split across four repositories and aggregated into a
single Mintlify deployment, so search and the AI assistant index every product
together. Each repository owns one entry in `navigation.products`:

| Product | Repository | Mounted at |
| --- | --- | --- |
| FalkorDB (this repo) | `FalkorDB/docs` | `/` |
| FalkorDB Cloud | `FalkorDB/mintlify-docs` | `/cloud` |
| FalkorDB Enterprise | `FalkorDB/FalkorDB-Enterprise` (`docs/`) | `/enterprise` |
| GraphRAG SDK | `FalkorDB/GraphRAG-SDK` (`docs/`) | `/graphrag` |

Only edit FalkorDB core content here. The other products live in their own
repositories.

## Aggregation

Each repository keeps the full `navigation.products` list and populates only its
own product, linking to the others with `href`. That way every repository still
builds and previews on its own.

`scripts/aggregate_docs.py` turns those four repositories into one site: it
clones each source listed in `scripts/sources.json`, copies its content under
the mount point, prefixes every path in its product entry, rewrites the repo's
own absolute links and assets, namespaces its snippets under
`/snippets/<mount>/`, and substitutes the result for the `href` placeholder in
this repository's `docs.json`. Redirects and links that point at a standalone
product site become internal paths.

```bash
python3 scripts/aggregate_docs.py --output build --use-local .. # sibling checkouts
python3 scripts/aggregate_docs.py --output build # clone the sources
```

`.github/workflows/aggregate-docs.yml` runs this on every push to `main`, on a
`docs-updated` repository dispatch from a source repository, and nightly. It
publishes to the `docs-site` branch, which is the branch Mintlify deploys.

Adding a product means adding it to `navigation.products` here as an `href`
placeholder and appending an entry to `scripts/sources.json`.

## Authoring rules

- Every page is an `.mdx` file with YAML front matter containing at least
`title`, and `description` where it adds value.
- **Do not write an H1 in the body.** Mintlify renders `title` as the H1.
Start the body at `##`.
- Register every new page in `docs.json`. A page that is not in `navigation`
is not reachable.
- Internal links are root-relative and omit the extension:
`[Configuration](/getting-started/configuration)`.
- A folder's landing page is `index.mdx` and is wired up as the group `root`.

## MDX gotchas

MDX parses `{`, `}` and `<` as JSX. Outside fenced code blocks and inline code
spans you must escape them, self-close void elements (`<br />`, `<img ... />`),
use `className` instead of `class`, and pass `style` as an object. Use MDX
comments (`{/* ... */}`) rather than HTML comments.

## Components

Prefer Mintlify components over hand-rolled HTML:

- `<CodeGroup>` for the same example in multiple languages.
- `<AccordionGroup>` / `<Accordion>` for FAQs and collapsible argument lists.
- `<Note>`, `<Tip>`, `<Warning>`, `<Info>` for callouts.

## Local development

```bash
npm i -g mint
mint dev # preview at http://localhost:3000
mint broken-links # verify every internal link resolves
```

`mint` requires an LTS release of Node.

To validate MDX syntax across every page in one pass:

```bash
npm install --no-save @mdx-js/mdx remark-gfm
node scripts/check_mdx.mjs
```

## Scripts

- `scripts/aggregate_docs.py` — builds the combined multi-product site.
- `scripts/sources.json` — the repositories that get aggregated.
- `scripts/check_mdx.mjs` — compiles every `.mdx` page and reports all syntax
errors at once.
- `scripts/migrate_to_mintlify.py` — the one-shot Jekyll to Mintlify conversion.
Kept for reference; it is a no-op now that no `.md` pages remain.
Loading