-
Notifications
You must be signed in to change notification settings - Fork 281
docs: custom multi-version build with git worktree, CSS fix for long … #765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
ee7b6e0
docs: custom multi-version build with git worktree, CSS fix for long …
cmgzn 6ff8d35
Update docs/sphinx_doc/source/_static/sidebar-menu.css
cmgzn c6a35a9
docs: update sidebar bottom menu template and conf settings
cmgzn fa76c1c
docs: enhance doc build script and fix version links
cmgzn ab9c3ae
refactor: remove unused function in conf.py
cmgzn 429abc1
docs: update sphinx doc build script and config
cmgzn 626d2e3
docs: refine doc build script and conf settings
cmgzn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
This file was deleted.
Oops, something went wrong.
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,73 @@ | ||
#!/bin/bash | ||
|
||
# Get project root directory (assuming we're in docs/sphinx_doc) | ||
PROJECT_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" | ||
WORKTREES_DIR="$PROJECT_ROOT/.worktrees" | ||
|
||
# Cleanup function: handle git worktree related issues | ||
cleanup_worktrees() { | ||
echo "Cleaning up git worktrees..." | ||
echo "Project root: $PROJECT_ROOT" | ||
|
||
# Change to project root for git operations | ||
cd "$PROJECT_ROOT" | ||
|
||
# 1. Prune invalid worktree references | ||
git worktree prune 2>/dev/null || true | ||
|
||
# 2. Force remove all worktrees in .worktrees directory | ||
if [ -d "$WORKTREES_DIR" ]; then | ||
echo "Found .worktrees directory at: $WORKTREES_DIR" | ||
for wt_dir in "$WORKTREES_DIR"/*; do | ||
if [ -d "$wt_dir" ]; then | ||
wt_name=$(basename "$wt_dir") | ||
echo " Removing worktree: $wt_name" | ||
# Try normal removal first | ||
git worktree remove --force "$wt_dir" 2>/dev/null || { | ||
# If normal removal fails, force delete directory | ||
echo " Force deleting directory: $wt_dir" | ||
rm -rf "$wt_dir" | ||
} | ||
fi | ||
done | ||
# Remove empty .worktrees directory | ||
rmdir "$WORKTREES_DIR" 2>/dev/null || true | ||
fi | ||
|
||
# 3. Prune worktree references again | ||
git worktree prune 2>/dev/null || true | ||
|
||
echo "Worktree cleanup completed" | ||
|
||
# Return to original directory | ||
cd - > /dev/null | ||
} | ||
|
||
# Error handling function | ||
handle_error() { | ||
echo "Error occurred during build process, cleaning up..." | ||
cleanup_worktrees | ||
exit 1 | ||
} | ||
|
||
# Set up error handling | ||
trap handle_error ERR | ||
|
||
# Store current directory | ||
ORIGINAL_DIR=$(pwd) | ||
|
||
# Pre-cleanup: ensure clean environment before starting | ||
echo "Pre-cleanup before build..." | ||
echo "Current directory: $ORIGINAL_DIR" | ||
cleanup_worktrees | ||
|
||
# Execute original build process (back in docs/sphinx_doc) | ||
echo "Starting build..." | ||
make clean | ||
languages=(en zh_CN) | ||
python build_versions.py | ||
|
||
for lang in "${languages[@]}"; do | ||
sphinx-multiversion source build/$lang -D "language=$lang" | ||
done | ||
# # Post-build cleanup (optional, as build_versions.py already has cleanup logic) | ||
# echo "Build completed, performing final cleanup..." | ||
# cleanup_worktrees | ||
|
||
echo "All operations completed successfully!" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import re | ||
import shutil | ||
import subprocess | ||
from pathlib import Path | ||
from packaging import version as pv | ||
|
||
# Repository structure and build configuration | ||
REPO_ROOT = Path(__file__).resolve().parents[2] | ||
SITE_DIR = REPO_ROOT / "docs" / "sphinx_doc" / "build" # Build output directory | ||
WORKTREES_DIR = REPO_ROOT / ".worktrees" # Temporary worktree directory for version builds | ||
DOCS_REL = Path("docs/sphinx_doc") | ||
LANGS = ["en", "zh_CN"] # Supported documentation languages | ||
MIN_TAG = "v1.4.0" # Minimum version tag to build | ||
REMOTE = "origin" # Git remote name | ||
|
||
# Build options | ||
KEEP_WORKTREES = False # Whether to keep worktrees after build (default: cleanup) | ||
HAS_SUBMODULES = False # Set True if repo uses submodules and needs initialization | ||
|
||
def run(cmd, cwd=None, env=None, check=True): | ||
"""Execute shell command with logging""" | ||
print(f"[RUN] {' '.join(map(str, cmd))}") | ||
subprocess.run(cmd, cwd=cwd, env=env, check=check) | ||
|
||
def is_valid_tag(tag: str) -> bool: | ||
"""Check if tag matches version pattern and meets minimum version requirement""" | ||
if not re.match(r"^v\d+\.\d+\.\d+$", tag): | ||
return False | ||
try: | ||
return pv.parse(tag) >= pv.parse(MIN_TAG) | ||
except Exception: | ||
return False | ||
|
||
def get_tags(): | ||
"""Fetch and filter valid version tags from remote repository""" | ||
run(["git", "fetch", "--tags", "--force", REMOTE]) | ||
out = subprocess.check_output(["git", "tag"], text=True).strip() | ||
tags = [t for t in out.splitlines() if t] | ||
return [t for t in tags if is_valid_tag(t)] | ||
|
||
def ensure_clean_worktree(path: Path): | ||
"""Remove existing worktree if present to ensure clean state""" | ||
if path.exists(): | ||
try: | ||
run(["git", "worktree", "remove", "--force", str(path)]) | ||
except Exception: | ||
cmgzn marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
shutil.rmtree(path, ignore_errors=True) | ||
|
||
def copy_docs_source_to(wt_root: Path): | ||
"""Copy current docs source to worktree to unify templates and extensions""" | ||
src = REPO_ROOT / DOCS_REL | ||
dst = wt_root / DOCS_REL | ||
dst.parent.mkdir(parents=True, exist_ok=True) | ||
print(f"[COPY] {src} -> {dst}") | ||
shutil.copytree(src, dst, dirs_exist_ok=True, ignore=shutil.ignore_patterns(".git", "build", ".pyc")) | ||
|
||
def maybe_init_submodules(wt_root: Path): | ||
"""Initialize submodules in worktree if repository uses them""" | ||
if HAS_SUBMODULES: | ||
try: | ||
run(["git", "submodule", "update", "--init", "--recursive"], cwd=wt_root) | ||
except Exception as e: | ||
print(f"[WARN] submodule init failed: {e}") | ||
|
||
def copy_markdown_files(wt_root: Path): | ||
for md_file in wt_root.rglob("*.md"): | ||
exclude_paths = ["outputs", "sphinx_doc", ".github"] | ||
if any(path in str(md_file) for path in exclude_paths): | ||
continue | ||
target = wt_root / DOCS_REL / "source" / md_file.relative_to(wt_root) | ||
target.parent.mkdir(parents=True, exist_ok=True) | ||
if not target.exists(): | ||
shutil.copy2(md_file, target) | ||
|
||
def build_one(ref: str, ref_label: str, available_versions: list[str]): | ||
"""Build documentation for a single version/branch""" | ||
# Create and setup worktree for the specific git reference | ||
wt = WORKTREES_DIR / ref_label | ||
ensure_clean_worktree(wt) | ||
run(["git", "worktree", "add", "--force", str(wt), ref]) | ||
maybe_init_submodules(wt) | ||
|
||
# Override docs/sphinx_doc with current repo version for unified templates | ||
copy_docs_source_to(wt) | ||
copy_markdown_files(wt) | ||
|
||
src = wt / DOCS_REL / "source" | ||
if not src.exists(): | ||
print(f"[SKIP] {ref_label}: {src} not found") | ||
if not KEEP_WORKTREES: | ||
run(["git", "worktree", "remove", "--force", str(wt)]) | ||
return | ||
|
||
# Build documentation for each supported language | ||
for lang in LANGS: | ||
out_dir = SITE_DIR / lang / ref_label | ||
out_dir.mkdir(parents=True, exist_ok=True) | ||
|
||
# Setup environment variables for Sphinx build | ||
env = os.environ.copy() | ||
env["DOCS_VERSION"] = ref_label # Documentation version label (e.g., latest, v1.5.0) | ||
env["GIT_REF_FOR_LINKS"] = ref # Git reference for GitHub links | ||
env["AVAILABLE_VERSIONS"] = ",".join(available_versions) # All available versions for switcher | ||
env["REPO_ROOT"] = str(wt) # Version-specific repo root for copying markdown files | ||
env["CODE_ROOT"] = str(wt) # Version-specific code root for autodoc imports | ||
|
||
# Generate the API rst files | ||
api_cmd = [ | ||
"sphinx-apidoc", | ||
"-o", str(wt / DOCS_REL / "source" / "api"), | ||
str(wt / "data_juicer"), | ||
"-t", "_templates", | ||
"-e" | ||
] | ||
run(api_cmd, env=env) | ||
|
||
# Execute Sphinx build command | ||
cmd = [ | ||
"sphinx-build", | ||
"-b", "html", # HTML builder | ||
"-D", f"language={lang}", # Set language for this build | ||
"-j", "auto", | ||
str(src), # Source directory | ||
str(out_dir), # Output directory | ||
] | ||
run(cmd, env=env) | ||
|
||
# Cleanup worktree after successful build | ||
if not KEEP_WORKTREES: | ||
run(["git", "worktree", "remove", "--force", str(wt)]) | ||
try: | ||
run(["git", "worktree", "prune"]) # Clean up worktree references | ||
except Exception: | ||
pass | ||
|
||
def main(): | ||
"""Main entry point: build documentation for all versions""" | ||
WORKTREES_DIR.mkdir(exist_ok=True) | ||
tags = get_tags() | ||
tags.sort(key=pv.parse, reverse=True) | ||
versions = ["main"] + tags # Build main branch + all valid tags | ||
|
||
# Build main branch first, then all tagged versions | ||
build_one("main", "main", versions) | ||
for t in tags: | ||
build_one(t, t, versions) | ||
|
||
if __name__ == "__main__": | ||
main() |
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.