From 361c586a7bd16d1697b6038d4188716f801b9fd5 Mon Sep 17 00:00:00 2001 From: Yuriy Andamasov Date: Fri, 10 Jul 2026 18:21:01 +0300 Subject: docs-infra: force latexmk through per-glyph/per-image LaTeX errors in PDF build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pdflatex hard-errors on the Devanagari etymology text in docs/introducing/history.md ("! LaTeX Error: Unicode character व (U+0935) not set up for use with LaTeX") and separately cannot embed several pre-existing .webp images (no BoundingBox) — both previously undiscovered because the Devanagari error always halted the build first. latexmk -f (force mode) + pdflatex -interaction=nonstopmode makes the build tolerate both classes of per-glyph/per-image failure and finish, matching how ReadTheDocs has always built this project's PDF (verified against the live docs.vyos.io PDF: same Devanagari glyphs blanked, same ~4 images embedded out of 2000+ pages). latexmk exits non-zero in force mode even on a fully-produced PDF, so the workflow step now verifies the artifact itself (exists, >2MB) instead of relying on the command's exit code. 🤖 Generated by [robots](https://vyos.io) --- .github/workflows/docs-build.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to '.github/workflows') diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index fc9a2239..cff205e2 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -56,15 +56,36 @@ jobs: cache-to: type=gha,mode=max - name: Build HTML + PDF in in-workflow-built container + env: + # pdflatex hard-errors ("! LaTeX Error: Unicode character ... not + # set up for use with LaTeX") on the Devanagari etymology text in + # docs/introducing/history.md, and separately cannot embed some + # pre-existing .webp images (no BoundingBox). latexmk's force mode + # (-f) plus non-interactive pdflatex (-interaction=nonstopmode) + # makes it skip both classes of per-glyph/per-image failure and + # finish the document instead of halting — this is how ReadTheDocs + # has always built this project's PDF (verified against the live + # docs.vyos.io PDF: same Devanagari glyphs blanked, same ~4 images + # embedded out of 2000+ pages, rather than a failed build). + # latexmk still exits non-zero in force mode even when it produces + # a complete PDF, so success below is verified by checking the + # artifact itself, not the command's exit code. + LATEXMKOPTS: -f + LATEXOPTS: -interaction=nonstopmode run: | set -eu docker run --rm -v "$PWD:/src" -w /src \ -e DOCS_VERSION_SLUG="${{ steps.matrix.outputs.slug }}" \ -e DOCS_VERSION_BRANCH="${{ github.ref_name }}" \ + -e LATEXMKOPTS \ + -e LATEXOPTS \ docs-build:local bash -c ' + set -e cd docs && make html if [ "${{ inputs.skip_pdf }}" != "true" ]; then - make latexpdf || make latexpdf # retry once (§14 LaTeX flakiness) + make latexpdf || true + pdf=$(find _build/latex -maxdepth 1 -name "*.pdf" -size +2M) + [ -n "$pdf" ] || { echo "no PDF >2MB produced in _build/latex — build genuinely failed"; exit 1; } fi' - name: Assemble artifact (nest under en//, §7.1) -- cgit v1.2.3 From bd19892033a56782065b40a11adf7162a9dacb4a Mon Sep 17 00:00:00 2001 From: Yuriy Andamasov Date: Fri, 10 Jul 2026 19:45:50 +0300 Subject: docs-infra: PDF artifact check — exact file, page-count floor, restored retry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated by [robots](https://vyos.io) --- .github/workflows/docs-build.yml | 24 ++++++++++++++++++++---- docker/Dockerfile | 3 ++- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index cff205e2..3cc4298c 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -69,7 +69,13 @@ jobs: # embedded out of 2000+ pages, rather than a failed build). # latexmk still exits non-zero in force mode even when it produces # a complete PDF, so success below is verified by checking the - # artifact itself, not the command's exit code. + # produced artifact directly (exact filename + page count), not the + # command's exit code. A bare existence/size check would let a + # truncated-but-large PDF (LaTeX aborting partway through) pass, so + # the completeness signal is pdfinfo's page count instead of file + # size. The retry-once below (§14 LaTeX flakiness) still applies + # first; the trailing `|| true` only swallows latexmk -f's expected + # non-zero exit on a genuinely complete document. LATEXMKOPTS: -f LATEXOPTS: -interaction=nonstopmode run: | @@ -83,9 +89,19 @@ jobs: set -e cd docs && make html if [ "${{ inputs.skip_pdf }}" != "true" ]; then - make latexpdf || true - pdf=$(find _build/latex -maxdepth 1 -name "*.pdf" -size +2M) - [ -n "$pdf" ] || { echo "no PDF >2MB produced in _build/latex — build genuinely failed"; exit 1; } + make latexpdf || make latexpdf || true + pdf=_build/latex/VyOS.pdf + [ -f "$pdf" ] || { echo "$pdf not produced — build genuinely failed"; exit 1; } + # Page-count floor as a completeness signal (a truncated forced-mode + # run can still leave behind a file that exists and is large). rolling + # is verified ~2000+ pages; 1.4/1.5 page counts have not been + # individually verified, so 1000 is a conservative floor intended to + # clear all three release branches without masking a real truncation. + pages=$(pdfinfo "$pdf" 2>/dev/null | awk "/^Pages:/{print \$2}") + case "$pages" in + ""|*[!0-9]*) pages=0 ;; + esac + [ "$pages" -ge 1000 ] || { echo "$pdf has $pages pages (<1000) — build genuinely failed"; exit 1; } fi' - name: Assemble artifact (nest under en//, §7.1) diff --git a/docker/Dockerfile b/docker/Dockerfile index fee5c91c..05171a07 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -25,7 +25,8 @@ RUN apt-get update && apt-get install -y \ gosu \ graphviz \ curl \ - dos2unix + dos2unix \ + poppler-utils RUN pip3 install --break-system-packages \ Sphinx \ -- cgit v1.2.3 From ac31ab70216716bcaebb4168074b9a790f4fda8a Mon Sep 17 00:00:00 2001 From: Yuriy Andamasov Date: Fri, 10 Jul 2026 19:57:21 +0300 Subject: docs-infra: retry LaTeX only when PDF absent; constrained poppler install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated by [robots](https://vyos.io) --- .github/workflows/docs-build.yml | 13 +++++++++---- docker/Dockerfile | 6 +++++- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to '.github/workflows') diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index 3cc4298c..bdb9e41d 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -73,9 +73,11 @@ jobs: # command's exit code. A bare existence/size check would let a # truncated-but-large PDF (LaTeX aborting partway through) pass, so # the completeness signal is pdfinfo's page count instead of file - # size. The retry-once below (§14 LaTeX flakiness) still applies - # first; the trailing `|| true` only swallows latexmk -f's expected - # non-zero exit on a genuinely complete document. + # size. The §14 retry-once is gated on artifact ABSENCE: latexmk -f + # exits non-zero even on a fully-produced PDF, so an unconditional + # `|| make latexpdf` would double the ~10-min LaTeX step on every + # forced success. Each `|| true` only swallows that expected + # non-zero exit; the validation below is the real success signal. LATEXMKOPTS: -f LATEXOPTS: -interaction=nonstopmode run: | @@ -89,8 +91,11 @@ jobs: set -e cd docs && make html if [ "${{ inputs.skip_pdf }}" != "true" ]; then - make latexpdf || make latexpdf || true pdf=_build/latex/VyOS.pdf + make latexpdf || true + # retry ONLY when no artifact was produced (§14 LaTeX flakiness) — + # latexmk -f exits non-zero even on success, so exit code cannot gate this + [ -f "$pdf" ] || make latexpdf || true [ -f "$pdf" ] || { echo "$pdf not produced — build genuinely failed"; exit 1; } # Page-count floor as a completeness signal (a truncated forced-mode # run can still leave behind a file that exists and is large). rolling diff --git a/docker/Dockerfile b/docker/Dockerfile index 05171a07..ba79bbb1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -25,7 +25,11 @@ RUN apt-get update && apt-get install -y \ gosu \ graphviz \ curl \ - dos2unix \ + dos2unix + +# pdfinfo (PDF page-count validation in the docs-build workflow) ships in the +# main poppler-utils package — no recommends needed. +RUN apt-get update && apt-get install -y --no-install-recommends \ poppler-utils RUN pip3 install --break-system-packages \ -- cgit v1.2.3