Build and Deploy Docusaurus Documentation #9
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: Build and Deploy Docusaurus Documentation | |
on: | |
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 | |
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 llama-stack repository | |
run: | | |
echo "📥 Cloning llama-stack repository..." | |
TEMP_DIR=$(mktemp -d) | |
echo "TEMP_DIR=$TEMP_DIR" >> $GITHUB_ENV | |
git clone https://github.com/llamastack/llama-stack.git "$TEMP_DIR/llama-stack" | |
cd "$TEMP_DIR/llama-stack" | |
git fetch --all --tags | |
# Determine version to checkout | |
VERSION="${{ github.event.inputs.version }}" | |
if [ "$VERSION" = "latest" ] || [ -z "$VERSION" ]; then | |
git checkout main | |
echo "✅ Using main branch (latest)" | |
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: Install dependencies and setup versioning | |
run: | | |
echo "📦 Installing dependencies..." | |
cd "${{ env.TEMP_DIR }}/llama-stack/docs" | |
npm ci | |
echo "✅ Dependencies installed" | |
echo "⚙️ Setting up versioning configuration..." | |
# Copy persistent versionsArchived.json from repo | |
cp "${{ github.workspace }}/versionsArchived.json" ./ | |
# Load existing versions.json from deployed site or create empty | |
if [ -f "${{ github.workspace }}/docs/versions.json" ]; then | |
# If we're building a specific version, exclude it from the imported versions.json | |
if [ "${{ env.BUILDING_LATEST }}" != "true" ]; then | |
# Filter out the version we're about to build | |
node -e " | |
const versions = JSON.parse(require('fs').readFileSync('${{ github.workspace }}/docs/versions.json', 'utf8')); | |
const filtered = versions.filter(v => v !== '${{ env.VERSION_TAG }}'); | |
require('fs').writeFileSync('versions.json', JSON.stringify(filtered, null, 2)); | |
console.log('✅ Loaded versions.json (filtered out ${{ env.VERSION_TAG }})'); | |
" | |
else | |
cp "${{ github.workspace }}/docs/versions.json" ./ | |
echo "✅ Loaded existing versions.json" | |
fi | |
else | |
echo "[]" > versions.json | |
echo "✅ Created empty versions.json" | |
fi | |
# Patch Docusaurus config for versioning | |
node << 'EOF' | |
const fs = require('fs'); | |
let config = fs.readFileSync('docusaurus.config.ts', 'utf8'); | |
// Add versioning imports after OpenAPI import | |
const versioningImports = ` | |
// Import fs for versioning configuration | |
const fs = require('fs'); | |
// Versioning configuration for llamastack.github.io | |
const versionsArchived = (() => { | |
try { | |
return JSON.parse(fs.readFileSync('./versionsArchived.json', 'utf8')); | |
} catch (e) { | |
console.warn('Could not load versionsArchived.json:', e); | |
return {}; | |
} | |
})(); | |
const archivedVersionsDropdownItems = Object.entries(versionsArchived).map( | |
([versionName, versionUrl]) => ({ | |
label: versionName, | |
href: versionUrl, | |
}) | |
); | |
`; | |
config = config.replace( | |
/import type \* as OpenApiPlugin from "docusaurus-plugin-openapi-docs";/, | |
`import type * as OpenApiPlugin from "docusaurus-plugin-openapi-docs"; | |
${versioningImports}` | |
); | |
// Add version dropdown to navbar (replace GitHub item) | |
const versionDropdown = ` { | |
href: 'https://github.com/llamastack/llama-stack', | |
label: 'GitHub', | |
position: 'right', | |
}, | |
{ | |
type: 'docsVersionDropdown', | |
position: 'right', | |
dropdownItemsAfter: archivedVersionsDropdownItems.length > 0 ? [ | |
{ | |
type: 'html', | |
value: '<hr class="dropdown-separator">', | |
}, | |
{ | |
type: 'html', | |
className: 'dropdown-archived-versions', | |
value: '<b>Previous versions</b>', | |
}, | |
...archivedVersionsDropdownItems, | |
] : [], | |
},`; | |
config = config.replace( | |
/\s*{\s*href:\s*'https:\/\/github\.com\/llamastack\/llama-stack',\s*label:\s*'GitHub',\s*position:\s*'right',\s*},/, | |
versionDropdown | |
); | |
fs.writeFileSync('docusaurus.config.ts', config); | |
console.log('✅ Configuration patched'); | |
EOF | |
echo "✅ Configuration patches applied" | |
- name: Import existing versioning artifacts | |
run: | | |
echo "📥 Importing existing versioning artifacts from repository..." | |
cd "${{ env.TEMP_DIR }}/llama-stack/docs" | |
# Copy existing versioned_docs if they exist | |
if [ -d "${{ github.workspace }}/versioned_docs" ]; then | |
cp -r "${{ github.workspace }}/versioned_docs" ./ | |
echo "✅ Imported existing versioned_docs" | |
else | |
echo "ℹ️ No existing versioned_docs found (first version)" | |
fi | |
# Copy existing versioned_sidebars if they exist | |
if [ -d "${{ github.workspace }}/versioned_sidebars" ]; then | |
cp -r "${{ github.workspace }}/versioned_sidebars" ./ | |
echo "✅ Imported existing versioned_sidebars" | |
else | |
echo "ℹ️ No existing versioned_sidebars found (first version)" | |
fi | |
# Copy existing versions.json if it exists (overrides what we loaded earlier) | |
if [ -f "${{ github.workspace }}/versions.json" ]; then | |
cp "${{ github.workspace }}/versions.json" ./ | |
echo "✅ Imported existing versions.json" | |
else | |
echo "ℹ️ No existing versions.json found (first version)" | |
fi | |
echo "✅ Versioning artifacts import completed" | |
- name: Build documentation | |
run: | | |
cd "${{ env.TEMP_DIR }}/llama-stack/docs" | |
# Generate API docs first (required for current build) | |
npm run gen-api-docs all | |
echo "✅ API docs generated" | |
# 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/llamastack/llama-stack/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: Build Docusaurus site | |
run: | | |
echo "🏗️ Building Docusaurus site..." | |
cd "${{ env.TEMP_DIR }}/llama-stack/docs" | |
# Generate API docs for current build | |
npm run gen-api-docs all | |
# Patch out duplicate version badges from OpenAPI MDX files | |
echo "🔧 Patching out duplicate version badges..." | |
find . -name "llama-stack-specification.info.mdx" -type f -exec sed -i '/<span$/,/<\/span>$/d' {} \; | |
# Also patch versioned files if they exist | |
if [ -d "versioned_docs" ]; then | |
find versioned_docs -name "llama-stack-specification.info.mdx" -type f -exec sed -i '/<span$/,/<\/span>$/d' {} \; | |
fi | |
echo "✅ Version badge patching completed" | |
# Build the site | |
npm run build | |
echo "✅ Docusaurus build completed" | |
- name: Deploy to GitHub Pages | |
run: | | |
echo "🗂️ Deploying Docusaurus build..." | |
DOCS_DIR="${{ github.workspace }}/docs" | |
# Smart deployment: clear everything except .git, .nojekyll, and archived versions | |
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 }}/llama-stack/docs/build/"* "$DOCS_DIR/" | |
# 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 }}/llama-stack/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 }}/llama-stack/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 | |
# Add deployment | |
git add docs/ | |
# 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: Setup GitHub Pages | |
if: ${{ github.event.inputs.action == 'build-and-deploy' }} | |
uses: actions/configure-pages@v5 | |
- name: Upload Pages artifact | |
if: ${{ github.event.inputs.action == 'build-and-deploy' }} | |
uses: actions/upload-pages-artifact@v3 | |
with: | |
path: 'docs' | |
deploy: | |
if: ${{ github.event.inputs.action == 'build-and-deploy' }} | |
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 |