From 5931027ab60b863ef1ed214c2501e0856ed1b308 Mon Sep 17 00:00:00 2001 From: mmcky Date: Thu, 20 Nov 2025 10:40:51 +1100 Subject: [PATCH 1/5] Add container test workflow - Compare container build vs ubuntu-latest baseline - Validate environment setup and package installation - Generate build artifact comparison - Measure performance improvements --- .github/workflows/test-container.yml | 120 +++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 .github/workflows/test-container.yml diff --git a/.github/workflows/test-container.yml b/.github/workflows/test-container.yml new file mode 100644 index 0000000..331a41c --- /dev/null +++ b/.github/workflows/test-container.yml @@ -0,0 +1,120 @@ +name: Test Container Build + +on: + workflow_dispatch: + push: + branches: [test-container] + +jobs: + build-container: + name: Build with Container + runs-on: ubuntu-latest + container: + image: ghcr.io/quantecon/quantecon:latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate container environment + run: | + echo "=== Python Version ===" + python --version + echo "" + echo "=== Anaconda Base Packages ===" + conda list | grep -E "(numpy|scipy|pandas|matplotlib|jupyter)" + echo "" + echo "=== Jupyter Book ===" + jupyter-book --version + echo "" + echo "=== LaTeX ===" + pdflatex --version | head -n 1 + + - name: Install lecture dependencies + run: | + echo "=== Installing lecture-specific packages ===" + cd _notebook_repo + conda env update -f environment.yml + echo "" + echo "=== Verify quantecon installed ===" + python -c "import quantecon; print(f'quantecon {quantecon.__version__}')" + + - name: Build lectures + run: jupyter-book build lectures/ + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: html-container + path: lectures/_build/html/ + retention-days: 7 + + build-ubuntu: + name: Build with ubuntu-latest (baseline) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup environment + uses: quantecon/actions/setup-environment@main + with: + python-version: '3.13' + environment-file: '_notebook_repo/environment.yml' + install-latex: 'true' + environment-name: 'quantecon' + + - name: Build lectures + run: jupyter-book build lectures/ + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: html-ubuntu + path: lectures/_build/html/ + retention-days: 7 + + compare: + name: Compare Results + needs: [build-container, build-ubuntu] + runs-on: ubuntu-latest + if: always() + steps: + - name: Download container artifact + uses: actions/download-artifact@v4 + with: + name: html-container + path: html-container + continue-on-error: true + + - name: Download ubuntu artifact + uses: actions/download-artifact@v4 + with: + name: html-ubuntu + path: html-ubuntu + continue-on-error: true + + - name: Generate summary + run: | + echo "## Build Comparison Results :mag:" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [ -d "html-container" ] && [ -d "html-ubuntu" ]; then + echo "✅ Both builds completed successfully" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "### File Comparison" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + diff -r html-container/ html-ubuntu/ | head -n 50 || echo "No differences found (or only timestamps)" + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "### Performance Metrics" >> $GITHUB_STEP_SUMMARY + echo "Check job timings above to compare:" >> $GITHUB_STEP_SUMMARY + echo "- Container setup time (pull + install)" >> $GITHUB_STEP_SUMMARY + echo "- ubuntu-latest setup time (conda + latex + install)" >> $GITHUB_STEP_SUMMARY + echo "- Build times should be similar" >> $GITHUB_STEP_SUMMARY + else + echo "⚠️ One or both builds failed" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Check job logs above for details" >> $GITHUB_STEP_SUMMARY + fi From 5b0963665b24ba4aa4087f372761a593d1123f7f Mon Sep 17 00:00:00 2001 From: mmcky Date: Thu, 20 Nov 2025 12:32:44 +1100 Subject: [PATCH 2/5] Use quantecon container in ci.yml - Replace setup-miniconda + manual LaTeX install with container - Remove redundant test-container.yml workflow - Simplify to single conda env update step - Remove shell: bash -l {0} (not needed in container) --- .github/workflows/ci.yml | 45 +++------- .github/workflows/test-container.yml | 120 --------------------------- 2 files changed, 12 insertions(+), 153 deletions(-) delete mode 100644 .github/workflows/test-container.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4806928..1e10b8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,40 +3,17 @@ on: [pull_request] jobs: preview: runs-on: ubuntu-latest + container: + image: ghcr.io/quantecon/quantecon:latest steps: - name: Checkout uses: actions/checkout@v5 - - name: Setup Anaconda - uses: conda-incubator/setup-miniconda@v3 - with: - auto-update-conda: true - auto-activate-base: true - miniconda-version: 'latest' - python-version: "3.13" - environment-file: environment.yml - activate-environment: quantecon - - name: Graphics Support #TODO: Review if graphviz is needed - run: | - sudo apt-get -qq update && sudo apt-get install -y graphviz - - name: Install latex dependencies + + - name: Install lecture dependencies run: | - sudo apt-get -qq update - sudo apt-get install -y \ - texlive-latex-recommended \ - texlive-latex-extra \ - texlive-fonts-recommended \ - texlive-fonts-extra \ - texlive-xetex \ - latexmk \ - xindy \ - dvipng \ - cm-super - - name: Display Conda Environment Versions - shell: bash -l {0} - run: conda list - - name: Display Pip Versions - shell: bash -l {0} - run: pip list + conda env update -f environment.yml + echo "=== Installed Packages ===" + conda list - name: Download "build" folder (cache) uses: dawidd6/action-download-artifact@v11 with: @@ -44,33 +21,35 @@ jobs: branch: main name: build-cache path: _build + # Build Assets (Download Notebooks and PDF via LaTeX) - name: Build PDF from LaTeX - shell: bash -l {0} run: | jb build lectures --builder pdflatex --path-output ./ -n --keep-going mkdir -p _build/html/_pdf cp -u _build/latex/*.pdf _build/html/_pdf + - name: Upload Execution Reports (LaTeX) uses: actions/upload-artifact@v5 if: failure() with: name: execution-reports path: _build/latex/reports + - name: Build Download Notebooks (sphinx-tojupyter) - shell: bash -l {0} run: | jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter mkdir -p _build/html/_notebooks cp -u _build/jupyter/*.ipynb _build/html/_notebooks + # Build HTML (Website) # BUG: rm .doctress to remove `sphinx` rendering issues for ipywidget mimetypes # and clear the sphinx cache for building final HTML documents. - name: Build HTML - shell: bash -l {0} run: | rm -r _build/.doctrees jb build lectures --path-output ./ -nW --keep-going + - name: Upload Execution Reports (HTML) uses: actions/upload-artifact@v5 if: failure() diff --git a/.github/workflows/test-container.yml b/.github/workflows/test-container.yml deleted file mode 100644 index 331a41c..0000000 --- a/.github/workflows/test-container.yml +++ /dev/null @@ -1,120 +0,0 @@ -name: Test Container Build - -on: - workflow_dispatch: - push: - branches: [test-container] - -jobs: - build-container: - name: Build with Container - runs-on: ubuntu-latest - container: - image: ghcr.io/quantecon/quantecon:latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Validate container environment - run: | - echo "=== Python Version ===" - python --version - echo "" - echo "=== Anaconda Base Packages ===" - conda list | grep -E "(numpy|scipy|pandas|matplotlib|jupyter)" - echo "" - echo "=== Jupyter Book ===" - jupyter-book --version - echo "" - echo "=== LaTeX ===" - pdflatex --version | head -n 1 - - - name: Install lecture dependencies - run: | - echo "=== Installing lecture-specific packages ===" - cd _notebook_repo - conda env update -f environment.yml - echo "" - echo "=== Verify quantecon installed ===" - python -c "import quantecon; print(f'quantecon {quantecon.__version__}')" - - - name: Build lectures - run: jupyter-book build lectures/ - - - name: Upload build artifact - uses: actions/upload-artifact@v4 - with: - name: html-container - path: lectures/_build/html/ - retention-days: 7 - - build-ubuntu: - name: Build with ubuntu-latest (baseline) - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup environment - uses: quantecon/actions/setup-environment@main - with: - python-version: '3.13' - environment-file: '_notebook_repo/environment.yml' - install-latex: 'true' - environment-name: 'quantecon' - - - name: Build lectures - run: jupyter-book build lectures/ - - - name: Upload build artifact - uses: actions/upload-artifact@v4 - with: - name: html-ubuntu - path: lectures/_build/html/ - retention-days: 7 - - compare: - name: Compare Results - needs: [build-container, build-ubuntu] - runs-on: ubuntu-latest - if: always() - steps: - - name: Download container artifact - uses: actions/download-artifact@v4 - with: - name: html-container - path: html-container - continue-on-error: true - - - name: Download ubuntu artifact - uses: actions/download-artifact@v4 - with: - name: html-ubuntu - path: html-ubuntu - continue-on-error: true - - - name: Generate summary - run: | - echo "## Build Comparison Results :mag:" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - if [ -d "html-container" ] && [ -d "html-ubuntu" ]; then - echo "✅ Both builds completed successfully" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - echo "### File Comparison" >> $GITHUB_STEP_SUMMARY - echo "\`\`\`" >> $GITHUB_STEP_SUMMARY - diff -r html-container/ html-ubuntu/ | head -n 50 || echo "No differences found (or only timestamps)" - echo "\`\`\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - echo "### Performance Metrics" >> $GITHUB_STEP_SUMMARY - echo "Check job timings above to compare:" >> $GITHUB_STEP_SUMMARY - echo "- Container setup time (pull + install)" >> $GITHUB_STEP_SUMMARY - echo "- ubuntu-latest setup time (conda + latex + install)" >> $GITHUB_STEP_SUMMARY - echo "- Build times should be similar" >> $GITHUB_STEP_SUMMARY - else - echo "⚠️ One or both builds failed" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Check job logs above for details" >> $GITHUB_STEP_SUMMARY - fi From 53eba4781482d6fc898f242f6478b0970cd0788e Mon Sep 17 00:00:00 2001 From: mmcky Date: Thu, 20 Nov 2025 14:58:50 +1100 Subject: [PATCH 3/5] Force fresh container pull to get latest image - Add --pull always option to container config - Ensures latest ghcr.io/quantecon/quantecon:latest is used - Bypasses GitHub Actions runner cache --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e10b8b..b97b82d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ jobs: runs-on: ubuntu-latest container: image: ghcr.io/quantecon/quantecon:latest + options: --pull always # Force fresh container pull steps: - name: Checkout uses: actions/checkout@v5 From a829470e6b815bf4311814a3975691b3ccb8e47b Mon Sep 17 00:00:00 2001 From: mmcky Date: Thu, 20 Nov 2025 15:10:49 +1100 Subject: [PATCH 4/5] Remove --pull always option - GitHub Actions already pulls latest tag when changed - Force-pull adds 2min overhead unnecessarily - Previous issue was timing (test before container built) --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b97b82d..1e10b8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,6 @@ jobs: runs-on: ubuntu-latest container: image: ghcr.io/quantecon/quantecon:latest - options: --pull always # Force fresh container pull steps: - name: Checkout uses: actions/checkout@v5 From 681c9a3e73dbdf11e14e23c45e433bec88588208 Mon Sep 17 00:00:00 2001 From: mmcky Date: Thu, 20 Nov 2025 15:18:22 +1100 Subject: [PATCH 5/5] Remove conda env update step - All required packages already in container base image - environment.yml duplicated container contents (python=3.13, anaconda=2025.06, jupyter-book) - Embracing full container approach for cleaner workflow - Saves 30-60s per build --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e10b8b..dc5aef2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,11 +9,6 @@ jobs: - name: Checkout uses: actions/checkout@v5 - - name: Install lecture dependencies - run: | - conda env update -f environment.yml - echo "=== Installed Packages ===" - conda list - name: Download "build" folder (cache) uses: dawidd6/action-download-artifact@v11 with: