feat: switch TTS to edge-tts en-US-GuyNeural (neutral US accent) #19
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
| 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 |