Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
198 changes: 128 additions & 70 deletions .github/workflows/book-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ permissions:
contents: write

env:
PANDOC_VERSION: "3.1.11"
PANDOC_VERSION: "3.6.1"

jobs:
# ═══════════════════════════════════════════════════
Expand All @@ -34,44 +34,35 @@ jobs:
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 docs/book/book.md ]; then
if [ ! -f book.md ]; then
echo "has_book=false" >> $GITHUB_OUTPUT
echo "lines=0" >> $GITHUB_OUTPUT
echo "WARNING: docs/book/book.md not found — skipping PDF build"
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 < docs/book/book.md)
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 "Book source: $LINES lines"

- name: Strip control characters
if: steps.check.outputs.has_book == 'true'
run: |
sed -i 's/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]//g' docs/book/book.md
echo "Control characters cleaned"

- name: Validate structure
if: steps.check.outputs.has_book == 'true'
run: |
CHAPTERS=$(grep -c "^## " docs/book/book.md || echo 0)
echo "Chapters: $CHAPTERS"
if grep -qi "Srikanth Patchava" docs/book/book.md; then
echo "Author: verified"
fi
TABLES=$(grep -c "^|" docs/book/book.md || echo 0)
CODE_BLOCKS=$(grep -c '```' docs/book/book.md || echo 0)
echo "Tables: $TABLES lines"
echo "Code blocks: $((CODE_BLOCKS / 2))"
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
# 2. BUILD PDF WITH FULL FIGURE/TABLE/IMAGE SUPPORT
# ═══════════════════════════════════════════════════
build-pdf:
name: Build PDF
Expand All @@ -81,34 +72,55 @@ jobs:
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 & LaTeX
- 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 pandoc texlive-xetex texlive-fonts-recommended texlive-fonts-extra texlive-science texlive-latex-extra
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
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' docs/book/book.md
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
TITLE=$(head -5 docs/book/book.md | grep "^# " | head -1 | sed 's/^# //')
# 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 from tag or commit SHA
# Version
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
else
Expand All @@ -119,23 +131,29 @@ jobs:

- name: Generate PDF
run: |
# Use cover image if available
cd docs/book
cd docs/book

# Cover image
COVER_ARGS=""
if [ -f docs/book/cover.png ]; then
COVER_ARGS="-V titlepage-background=docs/book/cover.png"
if [ -f cover.png ]; then
COVER_ARGS="-V titlepage-background=cover.png"
fi
# Use references if available

# Bibliography / citations
CITE_ARGS=""
if [ -f docs/book/references.bib ]; then
CITE_ARGS="--citeproc --bibliography=docs/book/references.bib"
if [ -f references.bib ]; then
CITE_ARGS="--citeproc --bibliography=references.bib"
fi

pandoc \
docs/book/book.md \
-o "docs/book/${{ steps.meta.outputs.pdf_name }}" \
book.md \
-o "${{ steps.meta.outputs.pdf_name }}" \
--pdf-engine=xelatex \
--from=markdown+smart \
--from=markdown+smart+implicit_figures \
--template=eisvogel \
--listings \
--resource-path=. \
$COVER_ARGS \
$CITE_ARGS \
-V titlepage=true \
Expand All @@ -146,19 +164,41 @@ jobs:
-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 "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=blue \
-V urlcolor=blue \
-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 "header-includes=\\usepackage{fancyhdr}\\pagestyle{fancy}\\fancyhead[R]{\\small ${{ steps.meta.outputs.version }}}" \
-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

Expand All @@ -172,10 +212,12 @@ jobs:
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: $PDF ($SIZE, $BYTES bytes)"
echo "pdf_pages=$PAGES" >> $GITHUB_OUTPUT
echo "PDF: $PDF ($SIZE, $PAGES pages, $BYTES bytes)"
if [ "$BYTES" -lt 1000 ]; then
echo "ERROR: PDF too small — likely corrupted"
echo "ERROR: PDF too small"
exit 1
fi

Expand All @@ -187,7 +229,7 @@ jobs:
retention-days: 90

# ═══════════════════════════════════════════════════
# 3. ATTACH TO RELEASE (any release or tag)
# 3. ATTACH TO RELEASE
# ═══════════════════════════════════════════════════
attach-to-release:
name: Attach PDF to Release
Expand Down Expand Up @@ -221,14 +263,17 @@ jobs:

- name: Summary
run: |
echo "## Book PDF Attached to Release"
echo ""
echo "- **Tag:** ${{ steps.tag.outputs.tag }}"
echo "- **PDF:** ${{ needs.build-pdf.outputs.pdf_name }} (${{ needs.build-pdf.outputs.pdf_size }})"
echo "- **Source:** ${{ needs.validate.outputs.lines }} lines"
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. NIGHTLY DEV BUILD (latest from master)
# 4. DEV BUILD (latest from master)
# ═══════════════════════════════════════════════════
dev-release:
name: Update Dev PDF
Expand All @@ -246,19 +291,31 @@ jobs:
uses: softprops/action-gh-release@v2
with:
tag_name: dev-latest
name: "Development Build (Latest)"
name: "📖 Development Build (Latest)"
prerelease: true
files: ./pdf-output/${{ needs.build-pdf.outputs.pdf_name }}
body: |
## Development Book PDF — Latest from `master`
## 📘 Development Book PDF — Latest from `master`

Auto-generated from `docs/book/` on every push to master.

Auto-generated from the latest `docs/book/book.md` on every push.
| 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 }} |

- **Commit:** ${{ github.sha }}
- **Date:** ${{ github.event.head_commit.timestamp }}
- **PDF:** ${{ needs.build-pdf.outputs.pdf_name }} (${{ needs.build-pdf.outputs.pdf_size }})
### 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.
> ⚠️ This is a development build. For stable releases, see the latest tagged release.
make_latest: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -274,13 +331,14 @@ jobs:
steps:
- name: Report
run: |
echo "## Book Build Report — ${GITHUB_REPOSITORY}"
echo ""
echo "| Step | Status |"
echo "|------|--------|"
echo "| Source validation | ${{ needs.validate.result }} |"
echo "| PDF generation | ${{ needs.build-pdf.result }} |"
echo ""
echo "- Source: ${{ needs.validate.outputs.lines }} lines"
echo "- Trigger: ${{ github.event_name }}"
echo "- Ref: ${{ github.ref }}"
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
45 changes: 17 additions & 28 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@
name: Release
# Thin caller for embeddedos-org/ebuild reusable orchestrator.

on:
push:
tags: ['v*']
branches: [master, main]

permissions:
contents: write
packages: write
id-token: write
attestations: write

jobs:
test:
name: Validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -e ".[dev]" 2>/dev/null || pip install -r requirements.txt 2>/dev/null || pip install pytest
- run: python -m pytest tests/ -v --tb=short || true
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false

jobs:
release:
name: Create Release
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version
id: version
run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.tag }}
name: "EoStudio ${{ steps.version.outputs.tag }}"
generate_release_notes: true
uses: embeddedos-org/ebuild/.github/workflows/_reusable-orchestrator.yml@v1
with:
project_type: python
platforms: linux-x64,linux-arm64,windows-x64,macos-x64,macos-arm64
build_book: true
build_video: true
build_docker: false
secrets: inherit
Loading