Skip to content

Commit 7309e1c

Browse files
committed
Add workflow and script for docs JSON export
Introduces a GitHub Actions workflow to build Sphinx HTML documentation and export structured documentation data to docs.json using a new Python script. The script parses generated HTML files to extract classes, methods, attributes, and functions, then outputs them in JSON format for use as an artifact.
1 parent 37b485d commit 7309e1c

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Docs JSON Export
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
workflow_dispatch:
8+
9+
jobs:
10+
export-docs-json:
11+
name: Export docs.json
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout repository
15+
id: checkout
16+
uses: actions/checkout@v5
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
id: setup-python
21+
with:
22+
python-version: "3.13"
23+
cache: "pip"
24+
cache-dependency-path: "requirements/docs.txt"
25+
check-latest: true
26+
27+
- name: Install dependencies
28+
id: install-deps
29+
run: |
30+
python -m pip install -U pip
31+
pip install ".[docs]"
32+
pip install beautifulsoup4
33+
34+
- name: Build Sphinx HTML docs
35+
id: build-sphinx
36+
run: sphinx-build -b html docs docs/_build/html
37+
38+
- name: Export docs.json
39+
id: generate-json
40+
run: python scripts/docs_json_exporter.py
41+
42+
- name: Upload docs.json as artifact
43+
uses: actions/[email protected]
44+
id: artifact-upload
45+
with:
46+
name: Pycord Docs JSON
47+
path: docs.json
48+
retention-days: 1
49+
50+
- name: Show docs.json summary
51+
run: |
52+
head -n 40 docs.json || tail -n 40 docs.json
53+
54+
- name: Output artifact ID
55+
run: |
56+
echo "artifact-id=${{ steps.artifact-upload.outputs.artifact-id }}" >> $GITHUB_OUTPUT
57+
echo "artifact-url=${{ steps.artifact-upload.outputs.artifact-url }}" >> $GITHUB_OUTPUT
58+
echo "::notice::Artifact uploaded: ${{ steps.artifact-upload.outputs.artifact-url }}"

scripts/docs_json_exporter.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
import os
3+
import json
4+
from bs4 import BeautifulSoup
5+
6+
def log(msg):
7+
print(f"::notice::{msg}")
8+
9+
log("Starting docs JSON export...")
10+
folders = [
11+
"docs/_build/html/api",
12+
"docs/_build/html/ext",
13+
]
14+
result = {}
15+
try:
16+
for folder in folders:
17+
if not os.path.isdir(folder):
18+
log(f"Skipping missing folder: {folder}")
19+
continue
20+
base_html = os.path.normpath("docs/_build/html")
21+
for root, _, files in os.walk(folder):
22+
rel_dir = os.path.relpath(root, base_html).replace("\\", "/") + "/"
23+
if rel_dir not in result:
24+
result[rel_dir] = {}
25+
for html_file in files:
26+
if not html_file.endswith(".html"):
27+
continue
28+
file_path = os.path.join(root, html_file)
29+
with open(file_path, encoding="utf-8") as f:
30+
soup = BeautifulSoup(f, "html.parser")
31+
page_index = {}
32+
for class_dl in soup.find_all("dl", class_="class"):
33+
dt = class_dl.find("dt")
34+
class_name = dt.get("id") if dt else None
35+
if not class_name:
36+
class_name = dt.text.split(":")[-1].strip() if dt else None
37+
members = []
38+
for member_dl in class_dl.find_all("dl", class_=["attribute", "method"]):
39+
for member_dt in member_dl.find_all("dt"):
40+
member_id = member_dt.get("id")
41+
member_name = member_id.split(".")[-1] if member_id else member_dt.text.split(":")[-1].strip()
42+
if member_name:
43+
members.append(member_name)
44+
page_index[class_name] = members
45+
for func_dl in soup.find_all("dl", class_="function"):
46+
dt = func_dl.find("dt")
47+
func_name = dt.get("id") if dt else None
48+
if not func_name:
49+
func_name = dt.text.split(":")[-1].strip() if dt else None
50+
page_index[func_name] = []
51+
result[rel_dir][html_file] = page_index
52+
cleaned_result = {k: v for k, v in result.items() if v}
53+
with open("docs.json", "w", encoding="utf-8") as out:
54+
json.dump(cleaned_result, out, indent=2, ensure_ascii=False)
55+
log("Exported docs to docs.json")
56+
log("To upload as artifact: docs.json")
57+
except Exception as e:
58+
print(f"::error::Docs JSON export failed: {e}")

0 commit comments

Comments
 (0)