Skip to content

docs-version-deploy #28

docs-version-deploy

docs-version-deploy #28

name: Build and Deploy Docusaurus Documentation
on:
repository_dispatch:
types: [docs-update, docs-version-deploy]
workflow_dispatch:
inputs:
version:
description: 'Version to build (latest, v0.2.23, etc.)'
required: false
default: 'latest'
type: string
action:
description: 'Action to perform'
required: false
default: 'build-and-deploy'
type: choice
options:
- build-only
- deploy-only
- build-and-deploy
ogx_branch:
description: 'Branch of ogx to build from (default: main)'
required: false
default: 'main'
type: string
permissions:
contents: write
pages: write
id-token: write
jobs:
build:
if: ${{ github.event.inputs.action != 'deploy-only' }}
runs-on: ubuntu-latest
steps:
- name: Checkout this repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Clone ogx repository
run: |
echo "πŸ“₯ Cloning ogx repository..."
TEMP_DIR=$(mktemp -d)
echo "TEMP_DIR=$TEMP_DIR" >> $GITHUB_ENV
git clone https://github.com/${{ github.repository_owner }}/ogx.git "$TEMP_DIR/ogx"
cd "$TEMP_DIR/ogx"
git fetch --all --tags
# Determine version to checkout
VERSION="${{ github.event.client_payload.version || github.event.inputs.version || 'latest' }}"
if [ "$VERSION" = "latest" ] || [ -z "$VERSION" ]; then
LSBRANCH="${{ github.event.inputs.ogx_branch || 'main' }}"
LSBRANCH="${LSBRANCH:-main}"
git checkout "$LSBRANCH"
echo "βœ… Using branch: $LSBRANCH"
echo "BUILDING_LATEST=true" >> $GITHUB_ENV
echo "VERSION_TAG=latest" >> $GITHUB_ENV
else
git checkout "$VERSION"
echo "βœ… Using tag: $VERSION"
echo "BUILDING_LATEST=false" >> $GITHUB_ENV
echo "VERSION_TAG=$VERSION" >> $GITHUB_ENV
fi
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Setup caching for build artifacts
uses: actions/cache@v4
id: cache-npm
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('${{ env.TEMP_DIR }}/ogx/docs/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
- name: Install dependencies and setup versioning
run: |
echo "πŸ“¦ Installing dependencies..."
cd "${{ env.TEMP_DIR }}/ogx/docs"
npm ci
echo "βœ… Dependencies installed"
echo "βš™οΈ Setting up versioning configuration..."
# Copy persistent versionsArchived.json from repo
cp "${{ github.workspace }}/versionsArchived.json" ./
# Archived versions are served as standalone static HTML under docs/vX.Y.Z/
# Docusaurus versioning is not used - always write empty versions.json
echo "[]" > versions.json
echo "βœ… Created empty versions.json (archived versions are static HTML, not Docusaurus versions)"
# Fix GitHub org to match this repo's owner
sed -i "s|https://github.com/ogx-ai/ogx|https://github.com/${{ github.repository_owner }}/ogx|g" docusaurus.config.ts
# Restrict blog to top-level .md/.mdx files only (exclude subdirectory files)
# Docusaurus defaults to '**/*.{md,mdx}' which picks up non-blog .md files from subfolders
node -e "
const fs = require('fs');
let c = fs.readFileSync('docusaurus.config.ts', 'utf8');
if (!c.match(/blog[\s\S]*?include:/)) {
c = c.replace(/(blog:\s*\{)/, \"\\\$1\\n include: ['*.{md,mdx}'],\");
fs.writeFileSync('docusaurus.config.ts', c);
console.log('βœ… Blog include pattern set to top-level only');
} else {
console.log('ℹ️ Blog already has explicit include pattern');
}
"
echo "βœ… Configuration patched"
- name: Cache stable API docs
uses: actions/cache@v4
id: cache-api-stable
with:
path: ${{ env.TEMP_DIR }}/ogx/docs/docs/api
key: api-stable-${{ hashFiles('${{ env.TEMP_DIR }}/ogx/docs/static/ogx-spec.yaml') }}
restore-keys: api-stable-
- name: Cache experimental API docs
uses: actions/cache@v4
id: cache-api-experimental
with:
path: ${{ env.TEMP_DIR }}/ogx/docs/docs/api-experimental
key: api-experimental-${{ hashFiles('${{ env.TEMP_DIR }}/ogx/docs/static/experimental-ogx-spec.yaml') }}
restore-keys: api-experimental-
- name: Cache deprecated API docs
uses: actions/cache@v4
id: cache-api-deprecated
with:
path: ${{ env.TEMP_DIR }}/ogx/docs/docs/api-deprecated
key: api-deprecated-${{ hashFiles('${{ env.TEMP_DIR }}/ogx/docs/static/deprecated-ogx-spec.yaml') }}
restore-keys: api-deprecated-
- name: Build documentation
run: |
cd "${{ env.TEMP_DIR }}/ogx/docs"
# Generate API docs in parallel for better performance
echo "πŸ”„ Generating API docs in parallel..."
# Start background processes for each API docs generation
PIDS=()
# Generate stable API docs if not cached
if [ "${{ steps.cache-api-stable.outputs.cache-hit }}" != 'true' ]; then
echo " πŸ“„ Starting stable API docs generation (cache miss)..."
npm run gen-api-docs stable &
STABLE_PID=$!
PIDS+=($STABLE_PID)
echo " πŸ”„ Stable API docs generation started (PID: $STABLE_PID)"
else
echo " ⚑ Using cached stable API docs"
fi
# Generate experimental API docs if not cached
if [ "${{ steps.cache-api-experimental.outputs.cache-hit }}" != 'true' ]; then
echo " πŸ“„ Starting experimental API docs generation (cache miss)..."
npm run gen-api-docs experimental &
EXPERIMENTAL_PID=$!
PIDS+=($EXPERIMENTAL_PID)
echo " πŸ”„ Experimental API docs generation started (PID: $EXPERIMENTAL_PID)"
else
echo " ⚑ Using cached experimental API docs"
fi
# Generate deprecated API docs if not cached
if [ "${{ steps.cache-api-deprecated.outputs.cache-hit }}" != 'true' ]; then
echo " πŸ“„ Starting deprecated API docs generation (cache miss)..."
npm run gen-api-docs deprecated &
DEPRECATED_PID=$!
PIDS+=($DEPRECATED_PID)
echo " πŸ”„ Deprecated API docs generation started (PID: $DEPRECATED_PID)"
else
echo " ⚑ Using cached deprecated API docs"
fi
# Wait for all parallel processes to complete
if [ ${#PIDS[@]} -gt 0 ]; then
echo " ⏳ Waiting for ${#PIDS[@]} API docs generation processes to complete..."
for pid in "${PIDS[@]}"; do
echo " ⏳ Waiting for process $pid..."
if wait $pid; then
echo " βœ… Process $pid completed successfully"
else
echo " ❌ Process $pid failed"
exit 1
fi
done
fi
echo "βœ… API docs generation completed"
# Create version if not latest (after content is ready)
if [ "${{ env.BUILDING_LATEST }}" != "true" ]; then
echo "πŸ“š Creating Docusaurus version: ${{ env.VERSION_TAG }}"
# Create the version snapshot
npx docusaurus docs:version "${{ env.VERSION_TAG }}"
# Ensure prompt-format.png is available where versioned docs expect it
mkdir -p versioned_docs/resources
if [ ! -f "versioned_docs/resources/prompt-format.png" ]; then
echo "πŸ“₯ Downloading missing prompt-format.png..."
curl -o versioned_docs/resources/prompt-format.png https://raw.githubusercontent.com/${{ github.repository_owner }}/ogx/main/docs/static/img/prompt-format.png
echo "βœ… Downloaded prompt-format.png to versioned_docs/resources/"
else
echo "βœ… prompt-format.png already exists in versioned_docs/resources/"
fi
echo "βœ… Version ${{ env.VERSION_TAG }} created"
else
echo "πŸ—οΈ Building latest version (no version snapshot needed)"
fi
- name: Inline raw-loader imports in versioned docs
if: env.BUILDING_LATEST != 'true'
run: |
cd "${{ env.TEMP_DIR }}/ogx/docs"
echo "πŸ”§ Inlining raw-loader imports in versioned docs..."
if [ -d "versioned_docs" ]; then
for version_dir in versioned_docs/version-*; do
if [ -d "$version_dir" ]; then
echo " Processing $version_dir..."
python3 "${{ github.workspace }}/inline-raw-loader.py" "$version_dir" "${{ env.TEMP_DIR }}/ogx"
fi
done
echo "βœ… Versioned docs raw-loader imports inlined"
else
echo "ℹ️ No versioned docs found"
fi
- name: Build Docusaurus site
run: |
cd "${{ env.TEMP_DIR }}/ogx/docs"
# Patch out duplicate version badges from OpenAPI MDX files
echo "πŸ”§ Patching out duplicate version badges..."
find . -name "ogx-specification.info.mdx" -type f -exec sed -i '/<span$/,/<\/span>$/d' {} \;
echo "πŸ—οΈ Running Docusaurus build..."
npm run build
echo "βœ… Docusaurus build completed"
env:
NODE_OPTIONS: "--max-old-space-size=10240"
- name: Deploy to GitHub Pages
run: |
echo "πŸ—‚οΈ Deploying Docusaurus build..."
DOCS_DIR="${{ github.workspace }}/docs"
# Clear everything except .git, .nojekyll, and archived versions (static HTML under v*)
find "$DOCS_DIR" -mindepth 1 -maxdepth 1 ! -name '.git' ! -name '.nojekyll' ! -name 'v[0-9]*' -exec rm -rf {} +
# Copy Docusaurus build output
cp -r "${{ env.TEMP_DIR }}/ogx/docs/build/"* "$DOCS_DIR/"
cp "${{ github.workspace }}/versions.html" "$DOCS_DIR/versions.html"
# Ensure .nojekyll exists
touch "$DOCS_DIR/.nojekyll"
echo "βœ… Docusaurus content deployed"
- name: Update workspace artifacts
if: env.BUILDING_LATEST != 'true'
run: |
echo "πŸ“‹ Updating workspace versioning artifacts..."
BUILD_PATH="${{ env.TEMP_DIR }}/ogx/docs"
# Copy versioned docs and sidebars to workspace (for git commit)
if [ -d "$BUILD_PATH/versioned_docs" ]; then
cp -r "$BUILD_PATH/versioned_docs" "${{ github.workspace }}/"
echo "βœ… Copied versioned_docs to workspace"
fi
if [ -d "$BUILD_PATH/versioned_sidebars" ]; then
cp -r "$BUILD_PATH/versioned_sidebars" "${{ github.workspace }}/"
echo "βœ… Copied versioned_sidebars to workspace"
fi
# Copy updated versions.json to workspace
cp "$BUILD_PATH/versions.json" "${{ github.workspace }}/"
echo "βœ… Updated workspace versions.json"
- name: Setup versioning files in deployed site
run: |
echo "βš™οΈ Setting up versioning configuration files..."
BUILD_PATH="${{ env.TEMP_DIR }}/ogx/docs"
# Copy versioning files to deployment
cp "$BUILD_PATH/versionsArchived.json" "${{ github.workspace }}/docs/"
cp "$BUILD_PATH/versions.json" "${{ github.workspace }}/docs/"
echo "βœ… Versioning files created"
- name: Verify deployment structure
run: |
echo "πŸ” Verifying deployment structure..."
echo "Contents of docs directory:"
ls -la "${{ github.workspace }}/docs/" | head -10
echo -e "\nVersioning files:"
[ -f "${{ github.workspace }}/docs/versionsArchived.json" ] && echo "βœ… versionsArchived.json exists" || echo "❌ versionsArchived.json missing"
[ -f "${{ github.workspace }}/docs/versions.json" ] && echo "βœ… versions.json exists" || echo "❌ versions.json missing"
echo -e "\nβœ… Structure verification complete"
- name: Commit versioning artifacts
if: env.BUILDING_LATEST != 'true'
run: |
echo "πŸ’Ύ Committing versioning artifacts..."
cd "${{ github.workspace }}"
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
# Add versioning artifacts
git add versioned_docs/ versioned_sidebars/ versions.json 2>/dev/null || true
# Commit if there are changes
if ! git diff --staged --quiet; then
git commit -m "Add Docusaurus version ${{ env.VERSION_TAG }}
- Created version snapshot in versioned_docs/version-${{ env.VERSION_TAG }}/
- Updated versions.json with new version
- Built and deployed multi-version site
πŸ€– Generated by Docusaurus versioning workflow"
git push
echo "βœ… Changes committed and pushed"
else
echo "ℹ️ No changes to commit"
fi
- name: Update versionsArchived.json
if: env.BUILDING_LATEST != 'true'
run: |
cd "${{ github.workspace }}"
TAG="${{ env.VERSION_TAG }}"
python3 -c "
import json
with open('versionsArchived.json') as f:
archived = json.load(f)
tag = '${TAG}'
url = 'https://ogx-ai.github.io/${TAG}/'
if tag not in archived:
archived[tag] = url
def version_key(item):
parts = item[0].lstrip('v').split('.')
return [int(p) for p in parts if p.isdigit()]
archived = dict(sorted(archived.items(), key=version_key, reverse=True))
with open('versionsArchived.json', 'w') as f:
json.dump(archived, f, indent=2)
f.write('\n')
"
git add versionsArchived.json
git diff --staged --quiet || git commit -s -m "docs: add ${TAG} to versionsArchived.json"
git push
- name: Setup GitHub Pages
if: ${{ github.event.inputs.action == 'build-and-deploy' || github.event_name == 'repository_dispatch' }}
uses: actions/configure-pages@v5
- name: Upload Pages artifact
if: ${{ github.event.inputs.action == 'build-and-deploy' || github.event_name == 'repository_dispatch' }}
uses: actions/upload-pages-artifact@v3
with:
path: 'docs'
deploy:
if: ${{ github.event.inputs.action == 'build-and-deploy' || github.event_name == 'repository_dispatch' }}
runs-on: ubuntu-latest
needs: build
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
deploy-only:
if: ${{ github.event.inputs.action == 'deploy-only' }}
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup GitHub Pages
uses: actions/configure-pages@v5
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4