diff --git a/.github/workflows/ci-benchmark.yml b/.github/workflows/ci-benchmark.yml index 374ebbd69..92ebdafa8 100644 --- a/.github/workflows/ci-benchmark.yml +++ b/.github/workflows/ci-benchmark.yml @@ -186,6 +186,115 @@ jobs: - name: Mark phase — python setup done run: echo "python_setup=$(date +%s)" >> /tmp/benchmark-clock + # ── Julia Setup ────────────────────────────────────────── + # Cold builds (force_full_rebuild) delete _freeze, so Julia/Heatmap.qmd + # and friends re-execute during the babelquarto render — benchmark run + # 38109155362 died there with "Ensuring an updated julia server + # environment failed" because no Julia was installed. Mirror the + # setup from quarto-publish-update-cache.yml: Julia + a pinned + # QuartoNotebookRunner environment (QUARTO_JULIA_PROJECT skips Quarto's + # ensureQuartoNotebookRunnerEnvironment, which needs network+Pkg.update + # at render time) + the tutorial project env. + - name: Set up Julia + uses: julia-actions/setup-julia@v3 + with: + version: '1' + + - name: Cache Julia packages + uses: actions/cache/restore@v6 + with: + path: ~/.julia + key: julia-packages-${{ runner.os }}-${{ hashFiles('Julia/Project.toml') }} + restore-keys: | + julia-packages-${{ runner.os }}- + + - name: Install Julia packages + run: | + # Find the QuartoNotebookRunner version required by this Quarto installation. + # Quarto bundles its own julia-engine Project.toml that pins an exact QNR version. + JULIA_ENGINE_PROJ=$(find /opt/quarto -name "Project.toml" -path "*/julia-engine/*" 2>/dev/null | head -1) + QNR_VERSION="" + if [ -n "$JULIA_ENGINE_PROJ" ]; then + QNR_VERSION=$(grep -oP 'QuartoNotebookRunner = "=([^"]+)"' "$JULIA_ENGINE_PROJ" \ + | grep -oP '[0-9]+\.[0-9]+\.[0-9]+' || true) + echo "Quarto requires QuartoNotebookRunner=${QNR_VERSION}" + fi + + # Create a dedicated QNR environment. Setting QUARTO_JULIA_PROJECT to this + # path tells Quarto to skip ensureQuartoNotebookRunnerEnvironment (which calls + # Pkg.update() and needs network at render time) and simply verify QNR loads. + QNR_ENV="${HOME}/.julia/environments/quarto-julia-env" + mkdir -p "${QNR_ENV}" + + if [ -n "$QNR_VERSION" ]; then + julia --project="${QNR_ENV}" -e " + using Pkg + Pkg.add(name=\"QuartoNotebookRunner\", version=\"${QNR_VERSION}\") + Pkg.instantiate() + using QuartoNotebookRunner + println(\"QuartoNotebookRunner \$(pkgversion(QuartoNotebookRunner)) ready\") + " + else + julia --project="${QNR_ENV}" -e ' + using Pkg + Pkg.add("QuartoNotebookRunner") + Pkg.instantiate() + using QuartoNotebookRunner + println("QuartoNotebookRunner $(pkgversion(QuartoNotebookRunner)) ready") + ' + fi + + # Export so the render step can pick it up. + echo "QUARTO_JULIA_PROJECT=${QNR_ENV}" >> "$GITHUB_ENV" + + # Pre-instantiate the tutorial project environment (Julia/Project.toml). + # QNR workers use JULIA_PROJECT=@. and cd into the notebook directory, + # so they automatically pick up Julia/Project.toml for CairoMakie etc. + julia --project=Julia -e ' + using Pkg + Pkg.resolve() + Pkg.instantiate() + using CairoMakie, DataFrames, Statistics + println("Tutorial packages ready") + ' + + # Pre-render Julia notebooks to avoid OOM during the R-heavy main render. + # Also REQUIRED for correctness: without this step babelquarto executes + # Julia qmds inline in its temp dir and the julia-engine JSON handshake + # fails ("SyntaxError: Unexpected end of JSON input" — CI run + # 38114723635). Pre-rendering freezes Julia/*.qmd into the workspace + # _freeze so babelquarto never executes them. + - name: Create temporary directory + run: | + sudo mkdir -p ${{ env.TMP_DIR }} + sudo chown -R $USER:$USER ${{ env.TMP_DIR }} + + - name: Pre-render Julia notebooks + env: + QUARTO_JULIA_PROJECT: ${{ env.QUARTO_JULIA_PROJECT }} + TMPDIR: ${{ env.TMP_DIR }} + TMP: ${{ env.TMP_DIR }} + TEMP: ${{ env.TMP_DIR }} + run: | + echo "Pre-rendering Julia tutorials..." + failed=0 + for qmd in Julia/*.qmd; do + echo " → $qmd" + if quarto render "$qmd" 2>&1; then + echo " ✓ OK: $qmd" + else + echo " ✗ Failed: $qmd" + failed=1 + fi + done + julia_log="${HOME}/.cache/quarto/julia/julia_server_log.txt" + if [ -f "$julia_log" ]; then + echo "=== QNR server log ===" + tail -50 "$julia_log" + echo "======================" + fi + [ $failed -eq 0 ] || exit 1 + # ── Render pipeline (mirrors quarto-publish-update-cache.yml) ── - name: Pre-render all non-frozen QMD files env: