Files
cs249r_book/.github/workflows/build-container.yml
Vijay Janapa Reddi 8a9fe3ade0 refactor(container): organize container files in proper directory structure
- Move Dockerfile to docker/quarto-build/
- Add docker/quarto-build/README.md with documentation
- Add docker/quarto-build/.dockerignore for build optimization
- Update workflow to use new Dockerfile path
- Update documentation to reflect new structure
- Improve organization and maintainability
2025-08-05 14:48:50 -04:00

264 lines
11 KiB
YAML

name: '🐳 Build Container'
# This workflow builds the Quarto build container and pushes it to GitHub Container Registry
# The container pre-installs all dependencies to eliminate 30-45 minute setup time
# Includes comprehensive testing to ensure all components work properly
on:
workflow_dispatch:
inputs:
force_rebuild:
description: 'Force rebuild even if no changes'
required: false
default: false
type: boolean
schedule:
- cron: '0 0 * * 0' # Weekly rebuild (Sunday at midnight)
push:
paths:
- 'tools/dependencies/**'
- 'docker/quarto-build/**'
- '.github/workflows/build-container.yml'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/quarto-build
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🔐 Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 🏷️ Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: 🐳 Build and push container
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/quarto-build/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: 🧪 Test Container Functionality
run: |
echo "🧪 Testing container functionality..."
# Pull the built container
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
# Create a test directory with sample content
mkdir -p test-container
cd test-container
# Create a simple Quarto document for testing
cat > test.qmd << 'EOF'
---
title: "Container Test"
format: html
---
# Test Document
This is a test document to verify the container works properly.
```{python}
import pandas as pd
import numpy as np
print("Python test successful!")
```
```{r}
library(ggplot2)
library(dplyr)
print("R test successful!")
```
## Math Test
Here's a simple equation: $E = mc^2$
```{tikz}
\begin{tikzpicture}
\node[draw, fill=blue!20] at (0,0) {TikZ Test};
\node[draw, fill=red!20] at (2,0) {Success};
\draw[->] (0.8,0) -- (1.2,0);
\end{tikzpicture}
```
EOF
# Test 1: Basic Quarto functionality
echo "📊 Test 1: Basic Quarto functionality..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && quarto --version"
# Test 2: Python packages
echo "📊 Test 2: Python packages..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && python3 -c 'import pandas, numpy, jupyter, openai, groq, pybtex, PIL, yaml, yamllint, gradio, jsonschema, pypandoc, ghostscript, absl, pre_commit, requests, titlecase, rich, sentence_transformers, faiss, sklearn, torch; print(\"✅ All Python packages available!\")'"
# Test 3: R packages
echo "📊 Test 3: R packages..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && Rscript -e 'library(ggplot2); library(ggrepel); library(knitr); library(rmarkdown); library(tidyverse); library(reshape2); library(reticulate); library(rsvg); library(viridis); library(xml2); library(dplyr); library(grid); cat(\"✅ All R packages available!\n\")'"
# Test 4: TeX Live and LaTeX
echo "📊 Test 4: TeX Live and LaTeX..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && lualatex --version && pdflatex --version && echo '✅ LaTeX engines available!'"
# Test 5: Inkscape
echo "📊 Test 5: Inkscape..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && inkscape --version && echo '✅ Inkscape available!'"
# Test 6: Ghostscript
echo "📊 Test 6: Ghostscript..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && gs --version && echo '✅ Ghostscript available!'"
# Test 7: Fonts and graphics
echo "📊 Test 7: Fonts and graphics..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && fc-list | head -5 && echo '✅ Fonts available!'"
# Test 8: Quarto render test
echo "📊 Test 8: Quarto render test..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && quarto render test.qmd --to html && ls -la test.html && echo '✅ Quarto render successful!'"
# Test 9: TikZ compilation test
echo "📊 Test 9: TikZ compilation test..."
cat > tikz_test.tex << 'EOF'
\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{xcolor}
\usepackage[T1]{fontenc}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[font=\small\usefont{T1}{phv}{m}{n}]
\node[draw, fill=blue!20] at (0,0) {TikZ Test};
\node[draw, fill=red!20] at (2,0) {Success};
\draw[->] (0.8,0) -- (1.2,0);
\end{tikzpicture}
\end{document}
EOF
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && lualatex -interaction=nonstopmode tikz_test.tex && ls -la tikz_test.pdf && echo '✅ TikZ compilation successful!'"
# Test 10: SVG to PDF conversion test
echo "📊 Test 10: SVG to PDF conversion test..."
cat > test.svg << 'EOF'
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red"/>
<text x="50" y="55" text-anchor="middle" fill="white">Test</text>
</svg>
EOF
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && inkscape --export-type=pdf --export-filename=test.pdf test.svg && ls -la test.pdf && echo '✅ SVG to PDF conversion successful!'"
# Test 11: Memory and disk space check
echo "📊 Test 11: System resources..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "df -h . && free -h && echo '✅ System resources adequate!'"
# Test 12: Network connectivity (for package downloads)
echo "📊 Test 12: Network connectivity..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "curl -s https://cran.r-project.org/ > /dev/null && echo '✅ Network connectivity good!'"
# Test 13: Book structure compatibility test
echo "📊 Test 13: Book structure compatibility..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && ls -la book/ && echo '✅ Book directory accessible!'"
# Test 14: Quarto configuration test
echo "📊 Test 14: Quarto configuration test..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace/book && ls -la config/ && echo '✅ Quarto config files accessible!'"
# Test 15: Dependencies files test
echo "📊 Test 15: Dependencies files test..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace && ls -la tools/dependencies/ && echo '✅ Dependencies files accessible!'"
# Test 16: Quarto check test (same as your workflow)
echo "📊 Test 16: Quarto check test..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace/book && quarto check"
# Test 17: Simulate actual build process
echo "📊 Test 17: Simulate actual build process..."
docker run --rm -v $(pwd):/workspace ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
bash -c "cd /workspace/book && cp config/_quarto-html.yml _quarto.yml && quarto render --to html --quiet && echo '✅ HTML build simulation successful!'"
echo "🎉 All container tests completed successfully!"
echo "📊 Container is ready for production use!"
- name: 📋 Container Info
run: |
echo "✅ Container built and tested successfully"
echo "📊 Registry: ${{ env.REGISTRY }}"
echo "📊 Image: ${{ env.IMAGE_NAME }}"
echo "📊 Tags: ${{ steps.meta.outputs.tags }}"
echo "📊 Size: $(docker images ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest --format '{{.Size}}')"
echo ""
echo "🚀 Usage in workflows:"
echo "container:"
echo " image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
echo " options: --user root"
echo ""
echo "🧪 Tests performed:"
echo "✅ Quarto functionality"
echo "✅ Python packages (all from requirements.txt)"
echo "✅ R packages (all from install_packages.R)"
echo "✅ TeX Live and LaTeX engines"
echo "✅ Inkscape SVG to PDF conversion"
echo "✅ Ghostscript PDF compression"
echo "✅ Fonts and graphics libraries"
echo "✅ Quarto render test"
echo "✅ TikZ compilation test"
echo "✅ System resources check"
echo "✅ Network connectivity"
echo "✅ Book structure compatibility"
echo "✅ Quarto configuration files"
echo "✅ Dependencies files accessibility"
echo "✅ Quarto check (same as workflow)"
echo "✅ Actual build process simulation"
echo ""
echo "📈 Expected performance improvement:"
echo " Traditional build: 45 minutes"
echo " Containerized build: 5-10 minutes"