Update Reference Documentation #102
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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/</\</g' "./out.md" | |
| sed -i 's/>/\>/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/</\</g' "./out.md" | |
| sed -i 's/>/\>/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 |