CI: install/run QuartoNotebookRunner under xvfb#42
Merged
Conversation
- Install QuartoNotebookRunner.jl into the @quarto named environment (per the upstream README's daemon-mode instructions) - Start it as a long-running socket server on port 1234 in the background, wrapped in xvfb-run so headless GeoMakie/CairoMakie rendering has a virtual display available - Wrap `quarto render` itself in xvfb-run; run publish with render:false so Netlify publish doesn't re-render outside xvfb - Add the GeoMakie.jl xvfb apt package set: xorg-dev mesa-utils xvfb libgl1 freeglut3-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev - Set DATADEPS_ALWAYS_ACCEPT=true and QUARTO_JULIA_PROJECT=@quarto Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
✅ Deploy Preview for courageous-phoenix-f7cc3c canceled.
|
Use port = 0 so the OS picks an unused port. Quarto's render does not connect to this daemon (it starts its own QNR Server() internally when engine: julia is set), so polling for a specific port was theatrical. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QuartoNotebookRunner.serve() does NOT write a transport file on its own
(verified locally: serve() returns a Server, but the transport file at
~/Library/Caches/quarto/julia/julia_transport.txt is never created).
Quarto's render reuses an existing QNR server only when that transport
file exists with port/pid/key (see quarto-cli julia-engine.ts:443
"Transport file ... exists, reusing server.") - otherwise it spawns its
own QNR. So pre-starting QNR under xvfb-run was insufficient on its own.
The fix mirrors quarto-cli's bundled quartonotebookrunner.jl:
- Compute the same transport-file path Quarto expects:
$XDG_RUNTIME_DIR/julia/julia_transport.txt when XDG_RUNTIME_DIR is set,
else $XDG_DATA_HOME/quarto/julia/julia_transport.txt
- Run a small Julia script under xvfb-run that calls
QuartoNotebookRunner.serve(; timeout = 300), writes
{"port": ..., "pid": ..., "key": ...} to the transport file, and then
wait()s on the server (without wait, the script exits and kills it)
- Poll for the transport file, fail the step with the QNR log on timeout
Verified locally on macOS: `quarto call engine julia status` reports the
pre-started server (correct pid, port, runner version, environment)
after the wrapper script writes the transport file.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both workflows shared identical apt-deps + Pkg.add(QNR) + start-server + wait-for-transport-file logic. Move it into .github/actions/setup-qnr/action.yml as a composite action, exposing timeout / xvfb screen / wait-seconds as inputs with sensible defaults. main.yaml and pr.yaml each shrink by ~50 lines and now just call `uses: ./.github/actions/setup-qnr` after the Julia setup steps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 similar comments
QNR is already pre-started under xvfb-run by the setup-quartonotebookrunner-jl local action, so QNR's worker processes have DISPLAY set. `quarto render` / `quarto publish` on the Quarto side just dispatch render requests to QNR over TCP - they don't draw anything themselves and don't need a display. So we can go back to the standard quarto-dev/quarto-actions and drop the manual xvfb-run wrapper plus the `render: false` workaround on publish. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Netlify's GitHub integration auto-builds on every push, finishing in ~4s with empty/wrong content and replacing production. The actual CI render takes ~15min, leaving production broken in between. `ignore = "exit 0"` tells Netlify to cancel every auto-build so production stays at the last GHA-deployed render until the new one lands. Our `quarto publish netlify` and `nwtgck/actions-netlify@v3` steps upload via the Netlify API and are unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
To use GLMakie in CI, QuartoNotebookRunner needs to run under
xvfb-runin CI, this makes it so ;)Applies to both
main.yaml(publish on push to main) andpr.yaml(preview deploy on PR).Test plan
Show QuartoNotebookRunner server logstep output is informative if anything fails🤖 Generated with Claude Code