test(tinytorch): regression coverage for core tensor/layers/autograd/optimizer gaps #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: '📚 Book · ✅ Validate (Dev)' | |
| # ============================================================================= | |
| # ✅ Validate (Dev) — Lint, build, and test the book on every dev push | |
| # ============================================================================= | |
| # Re-run trigger: 2026-05-18 — refresh after projects.json design-grammar fix | |
| # ============================================================================= | |
| # | |
| # Runs pre-commit checks, then builds both volumes in all formats (HTML, PDF, | |
| # EPUB) on Linux and Windows using containerized Quarto. Uploads artifacts | |
| # for the Preview workflow to deploy. | |
| # | |
| # Flow: | |
| # 1. PRE_COMMIT — Run pre-commit hooks on all files | |
| # 2. BUILD_CONFIG — Determine formats, OS targets, and container settings | |
| # 3. CONTAINER_BUILD — Matrix build via book-build-container.yml (up to 12 jobs) | |
| # 4. COLLECT_RESULTS — Aggregate per-platform success and artifact names | |
| # 5. VALIDATION_SUMMARY — Report pass/fail and trigger preview deployment | |
| # | |
| # Triggers: | |
| # - pull_request into dev, paths under book/ and workflow files | |
| # - push: dev branch, paths under book/ and workflow files | |
| # - workflow_dispatch: manual with format/OS/container options | |
| # | |
| # The pull_request trigger exists because book/** changes previously merged | |
| # with no render gate. PR #2002 landed with the vol1 chapter list commented | |
| # out (the PDF built the foreword alone) and with \newif\ifmlsyscoverpage | |
| # declared in a vol1-only header while the shared before-body.tex set it, | |
| # which broke the Volume II PDF build outright. Neither was visible until | |
| # someone built the PDFs by hand days later. | |
| # | |
| # Deploys to: N/A (artifacts consumed by book-preview-dev.yml) | |
| # | |
| # Related: | |
| # - book-build-container.yml — Reusable build matrix called by this workflow | |
| # - book-preview-dev.yml — Deploys artifacts produced here to staging | |
| # - book-publish-live.yml — Production pipeline (builds from main) | |
| # | |
| # ============================================================================= | |
| on: | |
| pull_request: | |
| branches: [dev] # Render gate: catch book breakage before it lands | |
| paths: | |
| - 'book/**' | |
| - '.github/workflows/book-validate-dev.yml' | |
| - '.github/workflows/book-preview-dev.yml' | |
| push: | |
| branches: [dev] # Auto-trigger for dev branch | |
| paths: | |
| - 'book/**' | |
| - '.github/workflows/book-validate-dev.yml' | |
| - '.github/workflows/book-preview-dev.yml' | |
| workflow_dispatch: # Manual trigger for testing | |
| inputs: | |
| test_branch: | |
| description: 'Branch to test (for feature branch testing)' | |
| required: false | |
| default: '' | |
| type: string | |
| target: | |
| description: 'Target branch for build artifacts (dev/main)' | |
| required: false | |
| type: choice | |
| default: 'dev' | |
| options: | |
| - dev | |
| - main | |
| # Format & OS selection | |
| build_formats: | |
| description: '📦 Build formats (all, html, pdf, epub)' | |
| required: true | |
| default: 'all' | |
| type: choice | |
| options: | |
| - all | |
| - html | |
| - epub | |
| build_os: | |
| description: '⚙️ Build OS (linux, both, windows) — Windows disabled by default' | |
| required: true | |
| default: 'linux' | |
| type: choice | |
| options: | |
| - linux | |
| - both | |
| - windows | |
| # Container validation | |
| run_health_check: | |
| description: '💊 Run container health check' | |
| required: false | |
| default: false | |
| type: boolean | |
| # Container configuration (consistent with other workflows) | |
| container_registry: | |
| description: 'Container registry URL' | |
| required: false | |
| default: 'ghcr.io' | |
| type: string | |
| container_tag: | |
| description: 'Container tag to use' | |
| required: false | |
| default: 'latest' | |
| type: string | |
| permissions: | |
| contents: write | |
| pages: write | |
| packages: read | |
| actions: read | |
| concurrency: | |
| # Group includes event_name so a manual workflow_dispatch doesn't cancel | |
| # the auto push run (or vice versa) on the same SHA. | |
| group: book-validate-${{ github.ref }}-${{ github.event_name }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Step 1: Pre-commit validation | |
| pre-commit: | |
| name: '🔍 Pre-commit Checks' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.test_branch || github.ref }} | |
| fetch-depth: 0 | |
| - name: 🐍 Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: 🔍 Run pre-commit checks | |
| run: | | |
| echo "🔍 Installing and running pre-commit..." | |
| python -m pip install --upgrade pip | |
| pip install pre-commit | |
| echo "📦 Installing project dependencies for custom hooks..." | |
| pip install -r requirements.txt || echo "⚠️ Could not install all requirements, continuing..." | |
| echo "📦 Installing fallback hook dependencies..." | |
| pip install rich requests pillow pint pandas pytest || echo "⚠️ Could not install one or more fallback deps, continuing..." | |
| echo "🔧 Installing pre-commit hooks..." | |
| pre-commit install --install-hooks | |
| echo "🔄 Running pre-commit on all files..." | |
| echo "Python version: $(python --version)" | |
| if pre-commit run --all-files --verbose; then | |
| echo "✅ Pre-commit checks: PASSED" | |
| else | |
| echo "❌ Pre-commit checks: FAILED" | |
| echo "📋 Showing detailed output:" | |
| pre-commit run --all-files --verbose || true | |
| exit 1 | |
| fi | |
| # Step 2: Container Health Check (validate containers before builds) | |
| container-health-check: | |
| name: '💊 Container Health Check' | |
| needs: [build-config] | |
| if: inputs.run_health_check == true | |
| uses: ./.github/workflows/infra-health-check.yml # Shared workflow - no book- prefix | |
| with: | |
| test_linux: true | |
| test_windows: true | |
| container_registry: 'ghcr.io' | |
| container_tag: 'latest' | |
| # Step 3: Update contributors (after validation passes, before build matrix) | |
| update-contributors: | |
| name: '👥 Update Contributors' | |
| needs: [pre-commit] | |
| if: needs.pre-commit.result == 'success' && github.event_name == 'push' | |
| uses: ./.github/workflows/update-contributors.yml | |
| # Step 4: Determine build configuration (shared logic) | |
| build-config: | |
| name: '🎯 Build Configuration' | |
| needs: [pre-commit, update-contributors] | |
| if: always() && needs.pre-commit.result == 'success' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| build_html: ${{ steps.config.outputs.build_html }} | |
| build_pdf: ${{ steps.config.outputs.build_pdf }} | |
| build_epub: ${{ steps.config.outputs.build_epub }} | |
| build_linux: ${{ steps.config.outputs.build_linux }} | |
| build_windows: ${{ steps.config.outputs.build_windows }} | |
| container_registry: ${{ steps.config.outputs.container_registry }} | |
| container_tag: ${{ steps.config.outputs.container_tag }} | |
| target: ${{ steps.config.outputs.target }} | |
| steps: | |
| - name: 🎯 Determine build configuration | |
| id: config | |
| run: | | |
| echo "🎯 === BUILD CONFIGURATION ===" | |
| # Determine what to build based on inputs (individual format flags) | |
| if [ "${{ github.event_name }}" = "push" ]; then | |
| # Auto-trigger: build Linux only. Windows validate-dev is temporarily | |
| # disabled on push — the Windows container itself is still built by | |
| # infra-container-windows.yml on its own schedule/path triggers. | |
| # Re-enable by flipping BUILD_WINDOWS back to "true" below. | |
| BUILD_HTML="true" | |
| BUILD_PDF="true" | |
| BUILD_EPUB="true" | |
| BUILD_LINUX="true" | |
| BUILD_WINDOWS="false" | |
| TARGET="dev" # For push events, always target dev | |
| echo "📊 Trigger: Automatic (dev branch push)" | |
| echo "📊 HTML: $BUILD_HTML (mandatory)" | |
| echo "📊 PDF: $BUILD_PDF (mandatory)" | |
| echo "📊 EPUB: $BUILD_EPUB (mandatory)" | |
| echo "📊 Linux: $BUILD_LINUX (mandatory)" | |
| echo "📊 Windows: $BUILD_WINDOWS (temporarily disabled on dev push)" | |
| echo "📊 Method: container-only" | |
| echo "📊 Target: $TARGET" | |
| else | |
| # Manual trigger: respect choices | |
| echo "📊 Trigger: Manual workflow dispatch" | |
| BUILD_HTML="false" | |
| if [[ "${{ inputs.build_formats }}" == "all" || "${{ inputs.build_formats }}" == "html" ]]; then | |
| BUILD_HTML="true" | |
| fi | |
| BUILD_PDF="false" | |
| if [[ "${{ inputs.build_formats }}" == "all" || "${{ inputs.build_formats }}" == "pdf" ]]; then | |
| BUILD_PDF="true" | |
| fi | |
| BUILD_EPUB="false" | |
| if [[ "${{ inputs.build_formats }}" == "all" || "${{ inputs.build_formats }}" == "epub" ]]; then | |
| BUILD_EPUB="true" | |
| fi | |
| BUILD_LINUX="false" | |
| if [[ "${{ inputs.build_os }}" == "both" || "${{ inputs.build_os }}" == "linux" ]]; then | |
| BUILD_LINUX="true" | |
| fi | |
| BUILD_WINDOWS="false" | |
| if [[ "${{ inputs.build_os }}" == "both" || "${{ inputs.build_os }}" == "windows" ]]; then | |
| BUILD_WINDOWS="true" | |
| fi | |
| TARGET="${{ inputs.target }}" | |
| echo "📊 Formats: ${{ inputs.build_formats }} (HTML: $BUILD_HTML, PDF: $BUILD_PDF)" | |
| echo "📊 OS: ${{ inputs.build_os }} (Linux: $BUILD_LINUX, Windows: $BUILD_WINDOWS)" | |
| echo "📊 Method: container-only" | |
| echo "📊 Target: $TARGET" | |
| fi | |
| # Container configuration | |
| CONTAINER_REGISTRY="${{ inputs.container_registry || 'ghcr.io' }}" | |
| CONTAINER_TAG="${{ inputs.container_tag || 'latest' }}" | |
| echo "📊 Final Configuration:" | |
| echo " HTML: $BUILD_HTML" | |
| echo " PDF: $BUILD_PDF" | |
| echo " Linux: $BUILD_LINUX" | |
| echo " Windows: $BUILD_WINDOWS" | |
| echo " Method: container" | |
| echo " Registry: $CONTAINER_REGISTRY" | |
| echo " Tag: $CONTAINER_TAG" | |
| echo " Target: $TARGET" | |
| # Set outputs (individual format flags for matrix-driven approach) | |
| echo "build_html=$BUILD_HTML" >> $GITHUB_OUTPUT | |
| echo "build_pdf=$BUILD_PDF" >> $GITHUB_OUTPUT | |
| echo "build_epub=$BUILD_EPUB" >> $GITHUB_OUTPUT | |
| echo "build_linux=$BUILD_LINUX" >> $GITHUB_OUTPUT | |
| echo "build_windows=$BUILD_WINDOWS" >> $GITHUB_OUTPUT | |
| echo "container_registry=$CONTAINER_REGISTRY" >> $GITHUB_OUTPUT | |
| echo "container_tag=$CONTAINER_TAG" >> $GITHUB_OUTPUT | |
| echo "target=$TARGET" >> $GITHUB_OUTPUT | |
| # Step 4: Matrix-driven build calls (clean and simple!) | |
| build-container: | |
| name: '🐳 Container Build Matrix' | |
| needs: [build-config] | |
| if: | | |
| always() && | |
| (needs.build-config.result == 'success') | |
| uses: ./.github/workflows/book-build-container.yml | |
| with: | |
| build_linux: ${{ needs.build-config.outputs.build_linux == 'true' }} | |
| build_windows: ${{ needs.build-config.outputs.build_windows == 'true' }} | |
| 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 }} | |
| # Step 4: Collect build results (needed for outputs) | |
| collect-results: | |
| name: '📊 Collect Results' | |
| needs: [build-config, build-container] | |
| runs-on: ubuntu-latest | |
| if: always() | |
| outputs: | |
| linux_success: ${{ steps.collect.outputs.linux_success }} | |
| windows_success: ${{ steps.collect.outputs.windows_success }} | |
| 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 | |
| id: collect | |
| run: | | |
| echo "📊 === COLLECTING BUILD RESULTS ===" | |
| # These will hold the final results, preferring container builds | |
| OVERALL_SUCCESS="false" | |
| LINUX_HTML_VOL1="" | |
| LINUX_HTML_VOL2="" | |
| LINUX_PDF_VOL1="" | |
| LINUX_PDF_VOL2="" | |
| LINUX_EPUB_VOL1="" | |
| LINUX_EPUB_VOL2="" | |
| # Container-only results | |
| if [[ "${{ needs.build-container.result }}" == "success" ]]; then | |
| echo "✅ Container builds completed successfully." | |
| OVERALL_SUCCESS="${{ needs.build-container.outputs.build_success }}" | |
| 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" | |
| fi | |
| # Determine per-platform success based on overall success and which platforms were built | |
| LINUX_SUCCESS="false" | |
| if [[ "${{ needs.build-config.outputs.build_linux }}" == "true" && "$OVERALL_SUCCESS" == "true" ]]; then | |
| LINUX_SUCCESS="true" | |
| fi | |
| WINDOWS_SUCCESS="false" | |
| if [[ "${{ needs.build-config.outputs.build_windows }}" == "true" && "$OVERALL_SUCCESS" == "true" ]]; then | |
| WINDOWS_SUCCESS="true" | |
| fi | |
| echo "Final Success Status: Linux -> $LINUX_SUCCESS, Windows -> $WINDOWS_SUCCESS" | |
| # Set outputs | |
| echo "linux_success=$LINUX_SUCCESS" >> $GITHUB_OUTPUT | |
| echo "windows_success=$WINDOWS_SUCCESS" >> $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 4a: Epubcheck validation (Tier 1 — blocks on FATAL) | |
| # The pre-commit hook `book-epub-hygiene` catches source-level issues | |
| # that historically caused EPUB rejection (SVG control chars, dupe | |
| # marker ids, BibTeX URL escapes). Epubcheck is the full structural | |
| # validator and catches the rest: OPF manifest shape, XHTML XML | |
| # validity, cross-file references, URI syntax. | |
| # | |
| # Failure policy: FATAL > 0 fails the job (Kindle and ClearView | |
| # reject any EPUB with FATAL, so this is a ship-stopper). ERROR > 0 | |
| # is reported as a warning but does NOT fail the job, to let | |
| # remaining legacy errors be cleaned up incrementally without | |
| # blocking feature work. Tighten this by setting MAX_ERRORS=0 once | |
| # the baseline is clean in both volumes. | |
| epub-validate: | |
| name: '📘 EPUB validate (epubcheck via binder)' | |
| needs: [collect-results] | |
| if: | | |
| always() && | |
| needs.collect-results.outputs.linux_success == 'true' && | |
| needs.collect-results.outputs.linux_epub_vol1_artifact != '' && | |
| needs.collect-results.outputs.linux_epub_vol2_artifact != '' | |
| runs-on: ubuntu-latest | |
| env: | |
| # Ratchet baseline — fails if epubcheck counts exceed recorded | |
| # per-volume ceilings. Update with | |
| # ./binder check epub --scope epubcheck \ | |
| # --baseline book/tools/audit/epubcheck-baseline.json \ | |
| # --update-baseline | |
| # after a cleanup lands, and commit the changed file in the | |
| # same PR as the cleanup. This replaces the older flat | |
| # MAX_FATAL/MAX_ERRORS approach: a ratchet prevents regression | |
| # without cliff-failing during incremental cleanup. | |
| # | |
| # Path is relative to book/ because the run step does `cd book` | |
| # before invoking the binder CLI. | |
| BASELINE_PATH: 'tools/audit/epubcheck-baseline.json' | |
| steps: | |
| - name: 📥 Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: 🐍 Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: 📥 Download vol1 EPUB artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ needs.collect-results.outputs.linux_epub_vol1_artifact }} | |
| # Materialize into the canonical location the binder CLI | |
| # discovers (_discover_built_epubs walks | |
| # book/quarto/_build/epub-vol*/). | |
| path: book/quarto/_build/epub-vol1 | |
| - name: 📥 Download vol2 EPUB artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ needs.collect-results.outputs.linux_epub_vol2_artifact }} | |
| path: book/quarto/_build/epub-vol2 | |
| - name: ☕ Set up Java (for the epubcheck jar) | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: ⬇️ Install book Python dependencies | |
| # Installs the `epubcheck` PyPI wrapper (declared in | |
| # book/tools/dependencies/requirements.txt) alongside rich, | |
| # pyyaml, and the rest of the binder runtime. The wrapper | |
| # bundles the epubcheck jar and exposes it on PATH. | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r book/tools/dependencies/requirements.txt | |
| - name: 📘 Run `binder check epub --scope epubcheck` with baseline ratchet | |
| # Both source-level hygiene and post-build epubcheck validation | |
| # live inside the binder CLI. This step invokes the same | |
| # command a developer runs locally, so CI and local behaviour | |
| # stay in lockstep. | |
| # | |
| # The --baseline ratchet means CI fails only when the per- | |
| # volume FATAL/ERROR/WARNING count *exceeds* what was | |
| # recorded last time the baseline was updated. Prevents | |
| # regression without forcing a cliff-cleanup of every | |
| # pre-existing issue on every PR. | |
| env: | |
| BASELINE_PATH: ${{ env.BASELINE_PATH }} | |
| run: | | |
| set -euo pipefail | |
| cd book | |
| # JSON pass: machine-readable artifact (uploaded below). | |
| # GITHUB_ACTIONS=true is set automatically, so _epub_checks | |
| # emits `::error` annotations inline on the PR diff. | |
| ./binder check epub --scope epubcheck \ | |
| --baseline "${BASELINE_PATH}" \ | |
| --json > epubcheck-report.json || true | |
| # Human pass: exit code gates the CI job via the ratchet. | |
| ./binder check epub --scope epubcheck --baseline "${BASELINE_PATH}" | |
| - name: 📤 Upload epubcheck report | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: epubcheck-report | |
| path: book/epubcheck-report.json | |
| retention-days: 14 | |
| # Step 4b: Link integrity (Tier 2 — non-blocking baseline) | |
| # Tier 1 pre-commit (shared/scripts/check-internal-links.py) already blocks | |
| # broken internal links + anchors. This Lychee pass adds external reachability | |
| # as a warning. Flip fail_on_broken=true once the baseline is clean. | |
| check-links: | |
| name: '🔗 Check Links' | |
| needs: [pre-commit] | |
| if: always() && needs.pre-commit.result == 'success' | |
| uses: ./.github/workflows/infra-link-check.yml | |
| with: | |
| path_pattern: './book/quarto/contents/**/*.qmd' | |
| lycheeignore_path: 'book/config/linting/.lycheeignore' | |
| fail_on_broken: false | |
| max_concurrency: 10 | |
| # Step 5: Final results and summary | |
| validation-summary: | |
| name: '🎯 Validation Summary' | |
| if: always() | |
| needs: [pre-commit, build-config, collect-results, epub-validate, check-links] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 🎯 Generate validation summary | |
| run: | | |
| echo "🎯 === VALIDATION SUMMARY ===" | |
| echo "==============================" | |
| echo "" | |
| # Visual status indicators | |
| echo "🔍 RESULTS:" | |
| echo "----------" | |
| if [ "${{ needs.pre-commit.result }}" = "success" ]; then | |
| echo "✅ Pre-commit checks: PASSED" | |
| else | |
| echo "❌ Pre-commit checks: FAILED" | |
| fi | |
| if [ "${{ needs.build-config.outputs.build_linux }}" = "true" ]; then | |
| if [ "${{ needs.collect-results.outputs.linux_success }}" = "true" ]; then | |
| echo "✅ Linux build: PASSED" | |
| else | |
| echo "❌ Linux build: FAILED" | |
| fi | |
| else | |
| echo "⏭️ Linux build: SKIPPED" | |
| fi | |
| if [ "${{ needs.build-config.outputs.build_windows }}" = "true" ]; then | |
| if [ "${{ needs.collect-results.outputs.windows_success }}" = "true" ]; then | |
| echo "✅ Windows build: PASSED" | |
| else | |
| echo "❌ Windows build: FAILED" | |
| fi | |
| else | |
| echo "⏭️ Windows build: SKIPPED" | |
| fi | |
| case "${{ needs.epub-validate.result }}" in | |
| success) echo "✅ EPUB validate (epubcheck): PASSED" ;; | |
| failure) echo "❌ EPUB validate (epubcheck): FAILED" ;; | |
| skipped) echo "⏭️ EPUB validate (epubcheck): SKIPPED" ;; | |
| *) echo "⚠️ EPUB validate (epubcheck): ${{ needs.epub-validate.result }}" ;; | |
| esac | |
| echo "" | |
| echo "🎯 OVERALL STATUS:" | |
| echo "-----------------" | |
| # Determine overall success | |
| PRECOMMIT_OK="${{ needs.pre-commit.result == 'success' }}" | |
| LINUX_OK="${{ needs.collect-results.outputs.linux_success == 'true' || needs.build-config.outputs.build_linux == 'false' }}" | |
| WINDOWS_OK="${{ needs.collect-results.outputs.windows_success == 'true' || needs.build-config.outputs.build_windows == 'false' }}" | |
| if [ "$PRECOMMIT_OK" = "true" ] && [ "$LINUX_OK" = "true" ] && [ "$WINDOWS_OK" = "true" ]; then | |
| echo "🟢 VALIDATION: FULLY OPERATIONAL ✅" | |
| echo " All enabled checks passed successfully!" | |
| echo "🚀 PREVIEW: DEPLOYMENT TRIGGERED ✅" | |
| echo " A separate workflow will deploy the preview to the staging site." | |
| else | |
| echo "🔴 VALIDATION: ISSUES DETECTED ❌" | |
| echo " Check the logs above for details" | |
| fi | |
| echo "==============================" | |
| - name: 📋 Generate GitHub summary | |
| run: | | |
| echo "# 🎯 Enhanced Dev Validation Report" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 📊 Build Results" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Pre-commit**: ${{ needs.pre-commit.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Linux Build**: ${{ needs.collect-results.outputs.linux_success == 'true' && '✅ success' || '❌ failed' }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Windows Build**: ${{ needs.collect-results.outputs.windows_success == 'true' && '✅ success' || '❌ failed' }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 🔧 Build Configuration" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ github.event_name }}" = "push" ]; then | |
| echo "- **Trigger**: Automatic (dev branch push)" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Format**: HTML + PDF + EPUB (mandatory)" >> $GITHUB_STEP_SUMMARY | |
| echo "- **OS**: Linux only (Windows temporarily disabled on push)" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Method**: ✅ Container builds only" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "- **Trigger**: Manual workflow dispatch" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Formats**: ${{ inputs.build_formats }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **OS**: ${{ inputs.build_os }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Method**: ✅ Container builds only" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Registry**: ${{ needs.build-config.outputs.container_registry }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Tag**: ${{ needs.build-config.outputs.container_tag }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Target**: ${{ needs.build-config.outputs.target }}" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 🚀 Preview Deployment" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ needs.collect-results.outputs.linux_success }}" = "true" ]; then | |
| echo "Deployment will be handled by a separate workflow." >> $GITHUB_STEP_SUMMARY | |
| echo "Check the 'Actions' tab for the '🚀 Deploy Preview' workflow run." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Deployment skipped due to build failure." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 🎯 Summary" >> $GITHUB_STEP_SUMMARY | |
| LINUX_OK="${{ needs.collect-results.outputs.linux_success == 'true' || needs.build-config.outputs.build_linux == 'false' }}" | |
| WINDOWS_OK="${{ needs.collect-results.outputs.windows_success == 'true' || needs.build-config.outputs.build_windows == 'false' }}" | |
| if [ "${{ needs.pre-commit.result }}" = "success" ] && [ "$LINUX_OK" = "true" ] && [ "$WINDOWS_OK" = "true" ]; then | |
| echo "✅ **Validation Passed** - All enabled builds successful" >> $GITHUB_STEP_SUMMARY | |
| echo "🚀 **Preview Deployment Triggered** - A separate workflow is handling the deployment." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ **Validation Failed** - Check the logs above" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## 🔗 Link Check (non-blocking)" >> $GITHUB_STEP_SUMMARY | |
| echo "- Result: \`${{ needs.check-links.result }}\` (see job for detail)" >> $GITHUB_STEP_SUMMARY |