129 lines
4.0 KiB
Bash
129 lines
4.0 KiB
Bash
#!/bin/bash
|
|
# Generate Slate documentation from OpenAPI specs
|
|
#
|
|
# This script:
|
|
# 1. Discovers all services with OpenAPI specs
|
|
# 2. Uses widdershins to convert OpenAPI JSON to Slate markdown
|
|
# 3. Injects the generated includes into the main index
|
|
#
|
|
# Usage: ./docs/scripts/generate-docs.sh [base_url]
|
|
# base_url: Optional base URL for fetching specs (default: http://localhost)
|
|
#
|
|
# The script expects services to be running locally during CI/CD build.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
DOCS_DIR="$(dirname "$SCRIPT_DIR")"
|
|
PROJECT_ROOT="$(dirname "$DOCS_DIR")"
|
|
INCLUDES_DIR="$DOCS_DIR/source/includes"
|
|
|
|
BASE_URL="${1:-http://localhost}"
|
|
|
|
echo "==> Generating API documentation from OpenAPI specs"
|
|
echo " Base URL: $BASE_URL"
|
|
echo " Docs dir: $DOCS_DIR"
|
|
|
|
# Ensure includes directory exists
|
|
mkdir -p "$INCLUDES_DIR"
|
|
|
|
# Clean old service includes (keep _errors.md)
|
|
find "$INCLUDES_DIR" -name '_*.md' ! -name '_errors.md' -delete 2>/dev/null || true
|
|
|
|
# Track which services we generate docs for
|
|
SERVICES=()
|
|
|
|
# Discover services by looking for OpenAPI spec files or main.go
|
|
for service_dir in "$PROJECT_ROOT"/services/*/; do
|
|
[ -d "$service_dir" ] || continue
|
|
|
|
service_name=$(basename "$service_dir")
|
|
[ "$service_name" = ".gitkeep" ] && continue
|
|
|
|
echo "==> Processing service: $service_name"
|
|
|
|
# Try to fetch OpenAPI spec from running service
|
|
spec_url="$BASE_URL/api/$service_name/openapi.json"
|
|
spec_file="$INCLUDES_DIR/_${service_name}_spec.json"
|
|
|
|
if curl -sf --connect-timeout 5 "$spec_url" > "$spec_file" 2>/dev/null; then
|
|
echo " Fetched spec from $spec_url"
|
|
else
|
|
# Fallback: check for static spec file
|
|
if [ -f "$service_dir/openapi.json" ]; then
|
|
cp "$service_dir/openapi.json" "$spec_file"
|
|
echo " Using static spec from $service_dir/openapi.json"
|
|
else
|
|
echo " WARNING: No OpenAPI spec found for $service_name, skipping"
|
|
rm -f "$spec_file"
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Convert OpenAPI to Slate markdown using widdershins
|
|
output_file="$INCLUDES_DIR/_${service_name}.md"
|
|
|
|
echo " Converting to markdown..."
|
|
widdershins \
|
|
--language_tabs 'shell:curl' 'go:Go' \
|
|
--summary \
|
|
--omitHeader \
|
|
--resolve \
|
|
--shallowSchemas \
|
|
"$spec_file" \
|
|
-o "$output_file"
|
|
|
|
# Clean up temp spec file
|
|
rm -f "$spec_file"
|
|
|
|
SERVICES+=("$service_name")
|
|
echo " Generated: $output_file"
|
|
done
|
|
|
|
# Update index.html.md with service includes
|
|
INDEX_FILE="$DOCS_DIR/source/index.html.md"
|
|
if [ -f "$INDEX_FILE" ]; then
|
|
echo "==> Updating index with service includes"
|
|
|
|
# Build includes list
|
|
INCLUDES=""
|
|
for svc in "${SERVICES[@]}"; do
|
|
INCLUDES="$INCLUDES - $svc"$'\n'
|
|
done
|
|
|
|
# Update the includes section in frontmatter
|
|
# This is a simple approach - insert after 'includes:' line
|
|
if grep -q "^includes:" "$INDEX_FILE"; then
|
|
# Create temp file with updated includes
|
|
awk -v services="$INCLUDES" '
|
|
/^includes:/ {
|
|
print $0
|
|
print " - errors"
|
|
# Add service includes
|
|
n = split(services, arr, "\n")
|
|
for (i = 1; i <= n; i++) {
|
|
if (arr[i] != "") print arr[i]
|
|
}
|
|
# Skip existing includes until next frontmatter key or ---
|
|
while ((getline line) > 0) {
|
|
if (line ~ /^[a-z_]+:/ || line == "---") {
|
|
print line
|
|
break
|
|
}
|
|
}
|
|
next
|
|
}
|
|
{ print }
|
|
' "$INDEX_FILE" > "$INDEX_FILE.tmp" && mv "$INDEX_FILE.tmp" "$INDEX_FILE"
|
|
fi
|
|
|
|
echo " Updated includes: ${SERVICES[*]:-none}"
|
|
fi
|
|
|
|
echo ""
|
|
echo "==> Documentation generation complete"
|
|
echo " Services documented: ${#SERVICES[@]}"
|
|
echo ""
|
|
echo "To build the static site:"
|
|
echo " cd $DOCS_DIR && bundle exec middleman build"
|