Support fully offline builds from a pre-populated deno cache#14708
Open
eejd wants to merge 21 commits into
Open
Support fully offline builds from a pre-populated deno cache#14708eejd wants to merge 21 commits into
eejd wants to merge 21 commits into
Conversation
…ass (quarto-dev#14274) * fix: set UTF-8 code page in safeWindowsExec batch files (quarto-dev#14267) safeWindowsExec writes temp .bat files as UTF-8 (Deno default), but cmd.exe reads them using the OEM code page (e.g., CP850). Multi-byte UTF-8 characters like é (0xC3 0xA9) get misinterpreted, breaking paths with accented characters (e.g., C:\Users\Sébastien\). Add `chcp 65001 >nul` to switch cmd.exe to UTF-8 before the command line is parsed. Use CRLF line endings for correct .bat parsing. * docs: add changelog entry for quarto-dev#14267 backport
…iew (quarto-dev#14288) * Fix transient .quarto_ipynb files accumulating during preview (quarto-dev#14281) Preview re-renders delete the fileInformationCache entry to pick up file changes, but this loses track of the transient .quarto_ipynb path. The collision-avoidance loop in jupyter.ts target() then sees the old file on disk and creates numbered variants (_1, _2, etc.) that are never cleaned up until preview exits. Add invalidateForFile() to FileInformationCacheMap that cleans up any transient notebook file from disk before removing the cache entry. Replace the bare delete() call in renderForPreview() with this method. Fixes quarto-dev#14281
Add type declarations for functions exported in init.lua that were missing from the lua-types annotations. This feeds into the autogen docs effort (quarto-dev/quarto-web#1649). quarto.doc: add_resource, add_supporting, is_filter_active quarto.utils: type, table.isarray, table.contains, table.sortedPairs, resolve_path_relative_to_document, as_inlines, as_blocks, is_empty_node, render, match, add_to_blocks (cherry picked from commit 6ce64dc)
…dev#14294) - EndBug/add-and-commit: v9.1.4 (node20) → v10.0.0 (node24) - softprops/action-gh-release: v1-era (node20) → v2.6.1, remove deprecated env GITHUB_TOKEN - julia-actions/setup-julia: @v2 (node20) → master SHA with node24 (no release yet) Follow-up to quarto-dev#14199 which updated official actions/* and other third-party actions. (cherry picked from commit 0ae540e)
…ev#14301) [backport] Fix preview browse URL for single-file documents Backport of quarto-dev#14300. After quarto-dev#13804 made the project variable always non-null via singleFileProjectContext(), single-file preview broke: the browse URL included the output filename and GET / returned 404. Guard both the URL path computation and handler selection with !project.isSingleFile. - Fix initialPath using relative path instead of empty string - Fix handler selection using wrong default file for single files - Add unit tests for previewInitialPath() - Add manual preview test entries and plain.qmd fixture Fixes quarto-dev#14298
Also sort quarto-dev#13878 into numerical order.
…tudio Backport from quarto-dev#14307. Gate `project` emission in `inspectDocumentConfig` on `!(isSingleFile && isRStudio())` so RStudio's publishing wizard doesn't crash on standalone .qmd files with Quarto >= 1.9.35. Ref: rstudio/rstudio#17333
…ecate chromium installer (quarto-dev#14335) Add arm64 Linux support for `quarto install chrome-headless-shell` using Microsoft's Playwright CDN as the download source, since Chrome for Testing has no arm64 Linux builds. Version metadata comes from Playwright's browsers.json, and the arm64 binary name difference (`headless_shell` vs `chrome-headless-shell`) is abstracted by a platform-aware helper. Add deprecation warnings guiding users from `chromium` to `chrome-headless-shell`: - `quarto install chromium` and `quarto update chromium` show deprecation before proceeding (including on WSL) - `quarto check install` shows migration guidance when legacy Chromium is detected in the installed tools list Add CI workflow (`test-install.yml`) covering arm64 Linux and macOS tool installation, and chromium deprecation warnings across all platforms. Partial backport from quarto-dev#14334. Fixes quarto-dev#1187
…uarto-dev#14360) Backport from quarto-dev#14357. `quarto install tinytex` silently succeeded when archive extraction failed, leaving users with a broken TinyTeX installation. Check the `unzip()` return value and surface a clear error message, including an xz-utils install hint on Linux for `.tar.xz` archives. Add `xz-utils`/`xz` to `.deb`/`.rpm` Recommends so the dependency is available on fresh installs. Fixes quarto-dev#14304
…icy restrictions (quarto-dev#14369) * Fall back to direct sass.bat execution when safeWindowsExec fails Enterprise Windows environments with Group Policy / AppLocker rules that block .bat execution from %TEMP% cause the safeWindowsExec temp wrapper to fail, breaking dart-sass invocation (regression from quarto-dev#14002). Try safeWindowsExec first (handles spaces in paths), then fall back to direct execProcess call (v1.8 behavior) when it fails. Fixes quarto-dev#14367 * Add changelog entry for quarto-dev#14367
v2 is a composite action whose post-save and delete-old-caches steps don't run reliably, letting per-run julia caches (~250 MB each) accumulate on refs/heads/main until the repository hits its 10 GB cache cap. v3 is a JavaScript rewrite with a proper post hook. It also uses Node.js 24 directly, dropping the latent Node 20 exposure from v2's transitive actions/cache dependency.
* Cache Deno development cache in CI (quarto-dev#14408) * Gate vendor.sh cache wipe behind QUARTO_SKIP_DENO_CACHE_WIPE Default behavior unchanged: local ./configure.sh still wipes deno_cache before re-vendoring. CI opts into cache preservation by setting QUARTO_SKIP_DENO_CACHE_WIPE=1, enabling actions/cache to restore the cache and have it survive vendor.sh. * Gate vendor.cmd cache wipe behind QUARTO_SKIP_DENO_CACHE_WIPE Windows counterpart to the vendor.sh change. Behavior matches: default wipes, QUARTO_SKIP_DENO_CACHE_WIPE=1 preserves. * Cache Deno development cache in CI Adds actions/cache restore for ./package/dist/bin/deno_cache, keyed on the five files that influence Deno dep resolution: configuration, src/import_map.json, src/vendor_deps.ts, tests/test-deps.ts, and package/scripts/deno_std/deno_std.ts. Both configure steps set QUARTO_SKIP_DENO_CACHE_WIPE=1 so the restored cache survives the configure.sh / configure.cmd run. Adds dev-docs/ci-deno-caching.md explaining the cache layout, key composition, env var contract, and how to force invalidation. Adds a cross-link from dev-docs/upgrade-dependencies.md so a contributor bumping deno_std version sees the cache consequences. Expected per-OS cache size ~150-200 MB; total footprint ~600 MB across Linux/macOS/Windows, well under GitHub's 10 GB repo quota. (cherry picked from commit e4b75c1) * Fix configure scripts destroying restored Deno CI cache (quarto-dev#14450) The CI Deno dev cache (Cache Deno development cache step in .github/workflows/actions/quarto-dev/action.yml) restores package/dist/bin/deno_cache before configure runs. configure.sh and configure.cmd then unconditionally wipe package/dist when bootstrapping Deno, destroying the just-restored cache before vendor.sh reaches it. The vendor scripts already gate their own cache wipe with QUARTO_SKIP_DENO_CACHE_WIPE=1; the configure-time wipe was missed. Apply the same gate to configure.sh and configure.cmd so the restored cache survives. Local devs (env var unset) keep the original wipe behavior. (cherry picked from commit 3e11b83)
… without _quarto.yml (quarto-dev#14492) * fix(preview): restore --output-dir for single-file preview without _quarto.yml When `quarto preview file.qmd --output-dir <dir>` runs in a directory without _quarto.yml, preview pre-creates a single-file ProjectContext and passes it to render() as pContext. The synthetic-project trigger in render-shared only fired when context was null, bypassing it for the preview path and surfacing the project-only-flag check. Extend the trigger to also fire when pContext is a single-file context. Discarded single-file context cleans up via globalTempContext. Adds a unit test that exercises the exact preview pattern. Fixes quarto-dev#14489. Preview side of posit-dev/positron#13370. * docs(changelog): add 1.9 entry for quarto-dev#14489 preview --output-dir fix Pairs with the backported render-shared.ts fix in the previous commit. * docs(changelog): move 1.9 entry under v1.10 backports section Backport entries belong under the "v1.10 backports > In this release" heading on the v1.9 release branch, not under "v1.9 changes > Regression fixes" (which tracks original v1.9 fixes).
…rsand (quarto-dev#14535) * [backport] Bypass sass.bat on Windows to fix ampersand-in-username regression (quarto-dev#14534) The v1.9 introduction of safeWindowsExec broke dart-sass for users whose Windows profile path contains `&` (e.g., C:\Users\Tom & Jerry\). The ampersand is a cmd.exe command separator, so the temp .bat wrapper that safeWindowsExec writes is split mid-path and fails. The existing quarto-dev#14367 fallback to direct sass.bat execution does not help: Windows still spawns cmd.exe internally to interpret any .bat file, and the ampersand splits again. Backport of the dart.exe + sass.snapshot direct-invocation rewrite from PR quarto-dev#14273 (commit 4a7b6ce). Calling dart.exe through Deno.Command bypasses cmd.exe entirely and removes the whole class of .bat issues on Windows. The bundled dart-sass version is identical between v1.9 and main (DARTSASS=1.87.0), so the src/dart.exe + src/sass.snapshot layout is the same on disk. This also subsumes the quarto-dev#14367 enterprise group-policy fallback (no .bat = no policy block) and reinforces the quarto-dev#14267 accented-path fix already backported via quarto-dev#14274. Out of scope: other safeWindowsExec callers (texlive, zip, shell) still go through cmd.exe and remain vulnerable to ampersand in paths. Those have separate fixes upstream and are not covered by this backport. * Add regression test for ampersand in dart-sass paths (quarto-dev#14534) Cover the exact path pattern that broke v1.9 (e.g. C:\Users\Tom & Jerry\) to prevent re-regression. Mirrors the existing spaced/accented tests by junctioning the real dart-sass install dir into an ampersand-containing parent directory and asserting compilation succeeds. The junction itself is created via cmd /c mklink — Deno.Command passes each arg as a separate CreateProcess argument, so the ampersand in the target path is not interpreted by cmd.exe as a command separator.
Publishing release has failed.
Two changes needed to build quarto.js from a source tarball (no .git, no network) against a pre-populated, checksummed DENO_DIR, as required by distro packaging (MacPorts, etc.): - src/webui/quarto-preview/build.ts: buildFromGit() unconditionally triggers a network-dependent `npm install && npm run build` whenever `git ls-files` fails, which it always does when building from a release tarball rather than a git checkout -- even though quarto-preview.js is already committed to the tree. Add an explicit QUARTO_SKIP_PREVIEW_BUILD opt-out so packagers can use the shipped build instead of triggering a spurious rebuild. - package/scripts/vendoring/vendor.sh: the `deno install` calls that resolve quarto's TypeScript module graph have no way to enforce that resolution stays local to an already-populated cache. Add QUARTO_VENDOR_LOCK (passes --lock=<path> --frozen) and QUARTO_VENDOR_OFFLINE=1 (passes --cached-only) so a cache miss fails loudly instead of silently reaching out to the network. Verified end-to-end: a full `configure.sh` + `quarto-bld prepare-dist` run against MacPorts-provided deno/pandoc/typst/dart-sass plus from-source esbuild/deno_dom dependencies, with these two env vars set and a pre-populated DENO_DIR, completes with zero network fetches and produces a working quarto.js that renders documents correctly.
Collaborator
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
cderv
requested changes
Jul 20, 2026
cderv
left a comment
Member
There was a problem hiding this comment.
Thanks for the PR - before we can review can you rebase you commits unto quarto-cli main branch from upstream. Looking at the number of commits in this PR, and the conflict, I believe your feature branch is not based on the correct HEAD.
Thank you
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.
Summary
Two small changes needed to build
quarto.jsfrom a source tarball (no.git, no network) against a pre-populated, checksummedDENO_DIR, as required by distro packaging (we're authoring a MacPorts port — see macports-ports-local#212).src/webui/quarto-preview/build.ts:buildFromGit()unconditionally triggers a network-dependentnpm install && npm run buildwhenevergit ls-filesfails — which it always does when building from a release tarball rather than a git checkout, even thoughquarto-preview.jsis already committed to the tree. This adds an explicitQUARTO_SKIP_PREVIEW_BUILDopt-out so packagers can use the shipped build instead of triggering a spurious (and network-dependent) rebuild.package/scripts/vendoring/vendor.sh: thedeno installcalls that resolve quarto's TypeScript module graph have no way to enforce that resolution stays local to an already-populated cache. This addsQUARTO_VENDOR_LOCK(passes--lock=<path> --frozen) andQUARTO_VENDOR_OFFLINE=1(passes--cached-only) so a cache miss fails loudly instead of silently reaching out to the network.Both are additive, env-var-gated, and no-ops unless explicitly opted into — no change to existing default behavior.
Test plan
Verified end-to-end on macOS/arm64: a full
configure.sh+quarto-bld prepare-distrun against system-provideddeno/pandoc/typst/dart-sassplus from-sourceesbuild/deno_dom, withQUARTO_SKIP_PREVIEW_BUILD=1 QUARTO_VENDOR_OFFLINE=1and a pre-populatedDENO_DIR, completes with zero network fetches and produces a workingquarto.jsthat renders documents correctly (quarto checkall green,quarto renderproduces valid self-contained HTML).configure.shcompletes with 0 downloadsquarto-bld prepare-distcompletes with 0 downloadsquarto checkpassesquarto render hello.qmd --to htmlproduces correct output