mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-03-11 17:49:25 -05:00
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:
258
.github/workflows/book-build-baremetal.yml
vendored
258
.github/workflows/book-build-baremetal.yml
vendored
@@ -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"
|
||||
|
||||
153
.github/workflows/book-build-container.yml
vendored
153
.github/workflows/book-build-container.yml
vendored
@@ -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
|
||||
# =================================================================
|
||||
|
||||
90
.github/workflows/book-preview-dev.yml
vendored
90
.github/workflows/book-preview-dev.yml
vendored
@@ -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
|
||||
|
||||
|
||||
220
.github/workflows/book-publish-live.yml
vendored
220
.github/workflows/book-publish-live.yml
vendored
@@ -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
|
||||
|
||||
|
||||
52
.github/workflows/book-validate-dev.yml
vendored
52
.github/workflows/book-validate-dev.yml
vendored
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user