Utensil's Hugo blog for math, tech and thoughts utensil.tngl.sh/blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

retire(blog): drop scripts/{freeze,setup-freeze-env}.sh + freeze-era docs

The freeze model is fully retired on both CI lanes:
- .github/workflows/gh-pages.yml renders Julia LIVE (julia-actions/setup-julia
+ xvfb-run quarto/hugo); see git history at fb831a1.
- .tangled/workflows/render.yml renders Julia LIVE off the R2-distributed
depot + render-env closure (see .tangled/workflows/build-depot.yml).

Neither lane reads scripts/freeze.sh or scripts/setup-freeze-env.sh any more,
and the referenced .github/workflows/freeze.yml is gone. Drop the dead scripts
+ rewrite scripts/README.md to document the actual two-lane flow; update the
stale 'tangled renders Julia-free' comment in _quarto.yml.

+16 -244
+3 -2
_quarto.yml
··· 8 8 9 9 execute: 10 10 warning: false 11 - # Reuse committed _freeze/ instead of re-executing (e.g. Julia) on every render. 12 - # Freeze is refreshed via scripts/freeze.sh; tangled renders Julia-free off it. 11 + # `freeze: auto` only short-circuits local re-renders when sources are 12 + # unchanged. Both CI lanes (gh-pages.yml on GH Actions, render.yml on tangled 13 + # Spindle) execute Julia LIVE — neither relies on a committed `_freeze/`. 13 14 freeze: auto 14 15 15 16 # # supppress HTML output
+13 -37
scripts/README.md
··· 7 7 - `make_changed.sh` / `dev.sh` — incremental rebuild + live preview (watchexec). 8 8 - `install_pikchr.sh`, `install_typst_ts_cli.sh` — fetch the diagram binaries. 9 9 10 - ## How to refresh the freeze 11 - 12 - The `ca-in-julia` post executes Julia (GLMakie animations), which is too heavy 13 - for tangled's short, no-cache CI. So we **freeze** that execution: Quarto's 14 - `_freeze/` cache (plus the generated `index.md` and `*.mp4`) is committed, and 15 - tangled does a Julia-**free** `quarto render` that reuses it (`freeze: auto` in 16 - `_quarto.yml`). 17 - 18 - Refresh the freeze whenever you change a Julia-touching post (its `.qmd`, 19 - `Project.toml`, or `Manifest.toml`): 20 - 21 - 1. Once per machine, prepare the toolchain (idempotent): 22 - ```sh 23 - ./scripts/setup-freeze-env.sh 24 - ``` 25 - Installs pinned Julia 1.10.3 (juliaup) + the post's deps, and checks/installs 26 - Quarto 1.5.39, Hugo 0.125.2, and the diagram tools (d2, pikchr, typst-ts-cli). 27 - It prints anything it can't auto-install. 28 - 29 - 2. Before committing the change, regenerate the freeze: 30 - ```sh 31 - ./scripts/freeze.sh 32 - ``` 33 - On macOS GLMakie uses the real display. On headless Linux run it under xvfb: 34 - `xvfb-run -a ./scripts/freeze.sh`. 10 + ## How the blog is rendered 35 11 36 - 3. Commit the result (generated media is gitignored, so force-add it): 37 - ```sh 38 - git add _freeze/ 39 - git add -f content/posts/ca-in-julia/index.md \ 40 - content/posts/ca-in-julia/lorenz.mp4 \ 41 - content/posts/ca-in-julia/streamplot.mp4 42 - ``` 12 + Two independent lanes, no cross-deps: 43 13 44 - GitHub Actions does the same automatically: the **Refresh Quarto Freeze** 45 - workflow (`.github/workflows/freeze.yml`) runs on `workflow_dispatch`, on push 46 - to the `freeze` branch, and when a `.qmd` / `Project.toml` / `Manifest.toml` 47 - changes — it commits "chore(blog): refresh Quarto freeze" and pushes. 14 + - **github.io lane** — `.github/workflows/gh-pages.yml` does a LIVE render on 15 + GitHub Actions (`julia-actions/setup-julia` + `xvfb-run quarto/hugo`) and 16 + publishes to `https://utensil.github.io/blog/`. 17 + - **tngl.sh lane** — `.tangled/workflows/{build-depot,render}.yml` runs on 18 + tangled's Spindle: `build-depot.yml` pre-builds the precompiled Julia depot 19 + + render-env closure (nix flake at repo root) and uploads to Cloudflare R2; 20 + `render.yml` pulls them via `manifest.json` and renders LIVE under Xvfb, 21 + publishing to the `site` branch → `https://utensil.tngl.sh/blog/`. 48 22 49 - **Tangled never runs Julia.** It only renders off the committed `_freeze/`. 23 + No freeze step is needed any more — the `ca-in-julia` Julia post executes on 24 + both lanes, and `_freeze/` is no longer relied upon. Quarto's `freeze: auto` 25 + remains on (in `_quarto.yml`) for cheap local re-renders only.
-52
scripts/freeze.sh
··· 1 - #!/bin/bash 2 - # Shared, env-agnostic freeze step. 3 - # 4 - # Renders diagrams + executes the Quarto project (incl. the Julia post) so that 5 - # Quarto writes its `_freeze/` cache and the generated media. Tangled later does 6 - # a Julia-FREE `quarto render` reusing this committed `_freeze/` (freeze: auto). 7 - # 8 - # This script installs NOTHING. Prepare the toolchain first with 9 - # scripts/setup-freeze-env.sh (locally) or the freeze.yml workflow (CI). 10 - # 11 - # Usage: 12 - # ./scripts/freeze.sh # macOS / display present 13 - # xvfb-run -a ./scripts/freeze.sh # headless Linux (GLMakie needs OpenGL) 14 - set -euo pipefail 15 - 16 - SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) 17 - PROJECT_ROOT="$SCRIPT_DIR/.." 18 - cd "$PROJECT_ROOT" 19 - 20 - echo "==> Building diagrams (pikchr / d2 / typst)" 21 - ./scripts/make_all.sh 22 - 23 - echo "==> Rendering Quarto project (executes Julia, writes _freeze/ + media)" 24 - quarto render . 25 - 26 - echo "==> _freeze/ status" 27 - if [ -d _freeze ]; then 28 - git status --short -- _freeze/ || true 29 - echo " _freeze/ tracked files: $(git ls-files _freeze/ | wc -l | tr -d ' ')" 30 - else 31 - echo " WARNING: _freeze/ was not created by quarto render" 32 - fi 33 - 34 - # All generated artifacts are gitignored; tangled reuses them (no Julia / typst 35 - # / d2 / pikchr toolchain there), so they MUST be force-added when freezing. 36 - ARTIFACTS=( 37 - content/posts/ca-in-julia/index.md 38 - content/posts/ca-in-julia/lorenz.mp4 39 - content/posts/ca-in-julia/streamplot.mp4 40 - content/posts/transformer/transformer_layer.d2.svg 41 - content/posts/transformer/transformer_layer.pikchr.svg 42 - content/posts/typst-test/fibonacci.artifact.svg 43 - content/posts/typst-test/example.artifact.svg 44 - content/posts/typst-test/fibonacci.pdf 45 - content/posts/typst-test/example.pdf 46 - ) 47 - 48 - echo "==> Generated artifact status (gitignored; commit with: git add -f <path>)" 49 - git status --short --ignored -- "${ARTIFACTS[@]}" || true 50 - 51 - echo "Done. Review changes, then:" 52 - echo " git add _freeze/ && git add -f ${ARTIFACTS[*]}"
-153
scripts/setup-freeze-env.sh
··· 1 - #!/bin/bash 2 - # Prepare the toolchain so scripts/freeze.sh runs fast. Idempotent: 3 - # detect-then-install. Designed for local macOS use (operator) but also 4 - # works on Ubuntu CI (freeze.yml). 5 - # 6 - # Pinned versions match .github/workflows/gh-pages.yml: 7 - # Julia 1.10.3 | Quarto 1.5.39 | Hugo 0.125.2 (extended) | typst-ts-cli v0.4.1 8 - # 9 - # After this finishes, run: ./scripts/freeze.sh (xvfb-run -a on headless Linux) 10 - set -euo pipefail 11 - 12 - SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) 13 - PROJECT_ROOT="$SCRIPT_DIR/.." 14 - cd "$PROJECT_ROOT" 15 - 16 - JULIA_VERSION="1.10.3" 17 - QUARTO_VERSION="1.5.39" 18 - HUGO_VERSION="0.125.2" 19 - 20 - MISSING_MANUAL=() 21 - 22 - have() { command -v "$1" >/dev/null 2>&1; } 23 - 24 - is_mac() { [ "$(uname -s)" = "Darwin" ]; } 25 - 26 - # --------------------------------------------------------------------------- 27 - # Julia 1.10.3 via juliaup 28 - # --------------------------------------------------------------------------- 29 - echo "==> Julia $JULIA_VERSION (juliaup)" 30 - if ! have juliaup; then 31 - echo " juliaup not found; installing" 32 - if is_mac && have brew; then 33 - brew install juliaup 34 - else 35 - curl -fsSL https://install.julialang.org | sh -s -- --yes 36 - export PATH="$HOME/.juliaup/bin:$PATH" 37 - fi 38 - fi 39 - 40 - if have juliaup; then 41 - juliaup add "$JULIA_VERSION" || true 42 - juliaup default "$JULIA_VERSION" || true 43 - else 44 - MISSING_MANUAL+=("juliaup/julia $JULIA_VERSION — install from https://github.com/JuliaLang/juliaup") 45 - fi 46 - 47 - # --------------------------------------------------------------------------- 48 - # Julia project deps for the ca-in-julia post 49 - # --------------------------------------------------------------------------- 50 - if have julia; then 51 - echo "==> Instantiate + precompile content/posts/ca-in-julia (Julia $JULIA_VERSION)" 52 - julia +"$JULIA_VERSION" --project=content/posts/ca-in-julia \ 53 - -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()' \ 54 - || julia --project=content/posts/ca-in-julia \ 55 - -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()' 56 - else 57 - echo " Skipping Julia instantiate (julia not on PATH yet — re-run after juliaup PATH is active)" 58 - fi 59 - 60 - # --------------------------------------------------------------------------- 61 - # Quarto 1.5.39 62 - # --------------------------------------------------------------------------- 63 - echo "==> Quarto $QUARTO_VERSION" 64 - if have quarto; then 65 - echo " found: $(quarto --version)" 66 - else 67 - if is_mac && have brew; then 68 - brew install --cask quarto 69 - echo " NOTE: brew installs latest Quarto, not pinned $QUARTO_VERSION." 70 - echo " For an exact pin, download from https://github.com/quarto-dev/quarto-cli/releases/tag/v$QUARTO_VERSION" 71 - else 72 - MISSING_MANUAL+=("quarto $QUARTO_VERSION — https://github.com/quarto-dev/quarto-cli/releases/tag/v$QUARTO_VERSION") 73 - fi 74 - fi 75 - 76 - # --------------------------------------------------------------------------- 77 - # Hugo 0.125.2 (extended) 78 - # --------------------------------------------------------------------------- 79 - echo "==> Hugo $HUGO_VERSION (extended)" 80 - if have hugo; then 81 - echo " found: $(hugo version)" 82 - else 83 - if is_mac && have brew; then 84 - brew install hugo 85 - echo " NOTE: brew installs latest Hugo, not pinned $HUGO_VERSION." 86 - else 87 - MISSING_MANUAL+=("hugo $HUGO_VERSION extended — https://github.com/gohugoio/hugo/releases/tag/v$HUGO_VERSION") 88 - fi 89 - fi 90 - 91 - # --------------------------------------------------------------------------- 92 - # Diagram tools: d2, pikchr, typst-ts-cli 93 - # --------------------------------------------------------------------------- 94 - echo "==> d2" 95 - if have d2; then 96 - echo " found: $(d2 --version 2>/dev/null || echo present)" 97 - elif have brew; then 98 - brew install d2 99 - else 100 - MISSING_MANUAL+=("d2 — curl -fsSL https://d2lang.com/install.sh | sh -s --") 101 - fi 102 - 103 - echo "==> pikchr (built via scripts/install_pikchr.sh into ../pikchr-cmd)" 104 - # install_pikchr.sh clones zenomt/pikchr-cmd and `make all`; needs git + make + cc. 105 - if have make && have cc && have git; then 106 - ./scripts/install_pikchr.sh || MISSING_MANUAL+=("pikchr — scripts/install_pikchr.sh failed; build zenomt/pikchr-cmd manually") 107 - else 108 - MISSING_MANUAL+=("pikchr — needs git+make+cc, then run scripts/install_pikchr.sh") 109 - fi 110 - 111 - TTC_HINT="v0.4.1" 112 - echo "==> typst-ts-cli $TTC_HINT (make_single.sh calls bare 'typst-ts-cli' on PATH)" 113 - if have typst-ts-cli; then 114 - echo " found on PATH" 115 - elif have cargo; then 116 - echo " installing via cargo (matches gh-pages.yml)" 117 - cargo install --locked --git https://github.com/Myriad-Dreamin/typst.ts typst-ts-cli \ 118 - || MISSING_MANUAL+=("typst-ts-cli — cargo install failed; see scripts/install_typst_ts_cli.sh for prebuilt $TTC_HINT") 119 - else 120 - MISSING_MANUAL+=("typst-ts-cli $TTC_HINT — either 'cargo install --git https://github.com/Myriad-Dreamin/typst.ts typst-ts-cli', or run scripts/install_typst_ts_cli.sh and add ../typst-ts/typst-ts/bin to PATH") 121 - fi 122 - 123 - # --------------------------------------------------------------------------- 124 - # Python deps (Quarto/Hugo helpers per gh-pages.yml requirements.txt) 125 - # --------------------------------------------------------------------------- 126 - if [ -f requirements.txt ]; then 127 - echo "==> Python deps (requirements.txt)" 128 - if have pip; then 129 - pip install -r requirements.txt || MISSING_MANUAL+=("python deps — pip install -r requirements.txt failed") 130 - elif have pip3; then 131 - pip3 install -r requirements.txt || MISSING_MANUAL+=("python deps — pip3 install -r requirements.txt failed") 132 - else 133 - MISSING_MANUAL+=("python deps — pip not found; pip install -r requirements.txt") 134 - fi 135 - fi 136 - 137 - # --------------------------------------------------------------------------- 138 - # Summary 139 - # --------------------------------------------------------------------------- 140 - echo "" 141 - if [ ${#MISSING_MANUAL[@]} -eq 0 ]; then 142 - echo "==> Environment ready. Next: ./scripts/freeze.sh" 143 - else 144 - echo "==> Environment mostly ready, but install these MANUALLY:" 145 - for item in "${MISSING_MANUAL[@]}"; do 146 - echo " - $item" 147 - done 148 - echo " Then: ./scripts/freeze.sh" 149 - fi 150 - 151 - if ! is_mac; then 152 - echo " (Headless Linux: GLMakie needs OpenGL — run freeze via 'xvfb-run -a ./scripts/freeze.sh')" 153 - fi