|
1 | | -name: "Pull Request Docs Check" |
| 1 | +name: "Build documentation" |
2 | 2 |
|
3 | 3 | on: |
4 | 4 | pull_request: |
|
7 | 7 | - master |
8 | 8 | - stable* |
9 | 9 |
|
| 10 | +permissions: |
| 11 | + contents: read |
| 12 | + |
10 | 13 | jobs: |
11 | | - user_manual: |
| 14 | + build: |
| 15 | + |
| 16 | + name: Build ${{ matrix.manual.name }} |
12 | 17 | runs-on: ubuntu-latest |
| 18 | + |
| 19 | + strategy: |
| 20 | + matrix: |
| 21 | + manual: |
| 22 | + - name: "user_manual" |
| 23 | + directory: "user_manual" |
| 24 | + make_target: "html" |
| 25 | + build_path: "_build/html" |
| 26 | + build_pdf_path: "_build/latex" |
| 27 | + publish: true |
| 28 | + |
| 29 | + - name: "user_manual-en" |
| 30 | + directory: "user_manual" |
| 31 | + make_target: "html-lang-en" |
| 32 | + build_path: "_build/html" |
| 33 | + publish: false |
| 34 | + |
| 35 | + - name: "developer_manual" |
| 36 | + directory: "developer_manual" |
| 37 | + make_target: "html" |
| 38 | + build_path: "_build/html/com" |
| 39 | + publish: true |
| 40 | + |
| 41 | + - name: "admin_manual" |
| 42 | + directory: "admin_manual" |
| 43 | + make_target: "html" |
| 44 | + build_path: "_build/html/com" |
| 45 | + build_pdf_path: "_build/latex" |
| 46 | + publish: true |
| 47 | + |
13 | 48 | steps: |
14 | | - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 |
15 | | - - uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4 |
| 49 | + - name: Cache git metadata |
| 50 | + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 |
16 | 51 | with: |
17 | | - python-version: '3.12' |
18 | | - cache: 'pip' |
19 | | - - name: Install pip dependencies |
20 | | - run: pip install -r requirements.txt |
21 | | - - name: Build using Makefile |
22 | | - run: cd user_manual && make html |
| 52 | + path: .git |
| 53 | + key: git-metadata-${{ github.sha }} |
| 54 | + restore-keys: | |
| 55 | + git-metadata-${{ github.sha }} |
| 56 | + git-metadata |
23 | 57 |
|
24 | | - user_manual-en: |
25 | | - runs-on: ubuntu-latest |
26 | | - steps: |
27 | | - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 |
28 | | - - uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4 |
| 58 | + - name: Checkout repository |
| 59 | + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
| 60 | + |
| 61 | + - name: Configure apt cache to use /dev/shm |
| 62 | + if: ${{ matrix.manual.build_pdf_path }} |
| 63 | + run: | |
| 64 | + mkdir -p /dev/shm/apt/cache/archives |
| 65 | + echo 'Dir::Cache::archives "/dev/shm/apt/cache/archives";' | sudo tee /etc/apt/apt.conf.d/apt-cache-shm |
| 66 | +
|
| 67 | + - name: Cache LaTeX apt packages |
| 68 | + if: ${{ matrix.manual.build_pdf_path }} |
| 69 | + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 |
29 | 70 | with: |
30 | | - python-version: '3.12' |
31 | | - - name: Install pip dependencies |
32 | | - run: pip install -r requirements.txt |
33 | | - - name: Build using Makefile |
34 | | - run: cd user_manual && make html-lang-en |
| 71 | + path: /dev/shm/apt/cache/archives |
| 72 | + key: latex-apt-${{ runner.os }}-${{ hashFiles('.github/workflows/sphinxbuild.yml') }} |
| 73 | + restore-keys: | |
| 74 | + latex-apt-${{ runner.os }}- |
35 | 75 |
|
36 | | - developer_manual: |
37 | | - runs-on: ubuntu-latest |
38 | | - steps: |
39 | | - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 |
40 | | - - uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4 |
| 76 | + - name: Install LaTeX dependencies |
| 77 | + if: ${{ matrix.manual.build_pdf_path }} |
| 78 | + run: | |
| 79 | + sudo DEBIAN_FRONTEND=noninteractive apt-get update |
| 80 | + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ |
| 81 | + --no-install-recommends \ |
| 82 | + python3-pil \ |
| 83 | + python3-pip \ |
| 84 | + tex-gyre \ |
| 85 | + texlive-fonts-recommended \ |
| 86 | + latexmk \ |
| 87 | + texlive-latex-extra \ |
| 88 | + texlive-latex-recommended \ |
| 89 | + texlive-xetex \ |
| 90 | + texlive-fonts-extra-links \ |
| 91 | + texlive-fonts-extra \ |
| 92 | + xindy |
| 93 | +
|
| 94 | + - name: Fix apt cache ownership for caching |
| 95 | + if: ${{ matrix.manual.build_pdf_path }} |
| 96 | + run: sudo chown -R $(id -u):$(id -g) /dev/shm/apt/cache/archives |
| 97 | + |
| 98 | + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 |
41 | 99 | with: |
42 | | - python-version: '3.12' |
| 100 | + python-version: '3.10' |
43 | 101 | cache: 'pip' |
| 102 | + |
44 | 103 | - name: Install pip dependencies |
45 | 104 | run: pip install -r requirements.txt |
46 | | - - name: Build using Makefile |
47 | | - run: cd developer_manual && make html |
48 | 105 |
|
49 | | - admin_manual: |
| 106 | + - name: Build html documentation |
| 107 | + run: cd ${{ matrix.manual.directory }} && make ${{ matrix.manual.make_target }} |
| 108 | + |
| 109 | + - name: Compute PDF release version |
| 110 | + if: ${{ matrix.manual.build_pdf_path }} |
| 111 | + id: pdf_version |
| 112 | + run: | |
| 113 | + branch="${GITHUB_REF#refs/heads/}" |
| 114 | + if [[ "$branch" == stable* ]]; then |
| 115 | + echo "release=${branch#stable}" >> $GITHUB_OUTPUT |
| 116 | + else |
| 117 | + echo "release=latest" >> $GITHUB_OUTPUT |
| 118 | + fi |
| 119 | +
|
| 120 | + - name: Build pdf documentation |
| 121 | + if: ${{ matrix.manual.build_pdf_path }} |
| 122 | + env: |
| 123 | + DOCS_RELEASE: ${{ steps.pdf_version.outputs.release }} |
| 124 | + run: | |
| 125 | + set -e |
| 126 | + cd ${{ matrix.manual.directory }} |
| 127 | + make latexpdf |
| 128 | + ls -la ${{ matrix.manual.build_pdf_path }} |
| 129 | + cp ${{ matrix.manual.build_pdf_path }}/*.pdf ${{ matrix.manual.build_path }}/ |
| 130 | +
|
| 131 | + - name: Upload static documentation |
| 132 | + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 |
| 133 | + if: ${{ matrix.manual.publish }} |
| 134 | + with: |
| 135 | + name: ${{ matrix.manual.name }} |
| 136 | + path: ${{ matrix.manual.directory }}/${{ matrix.manual.build_path }} |
| 137 | + |
| 138 | + deploy: |
| 139 | + name: Deploy pages |
| 140 | + needs: build |
50 | 141 | runs-on: ubuntu-latest |
| 142 | + if: github.event_name == 'push' # Only deploy on push, not PR |
| 143 | + |
| 144 | + permissions: |
| 145 | + contents: write |
| 146 | + |
51 | 147 | steps: |
52 | | - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 |
53 | | - - uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4 |
| 148 | + - name: Cache git metadata |
| 149 | + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 |
54 | 150 | with: |
55 | | - python-version: '3.12' |
56 | | - cache: 'pip' |
57 | | - - name: Install pip dependencies |
58 | | - run: pip install -r requirements.txt |
59 | | - - name: Build using Makefile |
60 | | - run: cd admin_manual && make html |
| 151 | + path: .git |
| 152 | + key: git-metadata-${{ github.sha }} |
| 153 | + restore-keys: | |
| 154 | + git-metadata-${{ github.sha }} |
| 155 | + git-metadata |
| 156 | +
|
| 157 | + - name: Checkout Github Pages branch |
| 158 | + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
61 | 159 | with: |
| 160 | + ref: gh-pages |
| 161 | + fetch-depth: 0 |
| 162 | + token: ${{ secrets.COMMAND_BOT_PAT }} |
| 163 | + |
| 164 | + - name: Download all ${{ needs.build.outputs.branch_name }} artifacts |
| 165 | + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 |
| 166 | + with: |
| 167 | + path: artifacts/ |
| 168 | + |
| 169 | + - name: Get branch name and find latest stable |
| 170 | + id: branch |
| 171 | + run: | |
| 172 | + current_branch="${GITHUB_REF#refs/heads/}" |
| 173 | +
|
| 174 | + # Find the highest numbered stable branch from the remote |
| 175 | + highest_stable=$(git ls-remote --heads origin | sed -n 's?.*refs/heads/stable\([0-9]\{2\}\)$?\1?p' | sort -n | tail -1) |
| 176 | + highest_stable_branch="stable${highest_stable}" |
| 177 | +
|
| 178 | + echo "Current branch: $current_branch" |
| 179 | + echo "Highest stable branch found: $highest_stable_branch" |
| 180 | +
|
| 181 | + # Map actual branch names to deployment folder names |
| 182 | + case "$current_branch" in |
| 183 | + "master") |
| 184 | + echo "branch_name=latest" >> $GITHUB_OUTPUT |
| 185 | + ;; |
| 186 | + "$highest_stable_branch") |
| 187 | + echo "branch_name=stable" >> $GITHUB_OUTPUT |
| 188 | + # Also record the numeric version so we can publish to server/<number>/ too |
| 189 | + echo "version_name=${highest_stable}" >> $GITHUB_OUTPUT |
| 190 | + ;; |
| 191 | + *) |
| 192 | + # Remove stable prefix for current branch |
| 193 | + current_branch="${current_branch#stable}" |
| 194 | + echo "branch_name=$current_branch" >> $GITHUB_OUTPUT |
| 195 | + ;; |
| 196 | + esac |
| 197 | +
|
| 198 | + echo "Deployment folder name: ${{ steps.branch.outputs.branch_name }}" |
| 199 | + echo "Version name for additional deployment (if applicable): ${{ steps.branch.outputs.version_name }}" |
| 200 | +
|
| 201 | + - name: Merge ${{ steps.branch.outputs.branch_name }} documentation artifacts into gh-pages |
| 202 | + run: | |
| 203 | + # List artifacts |
| 204 | + ls -la artifacts/*/ |
| 205 | +
|
| 206 | + # Cleanup old documentation |
| 207 | + rm -rf ${{ steps.branch.outputs.branch_name }} |
| 208 | + rm -rf server/${{ steps.branch.outputs.branch_name }} |
| 209 | + mkdir -p server/${{ steps.branch.outputs.branch_name }} |
| 210 | +
|
| 211 | + # Copy all built documentation into dedicated subdirectories |
| 212 | + for artifact in artifacts/*; do |
| 213 | + if [ -d "$artifact" ]; then |
| 214 | + manual_name="$(basename "$artifact")" |
| 215 | + mkdir -p "server/${{ steps.branch.outputs.branch_name }}/$manual_name" |
| 216 | + cp -r "$artifact/"* "server/${{ steps.branch.outputs.branch_name }}/$manual_name/" |
| 217 | + fi |
| 218 | + done |
| 219 | +
|
| 220 | + # Move pdf files to the root of the branch_name |
| 221 | + mv server/${{ steps.branch.outputs.branch_name }}/*/*.pdf server/${{ steps.branch.outputs.branch_name }}/ || true |
| 222 | +
|
| 223 | + # If this is the highest stable branch, also deploy to its versioned folder |
| 224 | + if [ -n "${{ steps.branch.outputs.version_name }}" ]; then |
| 225 | + rm -rf server/${{ steps.branch.outputs.version_name }} |
| 226 | + cp -r server/${{ steps.branch.outputs.branch_name }} server/${{ steps.branch.outputs.version_name }} |
| 227 | + fi |
| 228 | +
|
| 229 | + # Cleanup |
| 230 | + find . -type d -empty -delete |
| 231 | + rm -rf artifacts |
| 232 | +
|
| 233 | + - name: Add various redirects for go.php and user_manual english version |
| 234 | + run: | |
| 235 | + # Fetch source branches so git checkout origin/... works from the gh-pages checkout |
| 236 | + git fetch origin ${{ github.event.repository.default_branch }} ${{ github.ref_name }} |
| 237 | +
|
| 238 | + # Generate go.php redirect from main branch |
| 239 | + git checkout origin/${{ github.event.repository.default_branch }} -- go.php/index.html |
| 240 | + mkdir -p server/${{ steps.branch.outputs.branch_name }}/go.php |
| 241 | + mv go.php/index.html server/${{ steps.branch.outputs.branch_name }}/go.php/index.html |
| 242 | +
|
| 243 | + # Generate user_manual english redirect |
| 244 | + git checkout origin/${{ github.ref_name }} -- user_manual/index.html |
| 245 | + mkdir -p server/${{ steps.branch.outputs.branch_name }}/user_manual |
| 246 | + mv user_manual/index.html server/${{ steps.branch.outputs.branch_name }}/user_manual/index.html |
| 247 | +
|
| 248 | + - name: Commit ${{ steps.branch.outputs.branch_name }} documentation and push to gh-pages |
| 249 | + run: | |
| 250 | + git config --local user.email "nextcloud-command@users.noreply.github.com" |
| 251 | + git config --local user.name "nextcloud-command" |
| 252 | + git add . |
| 253 | + git diff --staged --quiet || git commit -m "chore: deploy documentation for ${{ steps.branch.outputs.branch_name }}" |
| 254 | + # Ensure we are up to date with the remote gh-pages branch |
| 255 | + git pull --rebase origin gh-pages || true |
| 256 | + git push origin gh-pages || echo "Nothing to push (expected if no changes)" |
| 257 | + env: |
| 258 | + GH_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} |
| 259 | + |
| 260 | + summary: |
| 261 | + needs: build |
| 262 | + runs-on: ubuntu-latest |
| 263 | + if: always() |
| 264 | + |
| 265 | + permissions: |
| 266 | + contents: read |
| 267 | + |
| 268 | + name: build-deploy-summary |
| 269 | + |
| 270 | + steps: |
| 271 | + # Only check if the build was successful |
| 272 | + - name: Summary status |
| 273 | + run: if ${{ needs.build.result != 'success' }}; then exit 1; fi |
0 commit comments