Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 01 Nov 15:59
· 85 commits to main since this release
Immutable release. Only release title and notes can be modified.
f6e7cc7

Upgrading from v0.3.x

Upgrading has the steps. What an upgrade can change for a running box:

  • 32-bit executables are refused before launch.
  • io_uring is denied inside an app's sandbox.
  • soak 0 means no soak, where it meant the default of 15 s. keep 0 and watchdog_grace 0, which also meant the default, are now refused.
  • A root path holding a space, colon, backslash, quote or control character is refused when the config loads.
  • An oversized environment or command is refused at pre-flight.
  • An app's command runs byte for byte (#301): a $VAR in it reaches the app as written, no longer substituted.
  • An env or claim key that Caddy strips as @id is refused (#254), where it was silently dropped.
  • Each app has its own IPC and /dev/shm (#355): apps that talked to each other through them no longer can.
  • Redeploy each app after upgrading. The fix for a one-process app losing its grace reaches a running app only at its next start, so its first stop after the upgrade can still kill it at once.

What's Changed

  • docs: secrets are released in v0.3.1, and the upgrade example names it by @earthlingdavey in #247
  • fix(examples): make check's too-old refusal names no version (#234) by @earthlingdavey in #241
  • docs(triage): flag one-way and wide fixes for the person who merges by @earthlingdavey in #248
  • docs(box): bin/apply names all three step-6 children; an env_file the box does not hold is an accepted residual by @earthlingdavey in #243
  • build(make): secretscan scans the working tree in a git worktree, and the fixture allowlist matches both path forms (#234) by @earthlingdavey in #253
  • fix(build): hotserve version names hotserve's release ahead of Caddy's by @earthlingdavey in #250
  • fix(examples): box scripts read non-ASCII paths, and check names a silent failure by @earthlingdavey in #252
  • fix(liveswap): refuse env and claim keys that Caddy strips as "@id" (#242) by @earthlingdavey in #254
  • docs(upgrading): the upgrade reads the latest release, and a failed check stops before apt by @earthlingdavey in #249
  • fix(packaging): a postrm — purge removes the box's config, the starter's record and the applier's exchange tree by @earthlingdavey in #255
  • feat(liveswap): a deploy or rollback to the running version relaunches it, same artifact only (#234) by @earthlingdavey in #256
  • fix(box): step 6 refuses a push whose server would refuse the workflow's connection by @earthlingdavey in #258
  • feat(examples): a release per box — /HOTSERVE_VERSION picks the hotserve make check checks it with (#223) by @earthlingdavey in #257
  • docs: the config is a Caddyfile, and a JSON config is unsupported (#251) by @earthlingdavey in #259
  • fix(liveswap): app units run with LimitCORE=0, so a crash writes no dump of the app's memory (#234) by @earthlingdavey in #260
  • fix(box): step 6 refuses a push that moves where the box's server listens (#223) by @earthlingdavey in #262
  • fix(box): step 6 refuses request limits and a request_body a push cannot work with (#223) by @earthlingdavey in #263
  • feat(usage): the public ledger of what building hotserve costs (make usage) by @earthlingdavey in #261
  • build(deps): bump the actions group across 1 directory with 2 updates by @dependabot[bot] in #265
  • build(deps): bump the go-deps group across 3 directories with 3 updates by @dependabot[bot] in #266
  • build(deps): bump python from 3.13-slim to 3.14-slim in the compose-images group by @dependabot[bot] in #264
  • fix(lint): readOwnFile tells a link from a loop with Readlink, so gosec's G703 no longer flakes the liveswap lint lane by @earthlingdavey in #269
  • fix(box): the upload's bound is the handler's own on the body, not the connection's deadline alone (#223) by @earthlingdavey in #268
  • fix(box): step 6 refuses a timeouts directive whose read settings would cut a push's upload (#223) by @earthlingdavey in #267
  • docs(box): the secrets caps are confirmed, no longer proposed by @earthlingdavey in #270
  • docs(hardening): step 4, Debian's updates on their own, with no automatic reboot (#223) by @earthlingdavey in #280
  • docs(box): no migration steps for box repositories from before v0.3.1; the tutorial links to the secrets commands (#272) by @earthlingdavey in #281
  • docs(liveswap): accept a host that refuses the sandbox failing at step 3, not step 2 (#274) by @earthlingdavey in #282
  • docs(box): init's lines refuse a placeholder left in the commit (#273) by @earthlingdavey in #283
  • feat(examples): deploy.sh names HOTSERVE_RUNS_ON when the box refuses a release's architecture (#277) by @earthlingdavey in #285
  • feat(examples): the apply job's summary says what an applied push did (#272) by @earthlingdavey in #286
  • docs(liveswap): a Node app that listens on PORT runs unchanged with env PORT {socket} (#279) by @earthlingdavey in #287
  • feat(examples): make signer speaks of a running box only when it added you to one (#279) by @earthlingdavey in #288
  • refactor(box): no handling for releases and templates from before v0.3.1 (#272) by @earthlingdavey in #290
  • docs(first-deploy): say why commits are signed before step 1 (#279) by @earthlingdavey in #284
  • refactor(packaging): no handling for packages from before v0.3.1 (#272) by @earthlingdavey in #291
  • fix(liveswap): a status that shows a restarted instance shows its restart; box test stubs run under the box's deadline (#289) by @earthlingdavey in #292
  • fix(liveswap): a unit's command execs byte for byte, with no $VAR substitution (#295) by @earthlingdavey in #301
  • docs: the remaining doc-vs-code rows from the 2026-09-25 review (#294) by @earthlingdavey in #302
  • fix(liveswap): explicit 0 in the Caddyfile, pre_start outlives the request (#295) by @earthlingdavey in #304
  • fix(deploytrust): bound the JWKS refetch and the local token's lifetime (#296) by @earthlingdavey in #303
  • build(deps): bump the go-deps group across 2 directories with 1 update by @dependabot[bot] in #322
  • fix(liveswap): a prune or a deploy never goes through a link under the root (#300) by @earthlingdavey in #293
  • docs(liveswap): a bind mount's source must be the app's own (#308) by @earthlingdavey in #309
  • fix(liveswap): pre-flight on every relaunch, Destruct waits for a deploy, the watchdog waits for a deploy's end (#297) by @earthlingdavey in #314
  • fix(liveswap): no io_uring ring and no x86-32 ABI in an app unit (#298) by @earthlingdavey in #312
  • fix(liveswap): releases ordered by deploy time; no prune through a linked app dir (#299) by @earthlingdavey in #310
  • fix(box): no io_uring ring and no x86-32 ABI in the applier unit (#313) by @earthlingdavey in #329
  • fix(box): step 6's validate refusal keeps the reason, not the head of Caddy's module chain (#324) by @earthlingdavey in #330
  • docs: the app-dir claim, the liveswap file tables, the triage skill's "newest five" (#320) by @earthlingdavey in #328
  • docs(liveswap): the no-link rules give today's reason, not a pre-sandbox upgrade's by @earthlingdavey in #331
  • fix(box): GET / answers 409 when the box runs a file the walk refuses (#325) by @earthlingdavey in #332
  • fix(box): GET / names the no-signer way back, as a push does (#325) by @earthlingdavey in #334
  • fix(liveswap): seccomp proven in force, by the capability probe and in the lanes (#316) by @earthlingdavey in #333
  • docs(liveswap): soak 0 needs a health_path, for good (#305) by @earthlingdavey in #335
  • fix(liveswap): a hotserve restart mid-deploy leaves the migration to finish and the version deployable (#317, #318) by @earthlingdavey in #336
  • fix(deploytrust): no token waits on an issuer; an 8 KiB token cap (#306) by @earthlingdavey in #337
  • ci(usage): every job logs its runner's specs, region and CPU time by @earthlingdavey in #338
  • docs: deploying from outside GitHub — any OIDC issuer, GitLab, or a key (#221) by @earthlingdavey in #339
  • docs(hardening): kernel modules no app needs, as the operator's step (#315) by @earthlingdavey in #340
  • feat(liveswap): per-app resource caps — memory_max, tasks_max, cpu_quota (#71) by @earthlingdavey in #345
  • docs: questions, bugs and ideas start in Discussions by @earthlingdavey in #348
  • fix(liveswap): sibling IPC closed — PrivateIPC=, a /dev/shm of the unit's own, one Exec*= per unit (#311) by @earthlingdavey in #355
  • build(deps): bump the compose-images group with 2 updates by @dependabot[bot] in #359
  • build(deps): bump github.com/darkweak/storages/otter/caddy from 0.0.20 to 0.0.22 in the go-deps group across 1 directory by @dependabot[bot] in #360
  • ci: runners off the eMudhra-trusting roots — a ca-certificates floor, Node on the system store, a ca-trust check by @earthlingdavey in #361
  • build(deps): bump github.com/go-chi/chi/v5 to v5.4.0 in /, /liveswap and /penaltybox by @earthlingdavey in #362
  • fix(packaging): the package's messages name the command, not sudo (#323) by @earthlingdavey in #365
  • docs(liveswap): run as the hotserve user with runuser, not sudo -u by @earthlingdavey in #366
  • docs: the snippets parse, an upgrade's cost is stated once, and the audience has one story by @earthlingdavey in #374
  • docs(liveswap): the temp-file cleanup goes by name alone, accepted by @earthlingdavey in #375
  • docs(deno): the install stops at a failed checksum by @earthlingdavey in #379
  • fix(liveswap): every unit keeps a sibling process, so systemd 257 waits a one-process app's grace (#380) by @earthlingdavey in #381
  • fix(liveswap): a unit whose file a reload cannot read back stays tracked, and the inputs that make one are refused (#380) by @earthlingdavey in #382

Full Changelog: v0.3.1...v0.4.0