Skip to content

Update Reference Documentation #102

Update Reference Documentation

Update Reference Documentation #102

name: Update Reference Documentation
on:
workflow_dispatch: # Allow manual triggers
schedule:
# Nightly at 06:30 UTC: regenerate API/Helm docs from the latest kagent/kmcp main so docs don't drift from code.
- cron: '30 6 * * *'
# Queue overlapping runs (e.g. nightly cron + a manual dispatch) so they don't force-push the same PR branch concurrently.
concurrency:
group: update-ref-docs
cancel-in-progress: false
# The docs are a Hugo site under docs-site/ (served at /docs). This workflow
# generates the reference pages directly as Hugo markdown into docs-site/content:
# - kagent CRD API ref -> docs-site/content/kagent/resources/api-ref.md
# - kmcp CRD API ref -> docs-site/content/kmcp/reference/api-ref.md
# - kagent Helm ref -> docs-site/content/kagent/resources/helm.md
# Each page uses plain Hugo YAML frontmatter (no MDX `export const metadata`).
jobs:
generate-api-docs:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
# Target Hugo content paths (relative to the website checkout).
env:
KAGENT_API_PAGE: docs-site/content/kagent/resources/api-ref.md
KMCP_API_PAGE: docs-site/content/kmcp/reference/api-ref.md
HELM_PAGE: docs-site/content/kagent/resources/helm.md
steps:
- name: Checkout kagent repository
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/kagent
path: kagent
- name: Checkout kmcp repository
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/kmcp
path: kmcp
- name: Checkout docs repository
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/website
path: website
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.24'
cache: false
- name: Set kagent commit SHA
run: echo "KAGENT_COMMIT=$(cd kagent && git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Set kmcp commit SHA
run: echo "KMCP_COMMIT=$(cd kmcp && git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Verify API directory exists
run: |
if [ ! -d "$GITHUB_WORKSPACE/kagent/go/api/v1alpha2" ]; then
echo "Error: API directory not found at $GITHUB_WORKSPACE/kagent/go/api/v1alpha2"
ls -la "$GITHUB_WORKSPACE/kagent/go/api/"
exit 1
fi
echo "API directory found and verified"
- name: Read max Kubernetes version
run: |
if [ ! -f "website/public/docs/versions/max-kube.md" ]; then
echo "Error: max-kube.md file not found"
exit 1
fi
KUBE_VERSION=$(cat website/public/docs/versions/max-kube.md | tr -d '\n')
echo "KUBE_VERSION=$KUBE_VERSION" >> $GITHUB_ENV
echo "Using Kubernetes version: $KUBE_VERSION"
- name: Generate API Reference
run: |
# Substitute KUBE_VERSION in the config template and write to a temp file
cd "$GITHUB_WORKSPACE/website"
if [ ! -f "scripts/crd-ref-docs-config.yaml" ]; then
echo "Error: crd-ref-docs-config.yaml not found in scripts directory"
exit 1
fi
envsubst < scripts/crd-ref-docs-config.yaml > crd-ref-docs-config.yaml
echo "Changed to docs repository: $PWD"
echo "Using config file:"
cat crd-ref-docs-config.yaml
# Generate API docs
go run github.com/elastic/crd-ref-docs@v0.1.0 \
--source-path="$GITHUB_WORKSPACE/kagent/go/api/v1alpha2/" \
--renderer=markdown \
--output-path ./ \
--config=crd-ref-docs-config.yaml
# Check if generation was successful
if [ ! -f "./out.md" ]; then
echo "Error: API docs generation failed - out.md not created"
exit 1
fi
# Remove the temporary config file so it is not included in the PR
rm -f crd-ref-docs-config.yaml
# Fix problematic angle brackets in the generated markdown.
# Goldmark (unsafe: true) would otherwise treat stray <...> as raw HTML
# and silently swallow it, so convert bare angle brackets to HTML
# entities (they render literally). Preserve legitimate <br /> tags.
echo "Fixing problematic angle brackets in generated markdown..."
sed -i 's/<br \/>/__BR_TAG__/g' "./out.md"
sed -i 's/</\&lt;/g' "./out.md"
sed -i 's/>/\&gt;/g' "./out.md"
sed -i 's/__BR_TAG__/<br \/>/g' "./out.md"
# crd-ref-docs's markdown renderer emits multiple consecutive blank
# lines around headings/descriptions. Collapse runs of 2+ blank
# lines to a single one so regenerating doesn't churn whitespace
# against the committed page on every run.
echo "Collapsing excess blank lines..."
sed -i ':a;N;$!ba;s/\n\{3,\}/\n\n/g' "./out.md"
# Drop crd-ref-docs's default leading `# API Reference` H1: Hextra
# renders the frontmatter title as the page H1, so a body H1 would
# duplicate it (same reasoning as the Helm chart step below).
sed -i '0,/^# /{/^# /d}' "./out.md"
# The H1 removal leaves a blank line where the heading was; strip
# leading blank lines so it doesn't stack with the frontmatter's
# own trailing blank line once appended below.
sed -i '/./,$!d' "./out.md"
# Write the Hugo page: plain YAML frontmatter + generated body.
mkdir -p "$(dirname "$KAGENT_API_PAGE")"
cat > "$KAGENT_API_PAGE" <<'EOF'
---
title: API Reference
linkTitle: API docs
description: kagent API reference documentation
weight: 1
author: kagent.dev
---
EOF
cat "./out.md" >> "$KAGENT_API_PAGE"
rm -f "./out.md"
# Normalize to exactly one trailing newline. crd-ref-docs can leave
# trailing blank lines at EOF that would otherwise churn on every
# regeneration even though nothing meaningful changed.
printf '%s\n' "$(cat "$KAGENT_API_PAGE")" > "$KAGENT_API_PAGE"
# Verify the output file was created
if [ ! -f "$KAGENT_API_PAGE" ]; then
echo "Error: Failed to create API docs page"
exit 1
fi
echo "API docs generated and processed successfully"
- name: Verify KMCP API directory exists
run: |
if [ ! -d "$GITHUB_WORKSPACE/kmcp/api/v1alpha1" ]; then
echo "Error: KMCP API directory not found at $GITHUB_WORKSPACE/kmcp/api/v1alpha1"
ls -la "$GITHUB_WORKSPACE/kmcp/api/" || echo "kmcp/api directory not found"
exit 1
fi
echo "KMCP API directory found and verified"
- name: Generate KMCP API Reference
run: |
# Substitute KUBE_VERSION in the config template and write to a temp file
cd "$GITHUB_WORKSPACE/website"
if [ ! -f "scripts/crd-ref-docs-config.yaml" ]; then
echo "Error: crd-ref-docs-config.yaml not found in scripts directory"
exit 1
fi
envsubst < scripts/crd-ref-docs-config.yaml > crd-ref-docs-config.yaml
echo "Changed to docs repository: $PWD"
echo "Using config file:"
cat crd-ref-docs-config.yaml
# Generate KMCP API docs
go run github.com/elastic/crd-ref-docs@v0.1.0 \
--source-path="$GITHUB_WORKSPACE/kmcp/api/v1alpha1/" \
--renderer=markdown \
--output-path ./ \
--config=crd-ref-docs-config.yaml
# Check if generation was successful
if [ ! -f "./out.md" ]; then
echo "Error: KMCP API docs generation failed - out.md not created"
exit 1
fi
# Remove the temporary config file so it is not included in the PR
rm -f crd-ref-docs-config.yaml
# Fix problematic angle brackets (see the kagent step for rationale).
echo "Fixing problematic angle brackets in generated markdown..."
sed -i 's/<br \/>/__BR_TAG__/g' "./out.md"
sed -i 's/</\&lt;/g' "./out.md"
sed -i 's/>/\&gt;/g' "./out.md"
sed -i 's/__BR_TAG__/<br \/>/g' "./out.md"
# See the kagent step above for rationale: collapse crd-ref-docs's
# excess blank lines so this doesn't churn whitespace every run.
echo "Collapsing excess blank lines..."
sed -i ':a;N;$!ba;s/\n\{3,\}/\n\n/g' "./out.md"
# See the kagent step above for rationale: drop the duplicate H1.
sed -i '0,/^# /{/^# /d}' "./out.md"
# See the kagent step above for rationale: strip the leading blank
# line the H1 removal leaves behind.
sed -i '/./,$!d' "./out.md"
# Write the Hugo page: plain YAML frontmatter + generated body.
mkdir -p "$(dirname "$KMCP_API_PAGE")"
cat > "$KMCP_API_PAGE" <<'EOF'
---
title: API Reference
linkTitle: API docs
description: kmcp API reference documentation
weight: 5
author: kagent.dev
---
EOF
cat "./out.md" >> "$KMCP_API_PAGE"
rm -f "./out.md"
# See the kagent step above for rationale: normalize trailing newline.
printf '%s\n' "$(cat "$KMCP_API_PAGE")" > "$KMCP_API_PAGE"
# Verify the output file was created
if [ ! -f "$KMCP_API_PAGE" ]; then
echo "Error: Failed to create KMCP API docs page"
exit 1
fi
echo "KMCP API docs generated and processed successfully"
- name: Generate Helm Chart Reference
run: |
echo "Looking for Helm directory:"
ls -la "$GITHUB_WORKSPACE/kagent/helm" || echo "Helm directory not found!"
# Update docs repository
cd "$GITHUB_WORKSPACE/website"
echo "Changed to docs repository: $PWD"
# Generate Helm Docs for kagent chart
if [ ! -d "$GITHUB_WORKSPACE/kagent/helm/kagent" ]; then
echo "Error: kagent Helm chart directory not found"
exit 1
fi
echo "Processing kagent Helm chart..."
echo "Chart directory contents:"
ls -la "$GITHUB_WORKSPACE/kagent/helm/kagent/"
# Generate Chart.yaml from template for helm-docs to work
echo "Generating Chart.yaml from template..."
cd "$GITHUB_WORKSPACE/kagent/helm/kagent"
# Get the version from git or use a default
VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.5.5")
echo "Using version: $VERSION"
# Copy template and substitute version
cp Chart-template.yaml Chart.yaml
sed -i "s/\${VERSION}/$VERSION/g" Chart.yaml
echo "Generated Chart.yaml contents:"
cat Chart.yaml
# Go back to website directory
cd "$GITHUB_WORKSPACE/website"
echo "Chart.yaml contents:"
cat "$GITHUB_WORKSPACE/kagent/helm/kagent/Chart.yaml" || echo "Chart.yaml not found!"
echo "Values.yaml contents (first 20 lines):"
head -20 "$GITHUB_WORKSPACE/kagent/helm/kagent/values.yaml" || echo "values.yaml not found!"
# Generate the helm documentation
echo "Running helm-docs..."
find "$GITHUB_WORKSPACE/kagent/helm" -name "Chart.yaml" -type f 2>/dev/null | head -10
go run github.com/norwoodj/helm-docs/cmd/helm-docs@v1.14.2 \
--chart-search-root "$GITHUB_WORKSPACE/kagent/helm/kagent" \
--dry-run > "helm-temp.md"
echo "Generated helm-docs output (first 50 lines):"
head -50 "helm-temp.md"
echo "Total lines generated:"
wc -l "helm-temp.md"
# Remove the badge line and following empty line
# (might be replaced by a helm-docs template in the future).
sed -i '/!\[Version:/,/^$/d' "helm-temp.md"
# Drop the leading `# <chart name>` H1: Hextra renders the frontmatter
# title as the page H1, so a body H1 would duplicate it.
sed -i '0,/^# /{/^# /d}' "helm-temp.md"
# The H1 removal leaves a blank line where the heading was; strip
# leading blank lines so it doesn't stack with the frontmatter's
# own trailing blank line once appended into $HELM_PAGE below.
sed -i '/./,$!d' "helm-temp.md"
# Wrap version placeholders in inline code so they show literally.
python - <<'PY'
import re
from pathlib import Path
path = Path("helm-temp.md")
text = path.read_text()
for placeholder in ("${KMCP_VERSION}", "${SUBSTRATE_VERSION}", "${SUBSTRATE_REPO}"):
text = text.replace(placeholder, "`" + placeholder + "`")
# Wrap bare Helm/Go template expressions ({{ ... }}) in inline code.
# Hugo renders them literally, but the MDX build (and copy-out to any
# MDX consumer) parses {{ ... }} in prose as a JSX expression and
# fails with "Could not parse expression with acorn" (e.g. the
# extraObjects @default example). Existing inline-code spans are left
# untouched so already-backticked templates are not double-wrapped.
template = re.compile(r"\{\{.*?\}\}")
code_span = re.compile(r"`[^`]*`")
wrapped = []
pos = 0
for span in code_span.finditer(text):
wrapped.append(template.sub(lambda m: "`" + m.group(0) + "`", text[pos:span.start()]))
wrapped.append(span.group(0))
pos = span.end()
wrapped.append(template.sub(lambda m: "`" + m.group(0) + "`", text[pos:]))
text = "".join(wrapped)
path.write_text(text)
PY
# Write the Hugo page: plain YAML frontmatter + generated body.
mkdir -p "$(dirname "$HELM_PAGE")"
cat > "$HELM_PAGE" <<'EOF'
---
title: kagent
linkTitle: Helm Chart Configuration
description: kagent Helm chart configuration reference
weight: 2
author: kagent.dev
---
EOF
cat "helm-temp.md" >> "$HELM_PAGE"
rm -f "helm-temp.md"
# Normalize to exactly one trailing newline, same as the API ref
# pages above.
printf '%s\n' "$(cat "$HELM_PAGE")" > "$HELM_PAGE"
echo "Final generated file contents (first 50 lines):"
head -50 "$HELM_PAGE"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
path: website
commit-message: "docs: Update kagent and kmcp API reference docs"
signoff: true
title: "Update kagent and kmcp API reference docs"
body: |
Automated API and kagent Helm chart documentation update based on the latest commits:
- **kagent**: [`${{ env.KAGENT_COMMIT }}`](https://github.com/${{ github.repository_owner }}/kagent/commit/${{ env.KAGENT_COMMIT }})
- **kmcp**: [`${{ env.KMCP_COMMIT }}`](https://github.com/${{ github.repository_owner }}/kmcp/commit/${{ env.KMCP_COMMIT }})
This PR was automatically generated by the [**Update Reference documentation** workflow](https://github.com/${{ github.repository_owner }}/website/actions/workflows/update-ref-docs.yaml).
branch: api-gen-update
delete-branch: true
base: main
labels: |
documentation
automated pr