Deploy Documentation #232
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
| # Workflow for deploying versioned documentation to GitHub Pages | |
| name: Deploy Documentation | |
| env: | |
| # Disable Husky Git hooks in CI to prevent local development hooks | |
| # (e.g., pre-commit formatting checks) from running during automated | |
| # workflows that perform git commits and pushes. | |
| HUSKY: 0 | |
| on: | |
| # Runs after Build & Test succeeds on main (publishes to /snapshot/) | |
| workflow_run: | |
| workflows: ["Build & Test"] | |
| types: [completed] | |
| branches: [main] | |
| # Runs on release publish (publishes to /latest/ and /vX.Y.Z/) | |
| release: | |
| types: [published] | |
| # Allows manual trigger | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Specific version/tag to build (leave empty for snapshot from main)' | |
| type: string | |
| default: '' | |
| publish_as_latest: | |
| description: 'Also publish as latest?' | |
| type: boolean | |
| default: false | |
| rebuild_all_versions: | |
| description: 'Rebuild documentation for all release tags?' | |
| type: boolean | |
| default: false | |
| # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages | |
| permissions: | |
| actions: read # Required to download artifacts from Build & Test workflow | |
| contents: write | |
| pages: write | |
| id-token: write | |
| # Allow only one concurrent deployment | |
| concurrency: | |
| group: "pages" | |
| cancel-in-progress: false | |
| jobs: | |
| build-and-deploy: | |
| # Skip if triggered by workflow_run that failed | |
| if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: '17' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Checkout gh-pages branch | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: gh-pages | |
| path: site | |
| continue-on-error: true | |
| - name: Initialize site if needed | |
| run: | | |
| if [ ! -d "site/.git" ]; then | |
| rm -rf site | |
| mkdir -p site | |
| cd site | |
| git init | |
| git checkout -b gh-pages | |
| git remote add origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" | |
| fi | |
| - name: Get all release tags | |
| id: tags | |
| run: | | |
| # Get all tags that look like version numbers (v1.0.0 or 1.0.0) | |
| TAGS=$(git tag -l | grep -E '^v?[0-9]+\.[0-9]+' | sort -Vr) | |
| echo "all_tags<<EOF" >> $GITHUB_OUTPUT | |
| echo "$TAGS" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| # Get the latest tag | |
| LATEST_TAG=$(echo "$TAGS" | head -n 1) | |
| echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT | |
| # Determine what to build | |
| if [[ "${{ github.event_name }}" == "release" ]]; then | |
| echo "build_tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT | |
| echo "is_release=true" >> $GITHUB_OUTPUT | |
| elif [[ -n "${{ inputs.version }}" ]]; then | |
| # Manual trigger with specific version | |
| VERSION="${{ inputs.version }}" | |
| # Add 'v' prefix if not present for tag lookup | |
| if [[ ! "$VERSION" =~ ^v ]]; then | |
| TAG="v$VERSION" | |
| else | |
| TAG="$VERSION" | |
| fi | |
| echo "build_tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "is_release=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "build_tag=" >> $GITHUB_OUTPUT | |
| echo "is_release=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Download test results from Build & Test | |
| if: steps.tags.outputs.is_release == 'false' && inputs.rebuild_all_versions != true && github.event_name == 'workflow_run' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: test-results-for-site | |
| path: /tmp/test-results | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| continue-on-error: true | |
| - name: Build snapshot documentation (main branch) | |
| if: steps.tags.outputs.is_release == 'false' && inputs.rebuild_all_versions != true | |
| run: | | |
| # Compile sources (needed for javadoc and other reports) | |
| ./mvnw clean compile -DskipTests -Dcheckstyle.skip=true | |
| # Restore test results from Build & Test (for JaCoCo + Surefire reports) | |
| # upload-artifact strips the common ancestor (target/), so files are at root | |
| if [ -d "/tmp/test-results/surefire-reports" ]; then | |
| mkdir -p target/surefire-reports | |
| cp -r /tmp/test-results/surefire-reports/* target/surefire-reports/ | |
| echo "Surefire reports restored" | |
| fi | |
| if [ -f "/tmp/test-results/jacoco-test-results/sdk-tests.exec" ]; then | |
| mkdir -p target/jacoco-test-results | |
| cp /tmp/test-results/jacoco-test-results/sdk-tests.exec target/jacoco-test-results/ | |
| echo "JaCoCo exec restored" | |
| fi | |
| # Generate site (report plugins pick up the restored data) | |
| ./mvnw site -DskipTests -Dcheckstyle.skip=true | |
| rm -rf "site/snapshot" | |
| mkdir -p "site/snapshot" | |
| cp -r target/site/* "site/snapshot/" | |
| - name: Build documentation for specific version | |
| if: steps.tags.outputs.is_release == 'true' && inputs.rebuild_all_versions != true | |
| run: | | |
| TAG="${{ steps.tags.outputs.build_tag }}" | |
| VERSION="${TAG#v}" # Remove 'v' prefix | |
| echo "Building documentation for $TAG (version $VERSION)" | |
| git checkout "$TAG" | |
| ./mvnw clean site -DskipTests -Dcheckstyle.skip=true | |
| rm -rf "site/$VERSION" | |
| mkdir -p "site/$VERSION" | |
| cp -r target/site/* "site/$VERSION/" | |
| # Update /latest/ if this is a release event or publish_as_latest is true | |
| if [[ "${{ github.event_name }}" == "release" ]] || [[ "${{ inputs.publish_as_latest }}" == "true" ]]; then | |
| rm -rf "site/latest" | |
| mkdir -p "site/latest" | |
| cp -r target/site/* "site/latest/" | |
| fi | |
| git checkout main | |
| - name: Build documentation for all release tags | |
| if: inputs.rebuild_all_versions == true | |
| run: | | |
| LATEST_TAG="${{ steps.tags.outputs.latest_tag }}" | |
| while IFS= read -r TAG; do | |
| if [[ -z "$TAG" ]]; then continue; fi | |
| VERSION="${TAG#v}" # Remove 'v' prefix | |
| echo "Building documentation for $TAG (version $VERSION)" | |
| git checkout "$TAG" | |
| ./mvnw clean site -DskipTests -Dcheckstyle.skip=true | |
| rm -rf "site/$VERSION" | |
| mkdir -p "site/$VERSION" | |
| cp -r target/site/* "site/$VERSION/" | |
| # If this is the latest tag, also update /latest/ | |
| if [[ "$TAG" == "$LATEST_TAG" ]]; then | |
| rm -rf "site/latest" | |
| mkdir -p "site/latest" | |
| cp -r target/site/* "site/latest/" | |
| fi | |
| done <<< "${{ steps.tags.outputs.all_tags }}" | |
| # Return to main and build snapshot | |
| git checkout main | |
| ./mvnw clean site -DskipTests -Dcheckstyle.skip=true | |
| rm -rf "site/snapshot" | |
| mkdir -p "site/snapshot" | |
| cp -r target/site/* "site/snapshot/" | |
| - name: Copy version index page | |
| run: | | |
| cp .github/templates/index.html site/index.html | |
| cp .github/templates/styles.css site/styles.css | |
| - name: Update version list from git tags | |
| run: | | |
| cd site | |
| REPO_URL="https://github.com/copilot-community-sdk/copilot-sdk-java" | |
| # Get versions from git tags (already sorted by version, descending) | |
| VERSIONS=$(git -C .. tag -l | grep -E '^v?[0-9]+\.[0-9]+' | sed 's/^v//' | sort -Vr) | |
| HAS_SNAPSHOT=$([ -d "snapshot" ] && echo "true" || echo "false") | |
| # Generate version links | |
| CURRENT_HTML="" | |
| OLDER_HTML="" | |
| IS_FIRST_VERSION="true" | |
| # Add snapshot if exists (goes to current versions) | |
| if [ "$HAS_SNAPSHOT" = "true" ]; then | |
| CURRENT_HTML+='<li><span class="version-name">Development (main branch)</span><span class="version-links"><a href="./snapshot/" class="doc-link">documentation ↗</a><a href="'"$REPO_URL"'/blob/main/CHANGELOG.md" class="release-link">changelog ↗</a><span class="badge snapshot">snapshot</span></span></li>' | |
| fi | |
| # Add versioned releases from tags (first one is latest, rest go to older) | |
| for v in $VERSIONS; do | |
| if [ -d "$v" ]; then | |
| if [ "$IS_FIRST_VERSION" = "true" ]; then | |
| CURRENT_HTML+='<li class="latest-version"><span class="version-name">Version '"$v"'</span><span class="version-links"><a href="./'"$v"'/" class="doc-link">documentation ↗</a><a href="'"$REPO_URL"'/releases/tag/v'"$v"'" class="release-link">release notes ↗</a><span class="badge latest">latest</span></span></li>' | |
| IS_FIRST_VERSION="false" | |
| else | |
| OLDER_HTML+='<li><span>'"$v"'</span><span class="older-links"><a href="./'"$v"'/" class="doc-link">documentation ↗</a><a href="'"$REPO_URL"'/releases/tag/v'"$v"'" class="release-link">release notes ↗</a></span></li>' | |
| fi | |
| fi | |
| done | |
| # Update the index.html using the placeholders | |
| sed -i "s|<!-- CURRENT_VERSIONS_PLACEHOLDER -->|$CURRENT_HTML|" index.html | |
| sed -i "s|<!-- OLDER_VERSIONS_PLACEHOLDER -->|$OLDER_HTML|" index.html | |
| - name: Overlay custom JaCoCo CSS | |
| run: | | |
| cd site | |
| for dir in */jacoco/jacoco-resources; do | |
| if [ -d "$dir" ]; then | |
| cp ../src/site/jacoco-resources/report.css "$dir/report.css" | |
| echo "Overlaid JaCoCo CSS in $dir" | |
| fi | |
| done | |
| - name: Deploy to GitHub Pages | |
| run: | | |
| cd site | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| # Set remote URL with token for authentication | |
| git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" 2>/dev/null || \ | |
| git remote add origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" | |
| git add -A | |
| # Create descriptive commit message | |
| if [[ "${{ inputs.rebuild_all_versions }}" == "true" ]]; then | |
| COMMIT_MSG="Rebuild documentation for all versions" | |
| elif [[ "${{ steps.tags.outputs.is_release }}" == "true" ]]; then | |
| COMMIT_MSG="Deploy documentation: ${{ steps.tags.outputs.build_tag }}" | |
| else | |
| COMMIT_MSG="Deploy documentation: snapshot" | |
| fi | |
| git diff --staged --quiet || git commit -m "$COMMIT_MSG" | |
| # Push, creating the branch if it doesn't exist | |
| git push -u origin gh-pages --force | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Pages | |
| uses: actions/configure-pages@v5 | |
| - name: Upload artifact | |
| uses: actions/upload-pages-artifact@v4 | |
| with: | |
| path: 'site' | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 |