name: "Build documentation" on: pull_request: push: branches: - master - stable* permissions: contents: read jobs: build: name: Build ${{ matrix.manual.name }} runs-on: ubuntu-latest strategy: matrix: manual: - name: "user_manual" directory: "user_manual" make_target: "html" build_path: "_build/html" build_pdf_path: "_build/latex" publish: true - name: "user_manual-en" directory: "user_manual" make_target: "html-lang-en" build_path: "_build/html" publish: false - name: "developer_manual" directory: "developer_manual" make_target: "html" build_path: "_build/html/com" publish: true - name: "admin_manual" directory: "admin_manual" make_target: "html" build_path: "_build/html/com" build_pdf_path: "_build/latex" publish: true steps: - name: Cache git metadata uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: .git key: git-metadata-${{ github.sha }} restore-keys: | git-metadata-${{ github.sha }} git-metadata - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Configure apt cache to use /dev/shm if: ${{ matrix.manual.build_pdf_path }} run: | mkdir -p /dev/shm/apt/cache/archives echo 'Dir::Cache::archives "/dev/shm/apt/cache/archives";' | sudo tee /etc/apt/apt.conf.d/apt-cache-shm - name: Cache LaTeX apt packages if: ${{ matrix.manual.build_pdf_path }} uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: /dev/shm/apt/cache/archives key: latex-apt-${{ runner.os }}-${{ hashFiles('.github/workflows/sphinxbuild.yml') }} restore-keys: | latex-apt-${{ runner.os }}- - name: Install LaTeX dependencies if: ${{ matrix.manual.build_pdf_path }} run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ --no-install-recommends \ python3-pil \ python3-pip \ texlive-fonts-recommended \ latexmk \ texlive-latex-extra \ texlive-latex-recommended \ texlive-xetex \ texlive-fonts-extra-links \ texlive-fonts-extra \ xindy - name: Fix apt cache ownership for caching if: ${{ matrix.manual.build_pdf_path }} run: sudo chown -R $(id -u):$(id -g) /dev/shm/apt/cache/archives - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: '3.12' cache: 'pip' - name: Install pip dependencies run: pip install -r requirements.txt - name: Build html documentation run: cd ${{ matrix.manual.directory }} && make ${{ matrix.manual.make_target }} - name: Compute PDF release version if: ${{ matrix.manual.build_pdf_path }} id: pdf_version run: | branch="${GITHUB_REF#refs/heads/}" if [[ "$branch" == stable* ]]; then echo "release=${branch#stable}" >> $GITHUB_OUTPUT else echo "release=latest" >> $GITHUB_OUTPUT fi - name: Build pdf documentation if: ${{ matrix.manual.build_pdf_path }} env: DOCS_RELEASE: ${{ steps.pdf_version.outputs.release }} run: | set -e cd ${{ matrix.manual.directory }} make latexpdf ls -la ${{ matrix.manual.build_pdf_path }} cp ${{ matrix.manual.build_pdf_path }}/*.pdf ${{ matrix.manual.build_path }}/ - name: Upload static documentation uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: ${{ matrix.manual.publish }} with: name: ${{ matrix.manual.name }} path: ${{ matrix.manual.directory }}/${{ matrix.manual.build_path }} deploy: name: Deploy pages needs: build runs-on: ubuntu-latest if: github.event_name == 'push' # Only deploy on push, not PR permissions: contents: write steps: - name: Cache git metadata uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: .git key: git-metadata-${{ github.sha }} restore-keys: | git-metadata-${{ github.sha }} git-metadata - name: Checkout Github Pages branch uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: gh-pages fetch-depth: 0 token: ${{ secrets.COMMAND_BOT_PAT }} - name: Download all ${{ needs.build.outputs.branch_name }} artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: artifacts/ - name: Get branch name and find latest stable id: branch run: | current_branch="${GITHUB_REF#refs/heads/}" # Find the highest numbered stable branch from the remote highest_stable=$(git ls-remote --heads origin | sed -n 's?.*refs/heads/stable\([0-9]\{2\}\)$?\1?p' | sort -n | tail -1) highest_stable_branch="stable${highest_stable}" echo "Current branch: $current_branch" echo "Highest stable branch found: $highest_stable_branch" # Map actual branch names to deployment folder names case "$current_branch" in "master") echo "branch_name=latest" >> $GITHUB_OUTPUT ;; "$highest_stable_branch") echo "branch_name=stable" >> $GITHUB_OUTPUT # Also record the numeric version so we can publish to server// too echo "version_name=${highest_stable}" >> $GITHUB_OUTPUT ;; *) # Remove stable prefix for current branch current_branch="${current_branch#stable}" echo "branch_name=$current_branch" >> $GITHUB_OUTPUT ;; esac echo "Deployment folder name: ${{ steps.branch.outputs.branch_name }}" echo "Version name for additional deployment (if applicable): ${{ steps.branch.outputs.version_name }}" - name: Merge ${{ steps.branch.outputs.branch_name }} documentation artifacts into gh-pages run: | # List artifacts ls -la artifacts/*/ # Cleanup old documentation rm -rf ${{ steps.branch.outputs.branch_name }} rm -rf server/${{ steps.branch.outputs.branch_name }} mkdir -p server/${{ steps.branch.outputs.branch_name }} # Copy all built documentation into dedicated subdirectories for artifact in artifacts/*; do if [ -d "$artifact" ]; then manual_name="$(basename "$artifact")" mkdir -p "server/${{ steps.branch.outputs.branch_name }}/$manual_name" cp -r "$artifact/"* "server/${{ steps.branch.outputs.branch_name }}/$manual_name/" fi done # Move pdf files to the root of the branch_name mv server/${{ steps.branch.outputs.branch_name }}/*/*.pdf server/${{ steps.branch.outputs.branch_name }}/ || true # If this is the highest stable branch, also deploy to its versioned folder if [ -n "${{ steps.branch.outputs.version_name }}" ]; then rm -rf server/${{ steps.branch.outputs.version_name }} cp -r server/${{ steps.branch.outputs.branch_name }} server/${{ steps.branch.outputs.version_name }} fi # Cleanup find . -type d -empty -delete rm -rf artifacts - name: Add various redirects for go.php and user_manual english version run: | # Fetch source branches so git checkout origin/... works from the gh-pages checkout git fetch origin ${{ github.event.repository.default_branch }} ${{ github.ref_name }} # Generate go.php redirect from main branch git checkout origin/${{ github.event.repository.default_branch }} -- go.php/index.html mkdir -p server/${{ steps.branch.outputs.branch_name }}/go.php mv go.php/index.html server/${{ steps.branch.outputs.branch_name }}/go.php/index.html # Generate user_manual english redirect git checkout origin/${{ github.ref_name }} -- user_manual/index.html mkdir -p server/${{ steps.branch.outputs.branch_name }}/user_manual mv user_manual/index.html server/${{ steps.branch.outputs.branch_name }}/user_manual/index.html - name: Commit ${{ steps.branch.outputs.branch_name }} documentation and push to gh-pages run: | git config --local user.email "nextcloud-command@users.noreply.github.com" git config --local user.name "nextcloud-command" git add . git diff --staged --quiet || git commit -m "chore: deploy documentation for ${{ steps.branch.outputs.branch_name }}" # Ensure we are up to date with the remote gh-pages branch git pull --rebase origin gh-pages || true git push origin gh-pages || echo "Nothing to push (expected if no changes)" env: GH_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} summary: needs: build runs-on: ubuntu-latest-low if: always() permissions: contents: read name: build-deploy-summary steps: # Only check if the build was successful - name: Summary status run: if ${{ needs.build.result != 'success' }}; then exit 1; fi