Skip to main content

max / alloy

4.3 KB · 90 lines History Blame Raw
1 # Seeded font bases
2
3 The image cuts its two house faces from pinned upstream bases (`quasi-type`,
4 wiki `typography-standard`). The pins name files on raw.githubusercontent.com,
5 which rate-limits by IP, and a 429 there fails the whole build an hour in,
6 behind every expensive layer. Alloy's only install path is building the image
7 yourself, so a fetch that cannot run is an install that cannot run.
8
9 Anything dropped in this directory is copied into the `quasi-type` checkout's
10 own `bases/cache/` before the cut runs, which is the directory the tool reads
11 before it fetches anything. This `README.md` is skipped, and is what keeps the
12 directory in git.
13
14 ## What the seed covers
15
16 The two cuts the image runs, and nothing else. A build makes three requests to
17 that host: these two, and a third from shop's own build script, which cuts the
18 terminal's bundled face while `cargo install shop` runs. This directory
19 does not cover that third one: shop's build script passes its own `OUT_DIR` as
20 the cache directory, so there is no path for the image build to point at a
21 carried copy. Covering it with a seed needs a change in shop (read the cache
22 directory and the offline flag from the environment).
23
24 What covers all three without that change is the mirror. `QUASI_TYPE_MIRROR`,
25 set in the Containerfile to `https://makenot.work/static/bases`, is read inside
26 `quasi-type` itself, so it reaches the fetch this directory cannot. It is a
27 second source and not a carried copy: files are addressed by the sha256 the pin
28 already carries and verified against it, upstream stays the fallback, and
29 `sealed` still means the two cuts. A warm cargo target directory is what covers
30 the terminal's fetch on a host that has built once.
31
32 The rest of the build is not offline either, in any mode: it clones two
33 repositories, resolves crates.io, and installs packages.
34
35 ## The four files
36
37 Named exactly as `quasi-type` caches them:
38
39 atkinson-mono-2.001-AtkinsonHyperlegibleMono%5Bwght%5D.ttf
40 atkinson-mono-2.001-LICENSE.txt
41 atkinson-next-2.001-AtkinsonHyperlegibleNext%5Bwght%5D.ttf
42 atkinson-next-2.001-LICENSE.txt
43
44 Copy them from a warm checkout, `~/Code/Libraries/quasi-type/bases/cache/`, or
45 from any machine that has built the image once. Do not commit them: a font in a
46 repo is a second source of truth that nothing rebuilds, which is the same
47 reason the built faces are not committed either. `.gitignore` here says so.
48
49 The list above is what the pins name today. The build does not read it: it
50 derives the names from the pinned checkout's own `bases/pins.toml`, so a
51 `QUASI_TYPE_REV` bump that moves to a new base version asks for the new names
52 and this list is what goes stale.
53
54 Seeding cannot forge a base. Every cached file is checked against the pin's
55 sha256 exactly as a downloaded one is, so a wrong or tampered copy fails the
56 cut rather than shipping.
57
58 ## Using it
59
60 build/build-iso.sh --build-arg QUASI_BASES=sealed
61
62 `sealed` passes `--offline` to the cut, so the cut may not reach the network. If
63 the seed is short of a file the pins name, the build says which files before the
64 tool is compiled, rather than at the cut. Use it on a build host with a
65 warm cache. The default, `fetch`, uses whatever is seeded and downloads the
66 rest, which is what a stranger with an empty directory gets.
67
68 Keeping the bases outside the repo is possible with
69
70 podman build -v ~/Code/Libraries/quasi-type/bases/cache:/base-cache:ro .
71
72 The mount shadows this directory for the length of the build. Note what that
73 costs: `build/build-iso.sh` and `build/build-image.sh` forward `--build-arg` and
74 nothing else, so this route means driving `podman build` yourself, and a build
75 started that way carries no build stamp and reports its version as
76 `0.1 (Fedora 43)` (docs/IMAGE.md). Copying the files in here is the route that
77 works with the scripts.
78
79 ## What none of this is
80
81 A fix. It is a carried copy of two files and it goes stale the first time
82 `QUASI_TYPE_REV` moves. The durable answer is the mirror above: the same files
83 on infrastructure we own, addressed by the same sha256, so an unseeded build has
84 somewhere to reach that is not somebody else's rate limiter, and reached from
85 inside `quasi-type` so it covers shop's fetch too.
86
87 What the seed buys on top of the mirror is `sealed`: a cut that reaches no
88 network at all, which is the only way to prove the two faces came from the bytes
89 the pins name and nothing else.
90