Reusable composite GitHub Actions for building QuantEcon lecture repositories.
This repository provides a set of composite actions that standardize and optimize the build process for QuantEcon lecture websites. These actions include intelligent caching strategies that significantly reduce build times.
Status: Stable; current release v0.7.0 (see the CHANGELOG).
📋 See: docs/CONTAINER-GUIDE.md for quick start, docs/ARCHITECTURE.md for design overview.
🚀 setup-environment [Recommended]
Flexible environment setup with optional Conda, LaTeX, and ML libraries.
Time Savings: ~5-6 minutes per run (container mode or cached Conda)
Features:
- Container-aware: Auto-detects QuantEcon container and optimizes setup
- Single action replaces both
setup-lecture-envandsetup-latex - Conda environment caching for fast restores
- Simplified workflow configuration
Builds Jupyter Book lectures (HTML, PDF, notebooks) with unified error handling.
Features: Multi-format builds, asset assembly (PDF/notebooks into HTML), execution reports on failure
Deploys preview builds to Netlify for pull requests with smart PR comments.
Features: Automatic changed-file detection, PR preview URLs, security-aware (skips forks)
Deploys preview builds to Cloudflare Pages for pull requests.
Features: Free for public & private repos, predictable URLs (pr-N.project.pages.dev), changed lecture detection, smart PR comments
Publishes production builds to GitHub Pages using native artifact-based deployment.
Features: Custom domain support, native GitHub Pages deployment (no gh-pages branch), optional release assets
Weekly cache generation for main branch builds.
Features: Multi-format builds (html, pdflatex, jupyter), validates all builds pass before saving, creates GitHub issues on failure, unique cache keys for safe updates
Read-only cache restore for PR workflows.
Features: Never saves (PRs can't corrupt cache), prefix matching for latest cache, detailed status logging, optional fail-on-miss
name: Build Preview
on: [pull_request]
jobs:
preview:
runs-on: ubuntu-latest
container:
image: ghcr.io/quantecon/quantecon-build:latest
permissions:
contents: read
packages: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Restore cache from main branch builds
- uses: quantecon/actions/restore-jupyter-cache@v0
with:
cache-type: 'build'
# Build (uses restored cache for incremental build)
- uses: quantecon/actions/build-lectures@v0
id: build
- uses: quantecon/actions/preview-netlify@v0
with:
netlify-auth-token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
netlify-site-id: ${{ secrets.NETLIFY_SITE_ID }}
build-dir: ${{ steps.build.outputs.build-path }}Run weekly on main branch to generate cache for PRs:
name: Build Cache
on:
schedule:
- cron: '0 2 * * 1' # Weekly Monday 2am UTC
workflow_dispatch:
jobs:
cache:
runs-on: ubuntu-latest
container:
image: ghcr.io/quantecon/quantecon:latest
permissions:
contents: read
issues: write
packages: read
steps:
- uses: actions/checkout@v4
- uses: quantecon/actions/build-jupyter-cache@v0
with:
builders: 'html'
create-issue-on-failure: trueFor projects with custom environment.yml that need full control:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: quantecon/actions/setup-environment@v0
with:
python-version: '3.13'
environment: 'environment.yml' # Full installation from scratch
install-latex: 'true'
latex-requirements-file: 'latex-requirements.txt'
- uses: quantecon/actions/build-lectures@v0- Pre-built container images with LaTeX and Python environment
ghcr.io/quantecon/quantecon:latest- Full image (~8.3 GB on disk, ~3.2 GB compressed pull)ghcr.io/quantecon/quantecon-build:latest- Lean image (~7.1 GB on disk, ~2.9 GB compressed pull); drops the full Anaconda metapackage, so it's only modestly smaller- Setup time: ~2-3 minutes (container pull + lecture-specific packages)
- Weekly automated builds (Monday 2am UTC) for security updates
Use build-jupyter-cache and restore-jupyter-cache actions for execution caching:
| Scenario | Build Time | Details |
|---|---|---|
| Full build (no cache) | ~17 minutes | All notebooks executed |
| Incremental build (cached) | ~3-4 minutes | Only changed notebooks executed |
| Time saved | ~13 minutes | ~80% reduction |
How it works:
- Weekly
build-jupyter-cacheruns on main branch (e.g., Monday 2am UTC) - PR workflows use
restore-jupyter-cacheto get the cached execution state - Jupyter Book only re-executes notebooks that have changed since the cache
The lecture repositories that consume these actions are tracked centrally in QuantEcon/meta#321 (avoids maintaining a duplicate list here).
We're in the 0.x development phase (pre-1.0.0). Reference the actions with:
@v0- Latest0.xrelease (recommended; floating tag, moved to each new release)@v0.7.0- Specific version (maximum reproducibility)@main- Latest development (use for testing only)
⚠️ During0.x, minor releases (0.x.0) may include breaking changes, so the floating@v0tag can move across a breaking change. Pin to an exact@v0.x.ytag if you need a guaranteed-stable reference. Floating major tags (@v1,@v2) will be introduced after the 1.0.0 release.
- docs/CONTAINER-GUIDE.md - Quick start with containers
- docs/ARCHITECTURE.md - System design and rationale
- docs/MIGRATION-GUIDE.md - Migrating lecture repositories
- docs/QUICK-REFERENCE.md - Action reference
- docs/GPU-AMI-SETUP.md - Building RunsOn GPU AMI
- docs/FUTURE-DEVELOPMENT.md - GPU support and roadmap
- TESTING.md - Testing strategy
- PLAN.md - Migration plan and feature parity status
See docs/MIGRATION-GUIDE.md for step-by-step instructions on migrating a lecture repository to use these actions.
See TESTING.md for our testing strategy and validation procedures.
- Create a feature branch
- Make changes to composite actions
- Test using
@mainreference in a lecture repository - Create a pull request with test results
- After merge, create a new version tag
MIT License - see LICENSE file for details
For issues or questions, please open an issue in this repository or contact the QuantEcon development team.