fix(ci): copy Libertinus OTFs into fontconfig's scan path #18
Workflow file for this run
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
| # Triggered automatically when Gitea mirrors a release@x.y.z tag to GitHub. | |
| # Builds the standard application distribution archives (zip + tar) and | |
| # publishes them as assets on the corresponding GitHub Release. | |
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - 'release@*' | |
| permissions: | |
| contents: write # required to create GitHub Releases and upload assets | |
| jobs: | |
| build-and-release: | |
| name: Build distribution and publish release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # full history + all tags are required by com.palantir.git-version | |
| - name: Set up JDK 21 (Temurin) | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| with: | |
| build-scan-publish: true | |
| build-scan-terms-of-service-url: "https://gradle.com/help/legal-terms-of-use" | |
| build-scan-terms-of-service-agree: "yes" | |
| - name: Set up Node.js (required by TypeScript discovery plugin) | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 'lts/*' | |
| # ----------------------------------------------------------------------- | |
| # Quality gate – explicit named steps so each check is visible in the log. | |
| # ----------------------------------------------------------------------- | |
| - name: Run tests | |
| run: ./gradlew test | |
| - name: Verify JaCoCo instruction coverage ≥ 70 % | |
| run: ./gradlew jacocoTestCoverageVerification | |
| - name: PMD static analysis | |
| run: ./gradlew pmdMain | |
| - name: SpotBugs analysis | |
| run: ./gradlew spotbugsMain | |
| # ----------------------------------------------------------------------- | |
| # Build artefacts | |
| # ----------------------------------------------------------------------- | |
| - name: Build distribution archives | |
| run: ./gradlew distZip distTar | |
| - name: Generate CycloneDX SBOM | |
| run: ./gradlew cyclonedxBom | |
| # ----------------------------------------------------------------------- | |
| # Documentation PDF. Built on demand only — not part of the standard | |
| # `build` lifecycle. Requires pandoc, XeLaTeX, Mermaid CLI, and Python | |
| # which are installed below. The output is published alongside the | |
| # distribution archives so the release asset bundle is self-contained. | |
| # ----------------------------------------------------------------------- | |
| - name: Install pandoc and XeLaTeX (TeX Live) | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install --no-install-recommends -y \ | |
| pandoc \ | |
| texlive-xetex \ | |
| texlive-fonts-recommended \ | |
| texlive-fonts-extra \ | |
| texlive-latex-recommended \ | |
| texlive-latex-extra \ | |
| texlive-plain-generic \ | |
| texlive-pictures \ | |
| lmodern \ | |
| fonts-dejavu | |
| # texlive-fonts-extra ships Libertinus Serif / Sans / Mono OTF | |
| # files inside TeX Live's font tree, but Ubuntu's texlive package | |
| # does NOT register that tree with fontconfig — so xelatex's | |
| # fontspec can't find them by family name. Copy the OTFs into | |
| # /usr/local/share/fonts/ (a path fontconfig always scans) and | |
| # refresh the cache so 'Libertinus Serif' resolves at PDF build | |
| # time. kpsewhich locates the file regardless of TeX Live | |
| # version-specific path layout. | |
| LIBERTINUS_OTF=$(kpsewhich -format=opentype\ fonts LibertinusSerif-Regular.otf || true) | |
| if [ -n "$LIBERTINUS_OTF" ] && [ -f "$LIBERTINUS_OTF" ]; then | |
| LIBERTINUS_DIR=$(dirname "$LIBERTINUS_OTF") | |
| sudo mkdir -p /usr/local/share/fonts/libertinus | |
| sudo cp "$LIBERTINUS_DIR"/*.otf /usr/local/share/fonts/libertinus/ | |
| echo "Copied Libertinus OTF files from $LIBERTINUS_DIR" | |
| else | |
| echo "WARNING: LibertinusSerif-Regular.otf not found via kpsewhich" | |
| fi | |
| sudo fc-cache -f >/dev/null 2>&1 || true | |
| # ---------------------------------------------------------------------- | |
| # Pre-flight verification — every .sty referenced by the LaTeX header, | |
| # back-matter, or pandoc's default xelatex template must be findable on | |
| # the TeX search path. If any is missing the workflow fails here with | |
| # an explicit diagnostic instead of producing a confusing pandoc error. | |
| # Keep this list in sync with methodatlas-docs/src/docs/latex-header.tex | |
| # and back-matter.tex. | |
| # ---------------------------------------------------------------------- | |
| - name: Verify required LaTeX packages and fonts | |
| run: | | |
| set -e | |
| missing=0 | |
| for sty in \ | |
| lmodern.sty \ | |
| fontspec.sty \ | |
| xcolor.sty \ | |
| newunicodechar.sty \ | |
| microtype.sty \ | |
| fvextra.sty \ | |
| fancyvrb.sty \ | |
| booktabs.sty \ | |
| longtable.sty \ | |
| array.sty \ | |
| tabularx.sty \ | |
| titlesec.sty \ | |
| fancyhdr.sty \ | |
| emptypage.sty \ | |
| tcolorbox.sty \ | |
| etoolbox.sty \ | |
| needspace.sty \ | |
| upquote.sty \ | |
| parskip.sty \ | |
| xurl.sty \ | |
| bookmark.sty \ | |
| hyperref.sty \ | |
| graphicx.sty \ | |
| geometry.sty \ | |
| unicode-math.sty; do | |
| if ! kpsewhich "$sty" > /dev/null; then | |
| echo "MISSING: $sty" | |
| missing=$((missing + 1)) | |
| fi | |
| done | |
| if [ "$missing" -gt 0 ]; then | |
| echo "ERROR: $missing required LaTeX style file(s) not found on the TeX path." | |
| echo "Add the providing apt package to the 'Install pandoc and XeLaTeX' step." | |
| exit 1 | |
| fi | |
| # Fonts: verify fontconfig sees what fontspec will ask for. | |
| for family in "Libertinus Serif" "Libertinus Sans" "DejaVu Sans Mono"; do | |
| if ! fc-list | grep -qi "${family}"; then | |
| echo "MISSING font: ${family}" | |
| missing=$((missing + 1)) | |
| fi | |
| done | |
| if [ "$missing" -gt 0 ]; then | |
| echo "ERROR: required font not visible to fontconfig." | |
| exit 1 | |
| fi | |
| echo "All required LaTeX packages and fonts are present." | |
| - name: Install Mermaid CLI | |
| run: npm install --global @mermaid-js/mermaid-cli | |
| - name: Set up Python (for Mermaid + Pandoc preprocessor) | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Build documentation PDF | |
| run: ./gradlew :methodatlas-docs:generatePdf | |
| - name: Rename PDF to versioned filename | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#release@}" | |
| cp methodatlas-docs/build/MethodAtlas.pdf \ | |
| methodatlas-docs/build/MethodAtlas-${VERSION}.pdf | |
| # ----------------------------------------------------------------------- | |
| # Changelog via git-cliff (reads cliff.toml at repo root) | |
| # ----------------------------------------------------------------------- | |
| - name: Install git-cliff | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: git-cliff | |
| - name: Generate changelog | |
| run: | | |
| git-cliff --tag "$GITHUB_REF_NAME" \ | |
| --output /tmp/CHANGELOG_RELEASE.md | |
| # ----------------------------------------------------------------------- | |
| # Publish release | |
| # The tag name is release@x.y.z; strip the prefix to get the plain version. | |
| # ----------------------------------------------------------------------- | |
| - name: Publish GitHub Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#release@}" | |
| gh release create "$GITHUB_REF_NAME" \ | |
| --title "MethodAtlas ${VERSION}" \ | |
| --notes-file /tmp/CHANGELOG_RELEASE.md \ | |
| build/distributions/*.zip \ | |
| build/distributions/*.tar \ | |
| build/reports/cyclonedx-direct/bom.json \ | |
| methodatlas-docs/build/MethodAtlas-${VERSION}.pdf |