Skip to content

fix(rag): normalise model-returned JSON types #2273

fix(rag): normalise model-returned JSON types

fix(rag): normalise model-returned JSON types #2273

Workflow file for this run

name: Docs
# Builds, validates, and deploys Docusaurus documentation to GitHub Pages.
# Fork (planetf1/mellea) → https://planetf1.github.io/mellea/ (baseUrl: /mellea/)
# Upstream (generative-computing/mellea) → https://docs.mellea.ai (baseUrl: /)
on:
push:
branches: [main]
paths:
- "docs/**"
- "mellea/**"
- "cli/**"
- "tooling/docs-autogen/**"
- ".github/workflows/docs-publish.yml"
# Fires for manually-created GitHub Releases only. Automated releases use
# GITHUB_TOKEN, which cannot trigger new workflow runs — those are handled
# by an explicit workflow_dispatch from the snapshot-docs job instead.
release:
types: [published]
pull_request:
types: [opened, synchronize, reopened, labeled]
paths:
- "docs/**"
- "mellea/**"
- "cli/**"
- "tooling/docs-autogen/**"
- ".github/workflows/docs-publish.yml"
workflow_dispatch:
inputs:
force_publish:
description: "Deploy even from a non-main context (for testing)"
type: boolean
default: false
release_tag:
description: >-
Set to a release tag (e.g. v0.6.0) to run the deploy-on-release flow.
type: string
default: ""
permissions: {}
concurrency:
group: docs-publish-${{ github.ref }}
cancel-in-progress: true
env:
UV_FROZEN: "1"
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
# baseUrl: /mellea/ on fork, / on upstream
DOCS_BASE_URL: ${{ github.repository == 'generative-computing/mellea' && '/' || '/mellea/' }}
DOCS_SITE_URL: ${{ github.repository == 'generative-computing/mellea' && 'https://docs.mellea.ai' || 'https://planetf1.github.io' }}
jobs:
# ---------------------------------------------------------------------------
# Build & Validate
# ---------------------------------------------------------------------------
build-and-validate:
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Set up uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: "docs/package-lock.json"
- name: Install Python dependencies
run: uv sync --frozen --all-extras --group dev
- name: Install Node dependencies
run: npm ci
working-directory: docs
# -- Generate API documentation ------------------------------------------
- name: Generate API documentation
run: uv run python tooling/docs-autogen/build.py
# -- Run docs-autogen unit tests ------------------------------------------
- name: Run CLI reference tests
run: uv run pytest tooling/docs-autogen/test_cli_reference.py -v --tb=short
# -- Validate static docs ------------------------------------------------
- name: Lint static docs (markdownlint)
id: markdownlint
run: |
set -o pipefail
npx --yes markdownlint-cli "docs/docs/**/*.md" --config docs/docs/.markdownlint.json 2>&1 \
| tee /tmp/markdownlint.log
continue-on-error: true
# -- Validate generated API docs -----------------------------------------
- name: Validate generated API docs
id: validate_api
run: |
set -o pipefail
uv run python tooling/docs-autogen/validate.py docs/docs/api 2>&1 \
| tee /tmp/validate_api.log
continue-on-error: true
- name: Audit API coverage
id: audit_coverage
run: |
set -o pipefail
uv run python tooling/docs-autogen/audit_coverage.py --docs-dir docs/docs/api --threshold 80 2>&1 \
| tee /tmp/audit_coverage.log
continue-on-error: true
- name: Docstring quality gate
id: quality_gate
run: |
set -o pipefail
uv run python tooling/docs-autogen/audit_coverage.py \
--docs-dir docs/docs/api \
--quality --fail-on-quality --threshold 100 \
--output /tmp/quality_report.json 2>&1 \
| tee /tmp/quality_gate.log
# -- Build Docusaurus site -----------------------------------------------
- name: Build Docusaurus site
id: build_site
run: npm run build
working-directory: docs
env:
DOCS_BASE_URL: ${{ env.DOCS_BASE_URL }}
# -- Upload artifacts ----------------------------------------------------
- name: Upload quality report
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: docstring-quality-report
path: /tmp/quality_report.json
retention-days: 30
- name: Upload built site artifact
if: success()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: docs-site
path: docs/build/
retention-days: 7
# -- Write job summary ---------------------------------------------------
- name: Write job summary
if: always()
env:
MARKDOWNLINT_OUTCOME: ${{ steps.markdownlint.outcome }}
VALIDATE_API_OUTCOME: ${{ steps.validate_api.outcome }}
AUDIT_COVERAGE_OUTCOME: ${{ steps.audit_coverage.outcome }}
QUALITY_GATE_OUTCOME: ${{ steps.quality_gate.outcome }}
BUILD_SITE_OUTCOME: ${{ steps.build_site.outcome }}
run: |
{
echo "## Docs Build Summary"
echo ""
echo "| Check | Result |"
echo "|-------|--------|"
echo "| Markdownlint | ${MARKDOWNLINT_OUTCOME} |"
echo "| API Validation | ${VALIDATE_API_OUTCOME} |"
echo "| API Coverage | ${AUDIT_COVERAGE_OUTCOME} |"
echo "| Docstring Quality | ${QUALITY_GATE_OUTCOME} |"
echo "| Docusaurus Build | ${BUILD_SITE_OUTCOME} |"
} >> "$GITHUB_STEP_SUMMARY"
# ---------------------------------------------------------------------------
# Deploy to GitHub Pages
# ---------------------------------------------------------------------------
deploy:
needs: build-and-validate
runs-on: ubuntu-latest
permissions:
contents: write
timeout-minutes: 10
# Deploy on: push to main, release event, force_publish via dispatch
if: >-
github.event_name == 'push' ||
github.event_name == 'release' ||
(github.event_name == 'workflow_dispatch' && (inputs.force_publish || inputs.release_tag != ''))
steps:
- name: Download site artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: docs-site
path: docs-site/
# For release events, confirm the published tag is the latest final by semver.
- name: Check release is latest final
id: latest_check
continue-on-error: true
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.release_tag != '')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CURRENT_TAG: ${{ github.event.release.tag_name || inputs.release_tag }}
REPO: ${{ github.repository }}
run: |
python3 - <<'PY'
import json, os, subprocess, sys
from packaging.version import Version, InvalidVersion
current = os.environ["CURRENT_TAG"]
repo = os.environ["REPO"]
raw = subprocess.check_output(
["gh", "api", f"repos/{repo}/releases", "--paginate",
"--jq", ".[] | select(.prerelease==false and .draft==false) | .tag_name"],
text=True,
)
candidates = []
for line in raw.splitlines():
t = line.strip()
if not t:
continue
try:
candidates.append((Version(t.lstrip("v")), t))
except InvalidVersion:
continue
try:
current_version = Version(current.lstrip("v"))
except InvalidVersion:
print(f"error: current tag {current} is not a valid version")
sys.exit(1)
candidates.append((current_version, current))
latest_version, latest_tag = max(candidates)
is_latest = (latest_tag == current or latest_version == current_version)
out = os.environ["GITHUB_OUTPUT"]
with open(out, "a") as fh:
fh.write(f"is_latest_final={'true' if is_latest else 'false'}\n")
fh.write(f"latest_tag={latest_tag}\n")
print(f"current={current} latest={latest_tag} is_latest={is_latest}")
PY
- name: Deploy to GitHub Pages (gh-pages branch)
if: >-
steps.latest_check.conclusion == 'skipped' ||
steps.latest_check.outputs.is_latest_final != 'false'
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages
publish_dir: docs-site/
force_orphan: true
cname: ${{ github.repository == 'generative-computing/mellea' && 'docs.mellea.ai' || '' }}
user_name: "github-actions[bot]"
user_email: "github-actions[bot]@users.noreply.github.com"
commit_message: |
docs: publish from ${{ github.sha }}
Branch: ${{ github.ref_name }}
Trigger: ${{ github.event_name }}
Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Write deploy summary
if: always()
run: |
{
echo "## Docs Deploy"
echo ""
echo "| | |"
echo "|-|-|"
echo "| Branch | \`gh-pages\` |"
echo "| Source | \`${GITHUB_SHA:0:7}\` |"
echo "| Base URL | \`${DOCS_BASE_URL}\` |"
} >> "$GITHUB_STEP_SUMMARY"
env:
DOCS_BASE_URL: ${{ env.DOCS_BASE_URL }}