Skip to content

feat: switch TTS to edge-tts en-US-GuyNeural (neutral US accent) #19

feat: switch TTS to edge-tts en-US-GuyNeural (neutral US accent)

feat: switch TTS to edge-tts en-US-GuyNeural (neutral US accent) #19

Workflow file for this run

name: Build & Release Book PDF
on:
push:
branches: [master, main]
paths:
- 'docs/book/**'
tags:
- 'v*'
pull_request:
paths:
- 'docs/book/**'
release:
types: [published, created]
workflow_dispatch:
concurrency:
group: book-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: write
env:
PANDOC_VERSION: "3.6.1"
jobs:
# ═══════════════════════════════════════════════════
# 1. VALIDATE BOOK SOURCE
# ═══════════════════════════════════════════════════
validate:
name: Validate Book Source
runs-on: ubuntu-latest
outputs:
lines: ${{ steps.check.outputs.lines }}
has_book: ${{ steps.check.outputs.has_book }}
images: ${{ steps.check.outputs.images }}
tables: ${{ steps.check.outputs.tables }}
steps:
- uses: actions/checkout@v4
- name: Check book source
id: check
run: |
if [ ! -f book.md ]; then
echo "has_book=false" >> $GITHUB_OUTPUT
echo "lines=0" >> $GITHUB_OUTPUT
echo "images=0" >> $GITHUB_OUTPUT
echo "tables=0" >> $GITHUB_OUTPUT
echo "WARNING: book.md not found"
exit 0
fi
echo "has_book=true" >> $GITHUB_OUTPUT
LINES=$(wc -l < book.md)
IMAGES=$(grep -c '!\[' book.md || echo 0)
TABLES=$(grep -c '^|' book.md || echo 0)
CODE=$(grep -c '```' book.md || echo 0)
CHAPTERS=$(grep -c '^## ' book.md || echo 0)
echo "lines=$LINES" >> $GITHUB_OUTPUT
echo "images=$IMAGES" >> $GITHUB_OUTPUT
echo "tables=$TABLES" >> $GITHUB_OUTPUT
echo "Book: $LINES lines, $CHAPTERS chapters, $IMAGES images, $TABLES table rows, $((CODE/2)) code blocks"
# ═══════════════════════════════════════════════════
# 2. BUILD PDF WITH FULL FIGURE/TABLE/IMAGE SUPPORT
# ═══════════════════════════════════════════════════
build-pdf:
name: Build PDF
runs-on: ubuntu-latest
needs: validate
if: needs.validate.outputs.has_book == 'true'
outputs:
pdf_name: ${{ steps.meta.outputs.pdf_name }}
pdf_size: ${{ steps.verify.outputs.pdf_size }}
pdf_pages: ${{ steps.verify.outputs.pdf_pages }}
steps:
- uses: actions/checkout@v4
- name: Install pandoc 3.x & LaTeX
run: |
# Install latest pandoc for Eisvogel + citeproc support
wget -q https://github.com/jgm/pandoc/releases/download/${{ env.PANDOC_VERSION }}/pandoc-${{ env.PANDOC_VERSION }}-1-amd64.deb
sudo dpkg -i pandoc-${{ env.PANDOC_VERSION }}-1-amd64.deb
# LaTeX with all needed packages for figures, tables, images
sudo apt-get update
sudo apt-get install -y \
texlive-xetex \
texlive-fonts-recommended \
texlive-fonts-extra \
texlive-latex-extra \
texlive-science \
texlive-latex-recommended \
librsvg2-bin \
poppler-utils
echo "pandoc $(pandoc --version | head -1)"
- name: Install Eisvogel template
run: |
mkdir -p ~/.local/share/pandoc/templates
wget -q https://github.com/Wandmalfarbe/pandoc-latex-template/releases/download/v2.4.0/Eisvogel-2.4.0.tar.gz
tar xzf Eisvogel-2.4.0.tar.gz 2>/dev/null || true
cp eisvogel.latex ~/.local/share/pandoc/templates/eisvogel.latex
echo "Eisvogel template installed"
- name: Clean source
run: |
sed -i 's/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]//g' book.md
echo "Control characters cleaned"
- name: Extract metadata
id: meta
run: |
REPO_NAME="${GITHUB_REPOSITORY#*/}"
echo "repo_name=$REPO_NAME" >> $GITHUB_OUTPUT
echo "pdf_name=${REPO_NAME}-guide.pdf" >> $GITHUB_OUTPUT
# Extract title from frontmatter or first heading
TITLE=$(grep -m1 '^title:' book.md | sed 's/^title: *"*//;s/"*$//' || echo "")
if [ -z "$TITLE" ]; then
TITLE=$(head -10 book.md | grep "^# " | head -1 | sed 's/^# //')
fi
if [ -z "$TITLE" ]; then TITLE="$REPO_NAME — Official Guide"; fi
echo "title=$TITLE" >> $GITHUB_OUTPUT
# Version
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
else
VERSION="dev-$(echo $GITHUB_SHA | cut -c1-7)"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Building: $TITLE ($VERSION)"
- name: Generate PDF
run: |
cd docs/book
cd docs/book
# Cover image
COVER_ARGS=""
if [ -f cover.png ]; then
COVER_ARGS="-V titlepage-background=cover.png"
fi
# Bibliography / citations
CITE_ARGS=""
if [ -f references.bib ]; then
CITE_ARGS="--citeproc --bibliography=references.bib"
fi
pandoc \
book.md \
-o "${{ steps.meta.outputs.pdf_name }}" \
--pdf-engine=xelatex \
--from=markdown+smart+implicit_figures \
--template=eisvogel \
--listings \
--resource-path=. \
$COVER_ARGS \
$CITE_ARGS \
-V titlepage=true \
-V titlepage-color="1a1a2e" \
-V titlepage-text-color="ffffff" \
-V titlepage-rule-color="58a6ff" \
-V titlepage-rule-height=2 \
-V page-background-color="ffffff" \
-V "title=${{ steps.meta.outputs.title }}" \
-V "subtitle=Version ${{ steps.meta.outputs.version }}" \
-V "author=Srikanth Patchava & EmbeddedOS Contributors" \
-V "date=$(date +'%B %Y')" \
-V toc=true \
-V toc-depth=3 \
-V toc-own-page=true \
-V colorlinks=true \
-V linkcolor="[HTML]{1a73e8}" \
-V urlcolor="[HTML]{1a73e8}" \
-V citecolor="[HTML]{6e40aa}" \
-V book=true \
-V classoption=oneside \
-V fontsize=11pt \
-V geometry:margin=1in \
-V float-placement-figure=H \
-V caption-justification=centering \
-V table-use-row-colors=true \
-V "header-includes=\
\usepackage{float}\
\usepackage{booktabs}\
\usepackage{longtable}\
\usepackage{caption}\
\captionsetup{font=small,labelfont=bf,format=hang}\
\captionsetup[figure]{name=Figure}\
\captionsetup[table]{name=Table}\
\usepackage{fancyhdr}\
\pagestyle{fancy}\
\fancyhead[L]{\small\leftmark}\
\fancyhead[R]{\small ${{ steps.meta.outputs.version }}}\
\fancyfoot[C]{\small EmbeddedOS Press — embeddedos-org.github.io}\
\fancyfoot[R]{\thepage}\
\renewcommand{\headrulewidth}{0.4pt}\
\renewcommand{\footrulewidth}{0.2pt}\
\usepackage{graphicx}\
\makeatletter\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}\makeatother\
\setkeys{Gin}{width=\maxwidth,keepaspectratio}" \
--highlight-style=tango \
--number-sections
- name: Verify PDF
id: verify
run: |
PDF="docs/book/${{ steps.meta.outputs.pdf_name }}"
if [ ! -f "$PDF" ]; then
echo "ERROR: PDF not generated"
exit 1
fi
SIZE=$(du -h "$PDF" | cut -f1)
BYTES=$(wc -c < "$PDF")
PAGES=$(pdfinfo "$PDF" 2>/dev/null | grep Pages | awk '{print $2}' || echo "?")
echo "pdf_size=$SIZE" >> $GITHUB_OUTPUT
echo "pdf_pages=$PAGES" >> $GITHUB_OUTPUT
echo "PDF: $PDF ($SIZE, $PAGES pages, $BYTES bytes)"
if [ "$BYTES" -lt 1000 ]; then
echo "ERROR: PDF too small"
exit 1
fi
- name: Upload PDF artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.meta.outputs.pdf_name }}
path: docs/book/${{ steps.meta.outputs.pdf_name }}
retention-days: 90
# ═══════════════════════════════════════════════════
# 3. ATTACH TO RELEASE
# ═══════════════════════════════════════════════════
attach-to-release:
name: Attach PDF to Release
runs-on: ubuntu-latest
needs: build-pdf
if: github.event_name == 'release' || startsWith(github.ref, 'refs/tags/')
steps:
- name: Download PDF artifact
uses: actions/download-artifact@v4
with:
name: ${{ needs.build-pdf.outputs.pdf_name }}
path: ./pdf-output
- name: Determine release tag
id: tag
run: |
if [ "${{ github.event_name }}" = "release" ]; then
echo "tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
else
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi
- name: Create or update release with PDF
uses: softprops/action-gh-release@v2
with:
files: ./pdf-output/${{ needs.build-pdf.outputs.pdf_name }}
tag_name: ${{ steps.tag.outputs.tag }}
fail_on_unmatched_files: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Summary
run: |
echo "## 📘 Book PDF Attached to Release" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Detail | Value |" >> $GITHUB_STEP_SUMMARY
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Tag | ${{ steps.tag.outputs.tag }} |" >> $GITHUB_STEP_SUMMARY
echo "| PDF | ${{ needs.build-pdf.outputs.pdf_name }} |" >> $GITHUB_STEP_SUMMARY
echo "| Size | ${{ needs.build-pdf.outputs.pdf_size }} |" >> $GITHUB_STEP_SUMMARY
echo "| Pages | ${{ needs.build-pdf.outputs.pdf_pages }} |" >> $GITHUB_STEP_SUMMARY
# ═══════════════════════════════════════════════════
# 4. DEV BUILD (latest from master)
# ═══════════════════════════════════════════════════
dev-release:
name: Update Dev PDF
runs-on: ubuntu-latest
needs: build-pdf
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main')
steps:
- name: Download PDF artifact
uses: actions/download-artifact@v4
with:
name: ${{ needs.build-pdf.outputs.pdf_name }}
path: ./pdf-output
- name: Update dev release
uses: softprops/action-gh-release@v2
with:
tag_name: dev-latest
name: "📖 Development Build (Latest)"
prerelease: true
files: ./pdf-output/${{ needs.build-pdf.outputs.pdf_name }}
body: |
## 📘 Development Book PDF — Latest from `master`
Auto-generated from `docs/book/` on every push to master.
| Detail | Value |
|--------|-------|
| **Commit** | `${{ github.sha }}` |
| **Date** | ${{ github.event.head_commit.timestamp }} |
| **PDF** | ${{ needs.build-pdf.outputs.pdf_name }} |
| **Size** | ${{ needs.build-pdf.outputs.pdf_size }} |
| **Pages** | ${{ needs.build-pdf.outputs.pdf_pages }} |
### Features
- Professional cover page with product branding
- Colorful architecture diagrams and technical illustrations
- Syntax-highlighted code blocks
- Academic references (IEEE format)
- Table of contents with numbered sections
- Professional headers/footers with EmbeddedOS Press branding
> ⚠️ This is a development build. For stable releases, see the latest tagged release.
make_latest: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ═══════════════════════════════════════════════════
# SUMMARY
# ═══════════════════════════════════════════════════
summary:
name: Build Summary
runs-on: ubuntu-latest
needs: [validate, build-pdf]
if: always()
steps:
- name: Report
run: |
echo "## 📘 Book Build Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Step | Status |" >> $GITHUB_STEP_SUMMARY
echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Validation | ${{ needs.validate.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| PDF Build | ${{ needs.build-pdf.result }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Lines:** ${{ needs.validate.outputs.lines }}" >> $GITHUB_STEP_SUMMARY
echo "- **Images:** ${{ needs.validate.outputs.images }}" >> $GITHUB_STEP_SUMMARY
echo "- **Tables:** ${{ needs.validate.outputs.tables }}" >> $GITHUB_STEP_SUMMARY
echo "- **Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY