Update book workflows for volume-only builds

Switch container/baremetal/validate/preview/live flows to vol1+vol2 artifacts, keep baremetal in dev validation, and add stable single-book navbar link.
This commit is contained in:
Vijay Janapa Reddi
2026-03-02 09:45:40 -05:00
parent a7f9367e42
commit 1052b2be31
7 changed files with 305 additions and 474 deletions

View File

@@ -36,6 +36,14 @@ on:
default: true
type: boolean
# Build configuration
build_target:
description: '📦 Build target (vol1, vol2)'
required: false
type: choice
default: 'vol1'
options:
- vol1
- vol2
target:
description: 'Target branch (dev/main)'
required: false
@@ -98,6 +106,11 @@ on:
default: false
description: 'Build EPUB format'
# Build configuration
build_target:
required: false
type: string
default: 'vol1'
description: 'Build target (vol1/vol2)'
target:
required: false
type: string
@@ -124,24 +137,42 @@ on:
build_success:
description: "Whether all builds completed successfully"
value: ${{ jobs.collect-outputs.outputs.build_success }}
linux_html_artifact:
description: "Linux HTML artifact name"
value: ${{ jobs.collect-outputs.outputs.linux_html_artifact }}
linux_pdf_artifact:
description: "Linux PDF artifact name"
value: ${{ jobs.collect-outputs.outputs.linux_pdf_artifact }}
windows_html_artifact:
description: "Windows HTML artifact name"
value: ${{ jobs.collect-outputs.outputs.windows_html_artifact }}
windows_pdf_artifact:
description: "Windows PDF artifact name"
value: ${{ jobs.collect-outputs.outputs.windows_pdf_artifact }}
linux_epub_artifact:
description: "Linux EPUB artifact name"
value: ${{ jobs.collect-outputs.outputs.linux_epub_artifact }}
windows_epub_artifact:
description: "Windows EPUB artifact name"
value: ${{ jobs.collect-outputs.outputs.windows_epub_artifact }}
linux_html_vol1_artifact:
description: "Linux HTML artifact name (Volume I)"
value: ${{ jobs.collect-outputs.outputs.linux_html_vol1_artifact }}
linux_pdf_vol1_artifact:
description: "Linux PDF artifact name (Volume I)"
value: ${{ jobs.collect-outputs.outputs.linux_pdf_vol1_artifact }}
linux_epub_vol1_artifact:
description: "Linux EPUB artifact name (Volume I)"
value: ${{ jobs.collect-outputs.outputs.linux_epub_vol1_artifact }}
windows_html_vol1_artifact:
description: "Windows HTML artifact name (Volume I)"
value: ${{ jobs.collect-outputs.outputs.windows_html_vol1_artifact }}
windows_pdf_vol1_artifact:
description: "Windows PDF artifact name (Volume I)"
value: ${{ jobs.collect-outputs.outputs.windows_pdf_vol1_artifact }}
windows_epub_vol1_artifact:
description: "Windows EPUB artifact name (Volume I)"
value: ${{ jobs.collect-outputs.outputs.windows_epub_vol1_artifact }}
linux_html_vol2_artifact:
description: "Linux HTML artifact name (Volume II)"
value: ${{ jobs.collect-outputs.outputs.linux_html_vol2_artifact }}
linux_pdf_vol2_artifact:
description: "Linux PDF artifact name (Volume II)"
value: ${{ jobs.collect-outputs.outputs.linux_pdf_vol2_artifact }}
linux_epub_vol2_artifact:
description: "Linux EPUB artifact name (Volume II)"
value: ${{ jobs.collect-outputs.outputs.linux_epub_vol2_artifact }}
windows_html_vol2_artifact:
description: "Windows HTML artifact name (Volume II)"
value: ${{ jobs.collect-outputs.outputs.windows_html_vol2_artifact }}
windows_pdf_vol2_artifact:
description: "Windows PDF artifact name (Volume II)"
value: ${{ jobs.collect-outputs.outputs.windows_pdf_vol2_artifact }}
windows_epub_vol2_artifact:
description: "Windows EPUB artifact name (Volume II)"
value: ${{ jobs.collect-outputs.outputs.windows_epub_vol2_artifact }}
permissions:
contents: write
@@ -162,56 +193,129 @@ jobs:
fail-fast: false
matrix:
include:
# Linux builds
# Linux Volume I builds
- os: ubuntu-latest
os_name: Linux
os_emoji: '🐧'
format: HTML
format_emoji: '📄'
config: _quarto-html.yml
volume: vol1
config: _quarto-html-vol1.yml
render_target: html
output_dir: _build/html-vol1
enabled: ${{ inputs.build_linux && inputs.build_html }}
- os: ubuntu-latest
os_name: Linux
os_emoji: '🐧'
format: PDF
format_emoji: '📑'
config: _quarto-pdf.yml
volume: vol1
config: _quarto-pdf-vol1.yml
render_target: titlepage-pdf
output_dir: _build/pdf-vol1
enabled: ${{ inputs.build_linux && inputs.build_pdf }}
# Windows builds
- os: ubuntu-latest
os_name: Linux
os_emoji: '🐧'
format: EPUB
format_emoji: '📚'
volume: vol1
config: _quarto-epub-vol1.yml
render_target: epub
output_dir: _build/epub-vol1
enabled: ${{ inputs.build_linux && inputs.build_epub }}
# Linux Volume II builds
- os: ubuntu-latest
os_name: Linux
os_emoji: '🐧'
format: HTML
format_emoji: '📄'
volume: vol2
config: _quarto-html-vol2.yml
render_target: html
output_dir: _build/html-vol2
enabled: ${{ inputs.build_linux && inputs.build_html }}
- os: ubuntu-latest
os_name: Linux
os_emoji: '🐧'
format: PDF
format_emoji: '📑'
volume: vol2
config: _quarto-pdf-vol2.yml
render_target: titlepage-pdf
output_dir: _build/pdf-vol2
enabled: ${{ inputs.build_linux && inputs.build_pdf }}
- os: ubuntu-latest
os_name: Linux
os_emoji: '🐧'
format: EPUB
format_emoji: '📚'
volume: vol2
config: _quarto-epub-vol2.yml
render_target: epub
output_dir: _build/epub-vol2
enabled: ${{ inputs.build_linux && inputs.build_epub }}
# Windows Volume I builds
- os: windows-latest
os_name: Windows
os_emoji: '🪟'
format: HTML
format_emoji: '📄'
config: _quarto-html.yml
volume: vol1
config: _quarto-html-vol1.yml
render_target: html
output_dir: _build/html-vol1
enabled: ${{ inputs.build_windows && inputs.build_html }}
- os: windows-latest
os_name: Windows
os_emoji: '🪟'
format: PDF
format_emoji: '📑'
config: _quarto-pdf.yml
volume: vol1
config: _quarto-pdf-vol1.yml
render_target: titlepage-pdf
output_dir: _build/pdf-vol1
enabled: ${{ inputs.build_windows && inputs.build_pdf }}
# EPUB builds
- os: ubuntu-latest
os_name: Linux
os_emoji: '🐧'
format: EPUB
format_emoji: '📚'
config: _quarto-epub.yml
render_target: epub
enabled: ${{ inputs.build_linux && inputs.build_epub }}
- os: windows-latest
os_name: Windows
os_emoji: '🪟'
format: EPUB
format_emoji: '📚'
config: _quarto-epub.yml
volume: vol1
config: _quarto-epub-vol1.yml
render_target: epub
output_dir: _build/epub-vol1
enabled: ${{ inputs.build_windows && inputs.build_epub }}
# Windows Volume II builds
- os: windows-latest
os_name: Windows
os_emoji: '🪟'
format: HTML
format_emoji: '📄'
volume: vol2
config: _quarto-html-vol2.yml
render_target: html
output_dir: _build/html-vol2
enabled: ${{ inputs.build_windows && inputs.build_html }}
- os: windows-latest
os_name: Windows
os_emoji: '🪟'
format: PDF
format_emoji: '📑'
volume: vol2
config: _quarto-pdf-vol2.yml
render_target: titlepage-pdf
output_dir: _build/pdf-vol2
enabled: ${{ inputs.build_windows && inputs.build_pdf }}
- os: windows-latest
os_name: Windows
os_emoji: '🪟'
format: EPUB
format_emoji: '📚'
volume: vol2
config: _quarto-epub-vol2.yml
render_target: epub
output_dir: _build/epub-vol2
enabled: ${{ inputs.build_windows && inputs.build_epub }}
timeout-minutes: 120 # ⏰ Set job timeout to 2 hours (7200 seconds)
@@ -975,17 +1079,7 @@ jobs:
id: build
shell: bash
run: |
OUTPUT_DIR=""
if [ "${{ matrix.format }}" = "HTML" ]; then
OUTPUT_DIR="_build/html"
elif [ "${{ matrix.format }}" = "PDF" ]; then
OUTPUT_DIR="_build/pdf"
elif [ "${{ matrix.format }}" = "EPUB" ]; then
OUTPUT_DIR="_build/epub"
else
echo "❌ Unknown format '${{ matrix.format }}'. Cannot determine default output directory."
exit 1
fi
OUTPUT_DIR="${{ matrix.output_dir }}"
echo "output_dir=${OUTPUT_DIR}" >> "$GITHUB_OUTPUT"
echo "🚀 Setting up ${{ matrix.format }} configuration..."
@@ -1160,9 +1254,14 @@ jobs:
if: matrix.enabled
id: build-declaration
shell: bash
env:
ARTIFACT_NAME_RAW: ${{ inputs.artifact_name != '' && format('{0}-{1}-{2}', inputs.artifact_name, matrix.os_name, matrix.format) || format('build-{0}-{1}-{2}', inputs.target, matrix.os_name, matrix.format) }}
run: |
if [ -n "${{ inputs.artifact_name }}" ]; then
ARTIFACT_NAME_RAW="${{ inputs.artifact_name }}-${{ matrix.os_name }}-${{ matrix.format }}-${{ matrix.volume }}"
else
FORMAT_LC=$(echo "${{ matrix.format }}" | tr '[:upper:]' '[:lower:]')
OS_LC=$(echo "${{ matrix.os_name }}" | tr '[:upper:]' '[:lower:]')
ARTIFACT_NAME_RAW="${{ inputs.target }}-${FORMAT_LC}-${{ matrix.volume }}-${OS_LC}"
fi
echo "📦 Build Declaration: Successfully created artifact '$ARTIFACT_NAME_RAW'"
echo "artifact_name=$ARTIFACT_NAME_RAW" >> $GITHUB_OUTPUT
@@ -1329,12 +1428,18 @@ jobs:
if: always()
outputs:
build_success: ${{ steps.collect.outputs.build_success }}
linux_html_artifact: ${{ steps.collect.outputs.linux_html_artifact }}
linux_pdf_artifact: ${{ steps.collect.outputs.linux_pdf_artifact }}
linux_epub_artifact: ${{ steps.collect.outputs.linux_epub_artifact }}
windows_html_artifact: ${{ steps.collect.outputs.windows_html_artifact }}
windows_pdf_artifact: ${{ steps.collect.outputs.windows_pdf_artifact }}
windows_epub_artifact: ${{ steps.collect.outputs.windows_epub_artifact }}
linux_html_vol1_artifact: ${{ steps.collect.outputs.linux_html_vol1_artifact }}
linux_pdf_vol1_artifact: ${{ steps.collect.outputs.linux_pdf_vol1_artifact }}
linux_epub_vol1_artifact: ${{ steps.collect.outputs.linux_epub_vol1_artifact }}
windows_html_vol1_artifact: ${{ steps.collect.outputs.windows_html_vol1_artifact }}
windows_pdf_vol1_artifact: ${{ steps.collect.outputs.windows_pdf_vol1_artifact }}
windows_epub_vol1_artifact: ${{ steps.collect.outputs.windows_epub_vol1_artifact }}
linux_html_vol2_artifact: ${{ steps.collect.outputs.linux_html_vol2_artifact }}
linux_pdf_vol2_artifact: ${{ steps.collect.outputs.linux_pdf_vol2_artifact }}
linux_epub_vol2_artifact: ${{ steps.collect.outputs.linux_epub_vol2_artifact }}
windows_html_vol2_artifact: ${{ steps.collect.outputs.windows_html_vol2_artifact }}
windows_pdf_vol2_artifact: ${{ steps.collect.outputs.windows_pdf_vol2_artifact }}
windows_epub_vol2_artifact: ${{ steps.collect.outputs.windows_epub_vol2_artifact }}
steps:
- name: 📊 Collect results
@@ -1349,43 +1454,30 @@ jobs:
BUILD_SUCCESS_MSG="❌ Failure"
fi
# Extract artifact names from build job outputs using jq
outputs_json='${{ toJSON(needs.build.outputs) }}'
# Helper function to extract artifact name
extract_artifact() {
local os_name=$1
local format=$2
# Robustly handle either a single output object or an object of output objects.
# Also, convert matrix os_name and format to lowercase for case-insensitive matching.
echo "$outputs_json" | jq -r --arg o "$os_name" --arg f "$format" \
'(if .os_name then . else .[] end) | select((.os_name | ascii_downcase) == $o and (.format | ascii_downcase) == $f and .status=="success") | .artifact_name'
}
# Set artifact names for requested builds if they were generated
TARGET="${{ inputs.target }}"
if [[ "${{ inputs.build_linux && inputs.build_html }}" == "true" ]]; then
artifact_name=$(extract_artifact "linux" "html")
echo "linux_html_artifact=$artifact_name" >> $GITHUB_OUTPUT
echo "linux_html_vol1_artifact=${TARGET}-html-vol1-linux" >> $GITHUB_OUTPUT
echo "linux_html_vol2_artifact=${TARGET}-html-vol2-linux" >> $GITHUB_OUTPUT
fi
if [[ "${{ inputs.build_linux && inputs.build_pdf }}" == "true" ]]; then
artifact_name=$(extract_artifact "linux" "pdf")
echo "linux_pdf_artifact=$artifact_name" >> $GITHUB_OUTPUT
fi
if [[ "${{ inputs.build_windows && inputs.build_html }}" == "true" ]]; then
artifact_name=$(extract_artifact "windows" "html")
echo "windows_html_artifact=$artifact_name" >> $GITHUB_OUTPUT
fi
if [[ "${{ inputs.build_windows && inputs.build_pdf }}" == "true" ]]; then
artifact_name=$(extract_artifact "windows" "pdf")
echo "windows_pdf_artifact=$artifact_name" >> $GITHUB_OUTPUT
echo "linux_pdf_vol1_artifact=${TARGET}-pdf-vol1-linux" >> $GITHUB_OUTPUT
echo "linux_pdf_vol2_artifact=${TARGET}-pdf-vol2-linux" >> $GITHUB_OUTPUT
fi
if [[ "${{ inputs.build_linux && inputs.build_epub }}" == "true" ]]; then
artifact_name=$(extract_artifact "linux" "epub")
echo "linux_epub_artifact=$artifact_name" >> $GITHUB_OUTPUT
echo "linux_epub_vol1_artifact=${TARGET}-epub-vol1-linux" >> $GITHUB_OUTPUT
echo "linux_epub_vol2_artifact=${TARGET}-epub-vol2-linux" >> $GITHUB_OUTPUT
fi
if [[ "${{ inputs.build_windows && inputs.build_html }}" == "true" ]]; then
echo "windows_html_vol1_artifact=${TARGET}-html-vol1-windows" >> $GITHUB_OUTPUT
echo "windows_html_vol2_artifact=${TARGET}-html-vol2-windows" >> $GITHUB_OUTPUT
fi
if [[ "${{ inputs.build_windows && inputs.build_pdf }}" == "true" ]]; then
echo "windows_pdf_vol1_artifact=${TARGET}-pdf-vol1-windows" >> $GITHUB_OUTPUT
echo "windows_pdf_vol2_artifact=${TARGET}-pdf-vol2-windows" >> $GITHUB_OUTPUT
fi
if [[ "${{ inputs.build_windows && inputs.build_epub }}" == "true" ]]; then
artifact_name=$(extract_artifact "windows" "epub")
echo "windows_epub_artifact=$artifact_name" >> $GITHUB_OUTPUT
echo "windows_epub_vol1_artifact=${TARGET}-epub-vol1-windows" >> $GITHUB_OUTPUT
echo "windows_epub_vol2_artifact=${TARGET}-epub-vol2-windows" >> $GITHUB_OUTPUT
fi
echo "✅ Results collected - Status: $BUILD_SUCCESS_MSG"

View File

@@ -33,12 +33,11 @@ on:
default: true
type: boolean
build_target:
description: '📦 Build target (combined=full book, vol1, vol2, all)'
description: '📦 Build target (vol1, vol2, all)'
required: false
type: choice
default: 'combined'
default: 'all'
options:
- combined
- vol1
- vol2
- all
@@ -85,7 +84,7 @@ on:
build_target:
required: false
type: string
default: 'combined'
default: 'all'
target:
required: false
type: string
@@ -103,27 +102,8 @@ on:
description: "Whether all builds completed successfully"
value: ${{ jobs.collect-outputs.outputs.build_success }}
build_target:
description: "Build target used (combined/vol1/vol2/all)"
description: "Build target used (vol1/vol2/all)"
value: ${{ jobs.collect-outputs.outputs.build_target }}
# Combined (full book) artifacts
linux_html_artifact:
description: "Linux HTML artifact name (combined)"
value: ${{ jobs.collect-outputs.outputs.linux_html_artifact }}
linux_pdf_artifact:
description: "Linux PDF artifact name (combined)"
value: ${{ jobs.collect-outputs.outputs.linux_pdf_artifact }}
linux_epub_artifact:
description: "Linux EPUB artifact name (combined)"
value: ${{ jobs.collect-outputs.outputs.linux_epub_artifact }}
windows_html_artifact:
description: "Windows HTML artifact name (combined)"
value: ${{ jobs.collect-outputs.outputs.windows_html_artifact }}
windows_pdf_artifact:
description: "Windows PDF artifact name (combined)"
value: ${{ jobs.collect-outputs.outputs.windows_pdf_artifact }}
windows_epub_artifact:
description: "Windows EPUB artifact name (combined)"
value: ${{ jobs.collect-outputs.outputs.windows_epub_artifact }}
# Volume I artifacts
linux_html_vol1_artifact:
description: "Linux HTML artifact name (Volume I)"
@@ -167,83 +147,6 @@ jobs:
matrix:
include:
# =================================================================
# Combined (full book) builds
# =================================================================
# Linux builds
- platform: linux
platform_name: Linux
platform_emoji: '🐧'
runner: ubuntu-latest
format_name: HTML
format_emoji: '📄'
volume: combined
config: _quarto-html.yml
render_target: html
enabled: ${{ inputs.build_linux && inputs.build_html && (inputs.build_target == 'combined' || inputs.build_target == 'all') }}
artifact_name: ${{ inputs.target }}-html-linux
output_dir: _build/html
- platform: linux
platform_name: Linux
platform_emoji: '🐧'
runner: ubuntu-latest
format_name: PDF
format_emoji: '📑'
volume: combined
config: _quarto-pdf.yml
render_target: titlepage-pdf
enabled: ${{ inputs.build_linux && inputs.build_pdf && (inputs.build_target == 'combined' || inputs.build_target == 'all') }}
artifact_name: ${{ inputs.target }}-pdf-linux
output_dir: _build/pdf
# Windows builds
- platform: windows
platform_name: Windows
platform_emoji: '🪟'
runner: windows-latest
format_name: HTML
format_emoji: '📄'
volume: combined
config: _quarto-html.yml
render_target: html
enabled: ${{ inputs.build_windows && inputs.build_html && (inputs.build_target == 'combined' || inputs.build_target == 'all') }}
artifact_name: ${{ inputs.target }}-html-windows
output_dir: _build/html
- platform: windows
platform_name: Windows
platform_emoji: '🪟'
runner: windows-latest
format_name: PDF
format_emoji: '📑'
volume: combined
config: _quarto-pdf.yml
render_target: titlepage-pdf
enabled: ${{ inputs.build_windows && inputs.build_pdf && (inputs.build_target == 'combined' || inputs.build_target == 'all') }}
artifact_name: ${{ inputs.target }}-pdf-windows
output_dir: _build/pdf
# EPUB builds
- platform: linux
platform_name: Linux
platform_emoji: '🐧'
runner: ubuntu-latest
format_name: EPUB
format_emoji: '📚'
volume: combined
config: _quarto-epub.yml
render_target: epub
enabled: ${{ inputs.build_linux && inputs.build_epub && (inputs.build_target == 'combined' || inputs.build_target == 'all') }}
artifact_name: ${{ inputs.target }}-epub-linux
output_dir: _build/epub
- platform: windows
platform_name: Windows
platform_emoji: '🪟'
runner: windows-latest
format_name: EPUB
format_emoji: '📚'
config: _quarto-epub.yml
render_target: epub
enabled: ${{ inputs.build_windows && inputs.build_epub && (inputs.build_target == 'combined' || inputs.build_target == 'all') }}
artifact_name: ${{ inputs.target }}-epub-windows
output_dir: _build/epub
# =================================================================
# Volume I builds (Linux only for now)
# =================================================================
- platform: linux
@@ -558,13 +461,6 @@ jobs:
outputs:
build_success: ${{ steps.collect.outputs.build_success }}
build_target: ${{ steps.collect.outputs.build_target }}
# Combined artifacts
linux_html_artifact: ${{ steps.collect.outputs.linux_html_artifact }}
linux_pdf_artifact: ${{ steps.collect.outputs.linux_pdf_artifact }}
linux_epub_artifact: ${{ steps.collect.outputs.linux_epub_artifact }}
windows_html_artifact: ${{ steps.collect.outputs.windows_html_artifact }}
windows_pdf_artifact: ${{ steps.collect.outputs.windows_pdf_artifact }}
windows_epub_artifact: ${{ steps.collect.outputs.windows_epub_artifact }}
# Volume I artifacts
linux_html_vol1_artifact: ${{ steps.collect.outputs.linux_html_vol1_artifact }}
linux_pdf_vol1_artifact: ${{ steps.collect.outputs.linux_pdf_vol1_artifact }}
@@ -593,47 +489,6 @@ jobs:
echo "🔌 Generating artifact names for target: $TARGET, build_target: $BUILD_TARGET"
echo "build_target=$BUILD_TARGET" >> $GITHUB_OUTPUT
# =================================================================
# Combined (full book) artifacts
# =================================================================
if [[ "$BUILD_TARGET" == "combined" || "$BUILD_TARGET" == "all" ]]; then
if [[ "${{ inputs.build_linux && inputs.build_html }}" == "true" ]]; then
ARTIFACT_NAME="${TARGET}-html-linux"
echo "linux_html_artifact=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
echo "📄 Linux HTML artifact (combined): $ARTIFACT_NAME"
fi
if [[ "${{ inputs.build_linux && inputs.build_pdf }}" == "true" ]]; then
ARTIFACT_NAME="${TARGET}-pdf-linux"
echo "linux_pdf_artifact=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
echo "📑 Linux PDF artifact (combined): $ARTIFACT_NAME"
fi
if [[ "${{ inputs.build_linux && inputs.build_epub }}" == "true" ]]; then
ARTIFACT_NAME="${TARGET}-epub-linux"
echo "linux_epub_artifact=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
echo "📚 Linux EPUB artifact (combined): $ARTIFACT_NAME"
fi
if [[ "${{ inputs.build_windows && inputs.build_html }}" == "true" ]]; then
ARTIFACT_NAME="${TARGET}-html-windows"
echo "windows_html_artifact=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
echo "📄 Windows HTML artifact (combined): $ARTIFACT_NAME"
fi
if [[ "${{ inputs.build_windows && inputs.build_pdf }}" == "true" ]]; then
ARTIFACT_NAME="${TARGET}-pdf-windows"
echo "windows_pdf_artifact=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
echo "📑 Windows PDF artifact (combined): $ARTIFACT_NAME"
fi
if [[ "${{ inputs.build_windows && inputs.build_epub }}" == "true" ]]; then
ARTIFACT_NAME="${TARGET}-epub-windows"
echo "windows_epub_artifact=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
echo "📚 Windows EPUB artifact (combined): $ARTIFACT_NAME"
fi
fi
# =================================================================
# Volume I artifacts
# =================================================================

View File

@@ -1,7 +1,6 @@
name: '📚 Book · 👁️ Preview (Dev)'
env:
ARTIFACT_NAME: dev-html-linux # The name of the artifact produced by the 'validate-dev' workflow
# ==========================================================================
# PATH CONFIGURATION - Uses GitHub Repository Variables (Settings > Variables)
# ==========================================================================
@@ -75,55 +74,79 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: 📥 Download HTML Artifact
- name: 📥 Download Vol1 HTML Artifact
uses: actions/download-artifact@v7
with:
name: ${{ env.ARTIFACT_NAME }}
name: dev-html-vol1-linux
run-id: ${{ steps.run_info.outputs.run_id }}
path: ./preview-site
path: ./html-vol1-artifact
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: 📥 Download PDF Artifact
- name: 📥 Download Vol2 HTML Artifact
uses: actions/download-artifact@v7
with:
name: dev-html-vol2-linux
run-id: ${{ steps.run_info.outputs.run_id }}
path: ./html-vol2-artifact
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: 📥 Download Vol1 PDF Artifact
uses: actions/download-artifact@v7
continue-on-error: true
with:
name: dev-pdf-linux
name: dev-pdf-vol1-linux
run-id: ${{ steps.run_info.outputs.run_id }}
path: ./pdf-artifact
path: ./pdf-vol1-artifact
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: 📥 Download EPUB Artifact
- name: 📥 Download Vol2 PDF Artifact
uses: actions/download-artifact@v7
continue-on-error: true
with:
name: dev-epub-linux
name: dev-pdf-vol2-linux
run-id: ${{ steps.run_info.outputs.run_id }}
path: ./epub-artifact
path: ./pdf-vol2-artifact
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: 📦 Combine artifacts with PDF and EPUB
- name: 📥 Download Vol1 EPUB Artifact
uses: actions/download-artifact@v7
continue-on-error: true
with:
name: dev-epub-vol1-linux
run-id: ${{ steps.run_info.outputs.run_id }}
path: ./epub-vol1-artifact
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: 📥 Download Vol2 EPUB Artifact
uses: actions/download-artifact@v7
continue-on-error: true
with:
name: dev-epub-vol2-linux
run-id: ${{ steps.run_info.outputs.run_id }}
path: ./epub-vol2-artifact
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: 📦 Build volume preview site
run: |
echo "📦 Preparing combined site with PDF and EPUB..."
echo "📦 Preparing volume preview site..."
mkdir -p ./preview-site/vol1 ./preview-site/vol2
# Create assets and downloads directories
mkdir -p ./preview-site/assets/downloads
cp -r ./html-vol1-artifact/* ./preview-site/vol1/
cp -r ./html-vol2-artifact/* ./preview-site/vol2/
# Copy PDF if available
if [ -f "./pdf-artifact/Machine-Learning-Systems.pdf" ]; then
cp "./pdf-artifact/Machine-Learning-Systems.pdf" "./preview-site/assets/downloads/Machine-Learning-Systems.pdf"
PDF_SIZE=$(du -h "./preview-site/assets/downloads/Machine-Learning-Systems.pdf" | cut -f1)
echo "✅ PDF deployed to dev site (${PDF_SIZE})"
else
echo "⚠️ PDF artifact not found - skipping PDF deployment"
mkdir -p ./preview-site/vol1/assets/downloads ./preview-site/vol2/assets/downloads
if [ -f "./pdf-vol1-artifact/Machine-Learning-Systems.pdf" ]; then
cp "./pdf-vol1-artifact/Machine-Learning-Systems.pdf" "./preview-site/vol1/assets/downloads/Machine-Learning-Systems-Vol1.pdf"
fi
# Copy EPUB if available
if [ -f "./epub-artifact/Machine-Learning-Systems.epub" ]; then
cp "./epub-artifact/Machine-Learning-Systems.epub" "./preview-site/assets/downloads/Machine-Learning-Systems.epub"
EPUB_SIZE=$(du -h "./preview-site/assets/downloads/Machine-Learning-Systems.epub" | cut -f1)
echo "✅ EPUB deployed to dev site (${EPUB_SIZE})"
else
echo "⚠️ EPUB artifact not found - skipping EPUB deployment"
if [ -f "./epub-vol1-artifact/Machine-Learning-Systems.epub" ]; then
cp "./epub-vol1-artifact/Machine-Learning-Systems.epub" "./preview-site/vol1/assets/downloads/Machine-Learning-Systems-Vol1.epub"
fi
if [ -f "./pdf-vol2-artifact/Machine-Learning-Systems.pdf" ]; then
cp "./pdf-vol2-artifact/Machine-Learning-Systems.pdf" "./preview-site/vol2/assets/downloads/Machine-Learning-Systems-Vol2.pdf"
fi
if [ -f "./epub-vol2-artifact/Machine-Learning-Systems.epub" ]; then
cp "./epub-vol2-artifact/Machine-Learning-Systems.epub" "./preview-site/vol2/assets/downloads/Machine-Learning-Systems-Vol2.epub"
fi
- name: 📝 Create .nojekyll file
@@ -203,8 +226,13 @@ jobs:
touch .nojekyll
echo "🔍 Validating deployment content..."
if [ ! -f "${{ vars.DEV_BOOK_PATH }}/index.html" ]; then
echo "❌ CRITICAL: ${{ vars.DEV_BOOK_PATH }}/index.html is missing after copy. Aborting deployment."
if [ ! -f "${{ vars.DEV_BOOK_PATH }}/vol1/index.html" ]; then
echo "❌ CRITICAL: ${{ vars.DEV_BOOK_PATH }}/vol1/index.html is missing after copy. Aborting deployment."
exit 1
fi
if [ ! -f "${{ vars.DEV_BOOK_PATH }}/vol2/index.html" ]; then
echo "❌ CRITICAL: ${{ vars.DEV_BOOK_PATH }}/vol2/index.html is missing after copy. Aborting deployment."
exit 1
fi

View File

@@ -143,12 +143,11 @@ on:
- 'yes'
default: 'no'
deploy_target:
description: 'Deploy target (combined=book only, vol1, vol2, all=everything)'
description: 'Deploy target (vol1, vol2, all=everything)'
required: false
type: choice
options:
- 'all'
- 'combined'
- 'vol1'
- 'vol2'
default: 'all'
@@ -762,7 +761,7 @@ jobs:
build_html: true # HTML + PDF + EPUB for production
build_pdf: true
build_epub: true
build_target: ${{ github.event.inputs.deploy_target || 'all' }}
build_target: all
target: main
container_registry: 'ghcr.io'
container_tag: 'latest'
@@ -847,54 +846,15 @@ jobs:
- name: 🔍 Validate API Contract
run: |
echo "🔍 Validating artifact names from API..."
HTML_ARTIFACT="${{ needs.call-production-build.outputs.linux_html_artifact }}"
PDF_ARTIFACT="${{ needs.call-production-build.outputs.linux_pdf_artifact }}"
EPUB_ARTIFACT="${{ needs.call-production-build.outputs.linux_epub_artifact }}"
echo "📄 HTML artifact name: '$HTML_ARTIFACT'"
echo "📑 PDF artifact name: '$PDF_ARTIFACT'"
echo "📚 EPUB artifact name: '$EPUB_ARTIFACT'"
# Fail explicitly if API didn't provide artifact names
if [ -z "$HTML_ARTIFACT" ]; then
echo "❌ CRITICAL: HTML artifact name not provided by build workflow API!"
echo "🔧 This indicates the workflow output contract is broken."
VOL1_HTML="${{ needs.call-production-build.outputs.linux_html_vol1_artifact }}"
VOL2_HTML="${{ needs.call-production-build.outputs.linux_html_vol2_artifact }}"
echo "📘 Vol1 HTML artifact: '$VOL1_HTML'"
echo "📙 Vol2 HTML artifact: '$VOL2_HTML'"
if [ -z "$VOL1_HTML" ] || [ -z "$VOL2_HTML" ]; then
echo "❌ CRITICAL: Volume artifact names missing from build workflow outputs"
exit 1
fi
if [ -z "$PDF_ARTIFACT" ]; then
echo "❌ CRITICAL: PDF artifact name not provided by build workflow API!"
echo "🔧 This indicates the workflow output contract is broken."
exit 1
fi
if [ -z "$EPUB_ARTIFACT" ]; then
echo "❌ CRITICAL: EPUB artifact name not provided by build workflow API!"
echo "🔧 This indicates the workflow output contract is broken."
exit 1
fi
echo "✅ API contract validated - all artifact names provided"
- name: 📦 Download HTML Artifacts
uses: actions/download-artifact@v7
with:
name: ${{ needs.call-production-build.outputs.linux_html_artifact }}
path: ./html-temp
- name: 📦 Download PDF Artifacts
uses: actions/download-artifact@v7
with:
name: ${{ needs.call-production-build.outputs.linux_pdf_artifact }}
path: ./pdf-temp
- name: 📦 Download EPUB Artifacts
uses: actions/download-artifact@v7
with:
name: ${{ needs.call-production-build.outputs.linux_epub_artifact }}
path: ./epub-temp
continue-on-error: true
echo "✅ API contract validated for volume artifacts"
# =================================================================
# Volume I Artifacts (when deploy_target is vol1 or all)
@@ -953,121 +913,11 @@ jobs:
- name: 📋 Verify Downloaded Artifacts
run: |
echo "📦 Verifying downloaded artifacts..."
# Find HTML build directory - check if html-temp has content
if [ ! -d "html-temp" ] || [ -z "$(ls -A html-temp 2>/dev/null)" ]; then
echo "❌ HTML build directory not found or empty!"
echo "📊 HTML artifact contents:"
find html-temp -type f -o -type d | head -20
if [ ! -d "html-vol1-temp" ] || [ ! -d "html-vol2-temp" ]; then
echo "❌ Required volume HTML artifacts were not downloaded."
exit 1
fi
# Look for the actual HTML build structure
HTML_BUILD_DIR="html-temp"
if [ -d "html-temp/html" ]; then
HTML_BUILD_DIR="html-temp/html"
echo "✅ HTML build found in subdirectory: $HTML_BUILD_DIR"
else
echo "✅ HTML build found at root level: $HTML_BUILD_DIR"
fi
echo "📊 HTML structure preview:"
ls -la "$HTML_BUILD_DIR" | head -5
# Find PDF file
PDF_FILE=$(find pdf-temp -name "Machine-Learning-Systems.pdf" -type f | head -1)
if [ -z "$PDF_FILE" ] || [ ! -f "$PDF_FILE" ]; then
echo "❌ PDF file not found in extracted artifacts!"
echo "📊 PDF artifact contents:"
find pdf-temp -type f -o -type d | head -20
exit 1
fi
echo "✅ PDF found: $PDF_FILE"
echo "📊 PDF size: $(du -h "$PDF_FILE" | cut -f1)"
# Find EPUB file if available
EPUB_FILE=""
if [ -d "epub-temp" ]; then
EPUB_FILE=$(find epub-temp -name "Machine-Learning-Systems.epub" -type f | head -1)
if [ -z "$EPUB_FILE" ] || [ ! -f "$EPUB_FILE" ]; then
# Try alternative EPUB filenames
EPUB_FILE=$(find epub-temp -name "*.epub" -type f | head -1)
if [ -n "$EPUB_FILE" ] && [ -f "$EPUB_FILE" ]; then
echo "✅ EPUB found (alternative name): $EPUB_FILE"
echo "📊 EPUB size: $(du -h "$EPUB_FILE" | cut -f1)"
else
echo "⚠️ EPUB file not found in extracted artifacts - will skip EPUB deployment"
EPUB_FILE=""
fi
else
echo "✅ EPUB found: $EPUB_FILE"
echo "📊 EPUB size: $(du -h "$EPUB_FILE" | cut -f1)"
fi
else
echo "⚠️ No EPUB artifact extracted - will skip EPUB deployment"
fi
# Prepare combined site
echo "🔄 Preparing combined HTML site with PDF and EPUB..."
mkdir -p combined-site
# Copy HTML content
cp -r "$HTML_BUILD_DIR"/* combined-site/
# Create assets and downloads directories
mkdir -p combined-site/assets/downloads
# Copy PDF if available
if [ -n "$PDF_FILE" ] && [ -f "$PDF_FILE" ]; then
PDF_SIZE_MB=$(du -m "$PDF_FILE" | cut -f1)
echo "📊 PDF size: ${PDF_SIZE_MB}MB"
# Deploy PDF to both GitHub Pages and GitHub Release
cp "$PDF_FILE" combined-site/assets/downloads/Machine-Learning-Systems.pdf
echo "✅ PDF deployed to GitHub Pages (${PDF_SIZE_MB}MB)"
# Also copy PDF for GitHub release
cp "$PDF_FILE" "Machine-Learning-Systems.pdf"
echo "✅ PDF prepared for release"
else
echo "❌ PDF file not found - skipping PDF deployment"
fi
# Copy EPUB if available
if [ -n "$EPUB_FILE" ] && [ -f "$EPUB_FILE" ]; then
EPUB_SIZE_MB=$(du -m "$EPUB_FILE" | cut -f1)
echo "📊 EPUB size: ${EPUB_SIZE_MB}MB"
# Deploy EPUB to both GitHub Pages and GitHub Release
cp "$EPUB_FILE" combined-site/assets/downloads/Machine-Learning-Systems.epub
echo "✅ EPUB deployed to GitHub Pages (${EPUB_SIZE_MB}MB)"
# Also copy EPUB for GitHub release
cp "$EPUB_FILE" "Machine-Learning-Systems.epub"
echo "✅ EPUB prepared for release"
else
echo "❌ EPUB file not found - skipping EPUB deployment"
fi
echo "📊 Combined site structure:"
ls -la combined-site/ | head -10
echo "📊 Assets directory:"
ls -la combined-site/assets/
# Summary of what was prepared
echo "📋 Asset preparation complete:"
if [ -f "Machine-Learning-Systems.pdf" ]; then
echo " ✅ PDF: Ready for deployment"
else
echo " ❌ PDF: Not available"
fi
if [ -f "Machine-Learning-Systems.epub" ]; then
echo " ✅ EPUB: Ready for deployment"
else
echo " ❌ EPUB: Not available"
fi
# =================================================================
# Prepare Volume I site (if artifacts exist)
# =================================================================
@@ -1166,9 +1016,8 @@ jobs:
# =================================================================
# Each subsite has its own directory:
# / - Landing page (AI Engineering)
# /book/ - Combined textbook (Vol I + II)
# /vol1/ - Volume I standalone
# /vol2/ - Volume II standalone
# /book/vol1/ - Volume I
# /book/vol2/ - Volume II
# /tinytorch/ - TinyTorch framework
# /kits/ - Hardware Kits
# /labs/ - Labs
@@ -1187,41 +1036,30 @@ jobs:
echo "✅ Stale files removed"
# =================================================================
# Deploy Combined Book to /book/ (if target is combined or all)
# =================================================================
if [[ "$DEPLOY_TARGET" == "combined" || "$DEPLOY_TARGET" == "all" ]]; then
echo "📦 Deploying combined textbook to /book/..."
rm -rf book/
mkdir -p book
cp -r ../combined-site/* book/
echo "✅ Combined textbook deployed to /book/"
fi
# =================================================================
# Deploy Volume I to /vol1/ (if target is vol1 or all)
# Deploy Volume I to /book/vol1/ (if target is vol1 or all)
# =================================================================
if [[ "$DEPLOY_TARGET" == "vol1" || "$DEPLOY_TARGET" == "all" ]]; then
if [ -d "../vol1-site" ]; then
echo "📦 Deploying Volume I to /vol1/..."
rm -rf vol1/
mkdir -p vol1
cp -r ../vol1-site/* vol1/
echo "✅ Volume I deployed to /vol1/"
echo "📦 Deploying Volume I to /book/vol1/..."
rm -rf book/vol1/
mkdir -p book/vol1
cp -r ../vol1-site/* book/vol1/
echo "✅ Volume I deployed to /book/vol1/"
else
echo "⚠️ Volume I site not found - skipping"
fi
fi
# =================================================================
# Deploy Volume II to /vol2/ (if target is vol2 or all)
# Deploy Volume II to /book/vol2/ (if target is vol2 or all)
# =================================================================
if [[ "$DEPLOY_TARGET" == "vol2" || "$DEPLOY_TARGET" == "all" ]]; then
if [ -d "../vol2-site" ]; then
echo "📦 Deploying Volume II to /vol2/..."
rm -rf vol2/
mkdir -p vol2
cp -r ../vol2-site/* vol2/
echo "✅ Volume II deployed to /vol2/"
echo "📦 Deploying Volume II to /book/vol2/..."
rm -rf book/vol2/
mkdir -p book/vol2
cp -r ../vol2-site/* book/vol2/
echo "✅ Volume II deployed to /book/vol2/"
else
echo "⚠️ Volume II site not found - skipping"
fi
@@ -1237,14 +1075,14 @@ jobs:
cp ../landing-page/logo.png . 2>/dev/null || true
echo "✅ Landing page deployed to root"
else
echo "⚠️ Landing page not found - creating redirect to /book/"
echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="refresh" content="0;url=/book/"><link rel="canonical" href="https://mlsysbook.ai/book/"><title>Redirecting...</title></head><body><p>Redirecting to <a href="/book/">ML Systems</a>...</p></body></html>' > index.html
echo "⚠️ Landing page not found - creating redirect to /book/vol1/"
echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="refresh" content="0;url=/book/vol1/"><link rel="canonical" href="https://mlsysbook.ai/book/vol1/"><title>Redirecting...</title></head><body><p>Redirecting to <a href="/book/vol1/">ML Systems Volume I</a>...</p></body></html>' > index.html
fi
else
# For non-all deployments, keep existing root or create redirect
if [ ! -f "index.html" ]; then
echo "📦 Creating root redirect to /book/..."
echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="refresh" content="0;url=/book/"><link rel="canonical" href="https://mlsysbook.ai/book/"><title>Redirecting...</title></head><body><p>Redirecting to <a href="/book/">ML Systems</a>...</p></body></html>' > index.html
echo "📦 Creating root redirect to /book/vol1/..."
echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="refresh" content="0;url=/book/vol1/"><link rel="canonical" href="https://mlsysbook.ai/book/vol1/"><title>Redirecting...</title></head><body><p>Redirecting to <a href="/book/vol1/">ML Systems Volume I</a>...</p></body></html>' > index.html
fi
fi

View File

@@ -255,6 +255,7 @@ jobs:
build_html: ${{ needs.build-config.outputs.build_html == 'true' }}
build_pdf: ${{ needs.build-config.outputs.build_pdf == 'true' }}
build_epub: ${{ needs.build-config.outputs.build_epub == 'true' }}
build_target: all
target: ${{ needs.build-config.outputs.target }}
container_registry: ${{ needs.build-config.outputs.container_registry }}
container_tag: ${{ needs.build-config.outputs.container_tag }}
@@ -273,6 +274,7 @@ jobs:
build_html: ${{ needs.build-config.outputs.build_html == 'true' }}
build_pdf: ${{ needs.build-config.outputs.build_pdf == 'true' }}
build_epub: ${{ needs.build-config.outputs.build_epub == 'true' }}
build_target: all
target: ${{ needs.build-config.outputs.target }}
report-baremetal-pass:
@@ -293,10 +295,12 @@ jobs:
outputs:
linux_success: ${{ steps.collect.outputs.linux_success }}
windows_success: ${{ steps.collect.outputs.windows_success }}
linux_html_artifact: ${{ steps.collect.outputs.linux_html_artifact }}
windows_html_artifact: ${{ steps.collect.outputs.windows_html_artifact }}
linux_pdf_artifact: ${{ steps.collect.outputs.linux_pdf_artifact }}
windows_pdf_artifact: ${{ steps.collect.outputs.windows_pdf_artifact }}
linux_html_vol1_artifact: ${{ steps.collect.outputs.linux_html_vol1_artifact }}
linux_html_vol2_artifact: ${{ steps.collect.outputs.linux_html_vol2_artifact }}
linux_pdf_vol1_artifact: ${{ steps.collect.outputs.linux_pdf_vol1_artifact }}
linux_pdf_vol2_artifact: ${{ steps.collect.outputs.linux_pdf_vol2_artifact }}
linux_epub_vol1_artifact: ${{ steps.collect.outputs.linux_epub_vol1_artifact }}
linux_epub_vol2_artifact: ${{ steps.collect.outputs.linux_epub_vol2_artifact }}
steps:
- name: 📊 Collect build results
@@ -306,20 +310,24 @@ jobs:
# These will hold the final results, preferring container builds
OVERALL_SUCCESS="false"
LINUX_HTML=""
WINDOWS_HTML=""
LINUX_PDF=""
WINDOWS_PDF=""
LINUX_HTML_VOL1=""
LINUX_HTML_VOL2=""
LINUX_PDF_VOL1=""
LINUX_PDF_VOL2=""
LINUX_EPUB_VOL1=""
LINUX_EPUB_VOL2=""
# Check container build results first
if [[ "${{ needs.build-config.outputs.build_method }}" == "container" || "${{ needs.build-config.outputs.build_method }}" == "both" ]]; then
if [[ "${{ needs.build-container.result }}" == "success" ]]; then
echo "✅ Container builds completed successfully."
OVERALL_SUCCESS="${{ needs.build-container.outputs.build_success }}"
LINUX_HTML="${{ needs.build-container.outputs.linux_html_artifact }}"
LINUX_PDF="${{ needs.build-container.outputs.linux_pdf_artifact }}"
WINDOWS_HTML="${{ needs.build-container.outputs.windows_html_artifact }}"
WINDOWS_PDF="${{ needs.build-container.outputs.windows_pdf_artifact }}"
LINUX_HTML_VOL1="${{ needs.build-container.outputs.linux_html_vol1_artifact }}"
LINUX_HTML_VOL2="${{ needs.build-container.outputs.linux_html_vol2_artifact }}"
LINUX_PDF_VOL1="${{ needs.build-container.outputs.linux_pdf_vol1_artifact }}"
LINUX_PDF_VOL2="${{ needs.build-container.outputs.linux_pdf_vol2_artifact }}"
LINUX_EPUB_VOL1="${{ needs.build-container.outputs.linux_epub_vol1_artifact }}"
LINUX_EPUB_VOL2="${{ needs.build-container.outputs.linux_epub_vol2_artifact }}"
else
echo "❌ Container builds failed or were skipped."
OVERALL_SUCCESS="false"
@@ -331,10 +339,12 @@ jobs:
if [[ "${{ needs.build-baremetal.result }}" == "success" ]]; then
echo "✅ Baremetal builds completed successfully."
OVERALL_SUCCESS="${{ needs.build-baremetal.outputs.build_success }}"
LINUX_HTML="${{ needs.build-baremetal.outputs.linux_html_artifact }}"
LINUX_PDF="${{ needs.build-baremetal.outputs.linux_pdf_artifact }}"
WINDOWS_HTML="${{ needs.build-baremetal.outputs.windows_html_artifact }}"
WINDOWS_PDF="${{ needs.build-baremetal.outputs.windows_pdf_artifact }}"
LINUX_HTML_VOL1="${{ needs.build-baremetal.outputs.linux_html_vol1_artifact }}"
LINUX_HTML_VOL2="${{ needs.build-baremetal.outputs.linux_html_vol2_artifact }}"
LINUX_PDF_VOL1="${{ needs.build-baremetal.outputs.linux_pdf_vol1_artifact }}"
LINUX_PDF_VOL2="${{ needs.build-baremetal.outputs.linux_pdf_vol2_artifact }}"
LINUX_EPUB_VOL1="${{ needs.build-baremetal.outputs.linux_epub_vol1_artifact }}"
LINUX_EPUB_VOL2="${{ needs.build-baremetal.outputs.linux_epub_vol2_artifact }}"
else
echo "❌ Baremetal builds also failed or were skipped."
OVERALL_SUCCESS="false"
@@ -357,10 +367,12 @@ jobs:
# Set outputs
echo "linux_success=$LINUX_SUCCESS" >> $GITHUB_OUTPUT
echo "windows_success=$WINDOWS_SUCCESS" >> $GITHUB_OUTPUT
echo "linux_html_artifact=$LINUX_HTML" >> $GITHUB_OUTPUT
echo "windows_html_artifact=$WINDOWS_HTML" >> $GITHUB_OUTPUT
echo "linux_pdf_artifact=$LINUX_PDF" >> $GITHUB_OUTPUT
echo "windows_pdf_artifact=$WINDOWS_PDF" >> $GITHUB_OUTPUT
echo "linux_html_vol1_artifact=$LINUX_HTML_VOL1" >> $GITHUB_OUTPUT
echo "linux_html_vol2_artifact=$LINUX_HTML_VOL2" >> $GITHUB_OUTPUT
echo "linux_pdf_vol1_artifact=$LINUX_PDF_VOL1" >> $GITHUB_OUTPUT
echo "linux_pdf_vol2_artifact=$LINUX_PDF_VOL2" >> $GITHUB_OUTPUT
echo "linux_epub_vol1_artifact=$LINUX_EPUB_VOL1" >> $GITHUB_OUTPUT
echo "linux_epub_vol2_artifact=$LINUX_EPUB_VOL2" >> $GITHUB_OUTPUT
# Step 5: Final results and summary
validation-summary:

View File

@@ -72,6 +72,9 @@ website:
- icon: journal
text: "Volume II: At Scale"
href: ../vol2/
- icon: book
text: "Stable (Single Book)"
href: https://mlsysbook.ai
- text: "---"
- icon: fire
text: "TinyTorch"

View File

@@ -72,6 +72,9 @@ website:
- icon: journal
text: "Volume II: At Scale"
href: ./
- icon: book
text: "Stable (Single Book)"
href: https://mlsysbook.ai
- text: "---"
- icon: fire
text: "TinyTorch"