1# Copyright (c) 2020 Linaro Limited.
2# SPDX-License-Identifier: Apache-2.0
3
4name: Documentation Build
5
6on:
7  schedule:
8  - cron: '0 */3 * * *'
9  push:
10    tags:
11    - v*
12  pull_request:
13
14env:
15  # NOTE: west docstrings will be extracted from the version listed here
16  WEST_VERSION: 1.2.0
17  # The latest CMake available directly with apt is 3.18, but we need >=3.20
18  # so we fetch that through pip.
19  CMAKE_VERSION: 3.20.5
20  DOXYGEN_VERSION: 1.12.0
21  # Job count is set to 2 less than the vCPU count of 16 because the total available RAM is 32GiB
22  # and each sphinx-build process may use more than 2GiB of RAM.
23  JOB_COUNT: 14
24
25jobs:
26  doc-file-check:
27    name: Check for doc changes
28    runs-on: ubuntu-22.04
29    if: >
30      github.repository_owner == 'zephyrproject-rtos'
31    outputs:
32      file_check: ${{ steps.check-doc-files.outputs.any_modified }}
33    steps:
34    - name: checkout
35      uses: actions/checkout@v4
36      with:
37        ref: ${{ github.event.pull_request.head.sha }}
38        fetch-depth: 0
39    - name: Check if Documentation related files changed
40      uses: tj-actions/changed-files@v45
41      id: check-doc-files
42      with:
43        files: |
44          doc/
45          boards/**/doc/
46          **.rst
47          include/
48          kernel/include/kernel_arch_interface.h
49          lib/libc/**
50          subsys/testsuite/ztest/include/**
51          tests/
52          **/Kconfig*
53          west.yml
54          scripts/dts/
55          doc/requirements.txt
56          .github/workflows/doc-build.yml
57          scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py
58          scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py
59
60  doc-build-html:
61    name: "Documentation Build (HTML)"
62    needs: [doc-file-check]
63    if: >
64      github.repository_owner == 'zephyrproject-rtos' &&
65        ( needs.doc-file-check.outputs.file_check == 'true' || github.event_name != 'pull_request' )
66    runs-on: ubuntu-22.04
67    timeout-minutes: 90
68    concurrency:
69      group: doc-build-html-${{ github.ref }}
70      cancel-in-progress: true
71
72    steps:
73    - name: install-pkgs
74      run: |
75        sudo apt-get update
76        sudo apt-get install -y wget python3-pip git ninja-build graphviz lcov
77        wget --no-verbose "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz"
78        sudo tar xf doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz -C /opt
79        echo "/opt/doxygen-${DOXYGEN_VERSION}/bin" >> $GITHUB_PATH
80        echo "${HOME}/.local/bin" >> $GITHUB_PATH
81
82    - name: checkout
83      uses: actions/checkout@v4
84      with:
85        ref: ${{ github.event.pull_request.head.sha }}
86        fetch-depth: 0
87
88    - name: Rebase
89      if: github.event_name == 'pull_request'
90      continue-on-error: true
91      env:
92        BASE_REF: ${{ github.base_ref }}
93        PR_HEAD: ${{ github.event.pull_request.head.sha }}
94      run: |
95        git config --global user.email "actions@zephyrproject.org"
96        git config --global user.name "Github Actions"
97        rm -fr ".git/rebase-apply"
98        rm -fr ".git/rebase-merge"
99        git rebase origin/${BASE_REF}
100        git clean -f -d
101        git log --graph --oneline HEAD...${PR_HEAD}
102
103    - name: cache-pip
104      uses: actions/cache@v4
105      with:
106        path: ~/.cache/pip
107        key: pip-${{ hashFiles('doc/requirements.txt') }}
108
109    - name: install-pip
110      run: |
111        pip install -r doc/requirements.txt
112        pip install west==${WEST_VERSION}
113        pip install cmake==${CMAKE_VERSION}
114        pip install coverxygen
115
116    - name: west setup
117      run: |
118        west init -l .
119
120    - name: build-docs
121      shell: bash
122      run: |
123        if [[ "$GITHUB_REF" =~ "refs/tags/v" ]]; then
124          DOC_TAG="release"
125        else
126          DOC_TAG="development"
127        fi
128
129        if [[ "${{ github.event_name }}" == "pull_request" ]]; then
130          DOC_TARGET="html-fast"
131        else
132          DOC_TARGET="html"
133        fi
134
135        DOC_TAG=${DOC_TAG} \
136        SPHINXOPTS="-j ${JOB_COUNT} -W --keep-going -T" \
137        SPHINXOPTS_EXTRA="-q -t publish" \
138        make -C doc ${DOC_TARGET}
139
140        # API documentation coverage
141        python3 -m coverxygen --xml-dir  doc/_build/html/doxygen/xml/ --src-dir include/ --output doc-coverage.info
142        # deprecated page causing issues
143        lcov --remove doc-coverage.info \*/deprecated > new.info
144        genhtml --no-function-coverage --no-branch-coverage new.info -o coverage-report
145
146    - name: compress-docs
147      run: |
148        tar --use-compress-program="xz -T0" -cf html-output.tar.xz --directory=doc/_build html
149        tar --use-compress-program="xz -T0" -cf api-output.tar.xz --directory=doc/_build html/doxygen/html
150        tar --use-compress-program="xz -T0" -cf api-coverage.tar.xz coverage-report
151
152    - name: upload-build
153      uses: actions/upload-artifact@v4
154      with:
155        name: html-output
156        path: html-output.tar.xz
157
158    - name: upload-api-coverage
159      uses: actions/upload-artifact@v4
160      with:
161        name: api-coverage
162        path: api-coverage.tar.xz
163
164    - name: process-pr
165      if: github.event_name == 'pull_request'
166      run: |
167        REPO_NAME="${{ github.event.repository.name }}"
168        PR_NUM="${{ github.event.pull_request.number }}"
169        DOC_URL="https://builds.zephyrproject.io/${REPO_NAME}/pr/${PR_NUM}/docs/"
170        API_DOC_URL="https://builds.zephyrproject.io/${REPO_NAME}/pr/${PR_NUM}/docs/doxygen/html/"
171        API_COVERAGE_URL="https://builds.zephyrproject.io/${REPO_NAME}/pr/${PR_NUM}/api-coverage/"
172
173        echo "${PR_NUM}" > pr_num
174        echo "Documentation will be available shortly at: ${DOC_URL}" >> $GITHUB_STEP_SUMMARY
175        echo "API Documentation will be available shortly at: ${API_DOC_URL}" >> $GITHUB_STEP_SUMMARY
176        echo "API Coverage Report will be available shortly at: ${API_COVERAGE_URL}" >> $GITHUB_STEP_SUMMARY
177
178    - name: upload-pr-number
179      uses: actions/upload-artifact@v4
180      if: github.event_name == 'pull_request'
181      with:
182        name: pr_num
183        path: pr_num
184
185  doc-build-pdf:
186    name: "Documentation Build (PDF)"
187    needs: [doc-file-check]
188    if: |
189      github.event_name != 'pull_request' &&
190      github.repository_owner == 'zephyrproject-rtos'
191    runs-on: ubuntu-22.04
192    container: texlive/texlive:latest
193    timeout-minutes: 120
194    concurrency:
195      group: doc-build-pdf-${{ github.ref }}
196      cancel-in-progress: true
197
198    steps:
199    - name: Apply container owner mismatch workaround
200      run: |
201        git config --global --add safe.directory ${GITHUB_WORKSPACE}
202
203    - name: checkout
204      uses: actions/checkout@v4
205
206    - name: install-pkgs
207      run: |
208        apt-get update
209        apt-get install -y python3-pip python3-venv ninja-build doxygen graphviz librsvg2-bin imagemagick
210
211    - name: cache-pip
212      uses: actions/cache@v4
213      with:
214        path: ~/.cache/pip
215        key: pip-${{ hashFiles('doc/requirements.txt') }}
216
217    - name: setup-venv
218      run: |
219        python3 -m venv .venv
220        . .venv/bin/activate
221        echo PATH=$PATH >> $GITHUB_ENV
222
223    - name: install-pip
224      run: |
225        pip install -r doc/requirements.txt
226        pip install west==${WEST_VERSION}
227        pip install cmake==${CMAKE_VERSION}
228
229    - name: west setup
230      run: |
231        west init -l .
232
233    - name: build-docs
234      shell: bash
235      continue-on-error: true
236      run: |
237        if [[ "$GITHUB_REF" =~ "refs/tags/v" ]]; then
238          DOC_TAG="release"
239        else
240          DOC_TAG="development"
241        fi
242
243        DOC_TAG=${DOC_TAG} \
244        SPHINXOPTS="-q -j ${JOB_COUNT}" \
245        LATEXMKOPTS="-quiet -halt-on-error" \
246        make -C doc pdf
247
248    - name: upload-build
249      if: always()
250      uses: actions/upload-artifact@v4
251      with:
252        name: pdf-output
253        if-no-files-found: ignore
254        path: |
255          doc/_build/latex/zephyr.pdf
256          doc/_build/latex/zephyr.log
257
258  doc-build-status-check:
259    if: always()
260    name: "Documentation Build Status"
261    needs:
262    - doc-build-pdf
263    - doc-file-check
264    - doc-build-html
265    uses: ./.github/workflows/ready-to-merge.yml
266    with:
267      needs_context: ${{ toJson(needs) }}
268