Skip to content

CI: install/run QuartoNotebookRunner under xvfb#42

Merged
asinghvi17 merged 7 commits into
mainfrom
as/qnr-xvfb
May 2, 2026
Merged

CI: install/run QuartoNotebookRunner under xvfb#42
asinghvi17 merged 7 commits into
mainfrom
as/qnr-xvfb

Conversation

@asinghvi17
Copy link
Copy Markdown
Collaborator

@asinghvi17 asinghvi17 commented May 2, 2026

To use GLMakie in CI, QuartoNotebookRunner needs to run under xvfb-run in CI, this makes it so ;)

Applies to both main.yaml (publish on push to main) and pr.yaml (preview deploy on PR).

Test plan

  • PR Publish workflow renders all chapters successfully under the new QNR + xvfb pipeline
  • Netlify preview deploy succeeds and the rendered site loads in the browser
  • Verify the Show QuartoNotebookRunner server log step output is informative if anything fails

🤖 Generated with Claude Code

- 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>
@netlify
Copy link
Copy Markdown

netlify Bot commented May 2, 2026

Deploy Preview for courageous-phoenix-f7cc3c canceled.

Name Link
🔨 Latest commit 27fa4b1
🔍 Latest deploy log https://app.netlify.com/projects/courageous-phoenix-f7cc3c/deploys/69f55f4a2e7f520008fd4fc3

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>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

asinghvi17 and others added 3 commits May 1, 2026 21:54
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>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

2 similar comments
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

@github-actions github-actions Bot temporarily deployed to pull request May 2, 2026 02:08 Inactive
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

asinghvi17 and others added 2 commits May 1, 2026 22:11
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>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

@github-actions github-actions Bot temporarily deployed to pull request May 2, 2026 02:19 Inactive
@asinghvi17 asinghvi17 merged commit d4cd72b into main May 2, 2026
5 checks passed
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

@github-actions github-actions Bot temporarily deployed to pull request May 2, 2026 02:26 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant