fix: docs build cleanup #5
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
| --- | |
| # Copyright 2026 Google LLC | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: Docs Build and Deploy | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| - 'release/**' | |
| pull_request: | |
| branches: | |
| - main | |
| paths: | |
| - ".github/workflows/docs.yml" | |
| - "requirements-docs.txt" | |
| - "mkdocs.yml" | |
| - "main.py" | |
| - "hooks.py" | |
| - "docs/**" | |
| - "source/**" | |
| jobs: | |
| build_and_deploy: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| actions: read | |
| pages: read | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v5 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| - name: Configure Git Credentials | |
| run: | | |
| git config --global user.name github-actions[bot] | |
| git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Install documentation dependencies | |
| run: uv sync | |
| - name: Lint YAML files | |
| run: uv run yamllint -c .github/linters/.yamllint.yml . | |
| - name: Check for changed files in source | |
| id: source_files_changed | |
| uses: tj-actions/changed-files@v46 | |
| with: | |
| files: source/** | |
| - name: Install ucp-schema for runtime resolution | |
| run: | | |
| cargo install ucp-schema | |
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | |
| - name: Lint source schemas | |
| if: steps.source_files_changed.outputs.any_changed == 'true' | |
| run: ucp-schema lint source/ | |
| - name: Create folders for JSON publishing | |
| run: | | |
| mkdir -p site/schemas | |
| mkdir -p site/services | |
| mkdir -p site/handlers | |
| mkdir -p site/discovery | |
| - name: Configure Site URL | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Fetch the Pages URL. Fails safely if not enabled. | |
| PAGES_URL=$(gh api "repos/${{ github.repository }}/pages" --jq '.html_url' 2>/dev/null || true) | |
| if [ -z "$PAGES_URL" ]; then | |
| echo "Pages URL not detected. Falling back to default structure." | |
| PAGES_URL="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}" | |
| fi | |
| # Ensure trailing slash | |
| if [[ "$PAGES_URL" != */ ]]; then | |
| PAGES_URL="${PAGES_URL}/" | |
| fi | |
| echo "Set SITE_URL to $PAGES_URL" | |
| echo "SITE_URL=$PAGES_URL" >> $GITHUB_ENV | |
| - name: Build and Verify Documentation Site (Main/PR) | |
| if: github.ref == 'refs/heads/main' || github.event.pull_request.base.ref == 'main' | |
| run: | | |
| # Create a full local preview (including mike logic) for validation | |
| bash scripts/build_local.sh --main-only | |
| uv run python scripts/check_links.py local_preview | |
| - name: Build and Verify Specification Docs (Release Branches) | |
| if: startsWith(github.ref, 'refs/heads/release/') || startsWith(github.event.pull_request.base.ref, 'release/') | |
| run: | | |
| export DOCS_MODE=spec | |
| uv run mkdocs build --strict | |
| uv run python scripts/check_links.py site | |
| - name: Deploy development version from main branch | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| run: | | |
| # 1. Deploy Specification Site using mike (DOCS_MODE=spec) | |
| export DOCS_MODE=spec | |
| uv run mike deploy --push draft | |
| # 2. Build Root Site (DOCS_MODE=root) | |
| export DOCS_MODE=root | |
| uv run mkdocs build --strict | |
| # 3. Deploy Root Site to gh-pages root | |
| # Fetch and checkout gh-pages | |
| git fetch origin gh-pages | |
| git checkout gh-pages | |
| # Copy build artifacts to root | |
| cp -r site/* . | |
| rm -rf site | |
| # Add redirects for all specification files | |
| ln -s latest/specification specification | |
| # Commit and push | |
| git add . | |
| git commit -m "Deploy root site from main" --allow-empty | |
| git push origin gh-pages | |
| - name: Deploy release version | |
| if: startsWith(github.ref, 'refs/heads/release/') | |
| run: | | |
| export DOCS_MODE=spec | |
| # Extract the date (e.g., release/2026-01-11 -> 2026-01-11) | |
| VERSION_NAME=${GITHUB_REF#refs/heads/release/} | |
| # Fetch all release branches to determine if this is the latest | |
| git fetch origin "+refs/heads/release/*:refs/remotes/origin/release/*" | |
| # Find the highest version number among all release branches | |
| LATEST_VERSION=$(git branch -r --list "origin/release/*" | sed 's|origin/release/||' | sort -V | tail -n 1 | tr -d ' ') | |
| echo "Deploying version: $VERSION_NAME" | |
| echo "Latest detected version: $LATEST_VERSION" | |
| if [ "$VERSION_NAME" = "$LATEST_VERSION" ]; then | |
| echo "This is the latest version. Updating 'latest' alias." | |
| uv run mike deploy --push --update-aliases "$VERSION_NAME" latest | |
| else | |
| echo "This is NOT the latest version. Deploying without updating 'latest' alias." | |
| uv run mike deploy --push "$VERSION_NAME" | |
| fi | |
| - name: Create GitHub Release and Tag | |
| if: startsWith(github.ref, 'refs/heads/release/') | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION_DATE=${GITHUB_REF#refs/heads/release/} | |
| TAG_NAME="v$VERSION_DATE" | |
| # Create Release (This implicitly creates the git tag) | |
| # The '|| true' ensures the workflow doesn't fail if you | |
| # push updates to this branch later (re-running the build). | |
| gh release create "$TAG_NAME" \ | |
| --title "Release $TAG_NAME" \ | |
| --generate-notes \ | |
| --target "$GITHUB_REF_NAME" \ | |
| || echo "Release $TAG_NAME already exists, skipping creation." |