The 2026-10-12 OOM killed the host, not the service: sowerd had no memory
ceiling anywhere while the sower client has had SOWER_MEMORY_LIMIT_MB since
d0031e4. Put a GOMEMLIMIT on the unit the installer writes and on the
packaged unit, so a runaway heap degrades sowerd instead of OOM-killing the
machine it runs on. kr already carries the same value through a drop-in.
Every published artifact was stamped `vcs.modified=true` with module version
`+dirty` (verified on v1.6.1, v1.6.2 and v1.7.0): the packaging step copies
`.github/sower.toml` and the service files into the repository root, and the
toolchain records the worktree state at build time. sowerd.service is neither
tracked nor ignored, so the tree was dirty before the compiler ran. Kr's edge
deployment rule ("confirm vcs.modified=false") was therefore unsatisfiable
from a release artifact, and the binary could not be held to any commit.
Move the copies and the tarball into a Package step that runs after the build.
Verified locally: building this commit on a clean tree reports `v1.7.0` with
vcs.modified=false, while copying one service file in first reproduces
`v1.7.0+dirty` — the same experiment the next tag re-runs end to end.
Installing sower meant grabbing a tarball and wiring the service up by hand,
and the packaged unit was too fragile for something a resolver depends on
(on-failure restart after 1min, no memory limit).
Add install.sh: detects the platform and init system, installs or upgrades
the binary atomically, keeps an existing config, verifies the release
SHA256SUMS unless explicitly opted out, and registers the service on systemd,
OpenWrt procd or macOS launchd. Every network call carries an explicit
timeout, the OpenWrt init script ships in Linux tarballs, the release
workflow generates SHA256SUMS, the README documents the installer, and
make test syntax-checks the scripts.
The default 128 MiB soft memory limit sits below the ~105 MB live heap the
full pexcn rule sets build, so the GC goal gets pinned to the live heap and
every allocation triggers a full-heap mark: measured 39% CPU on an otherwise
idle gateway with a GC cycle every 300-500 ms.
Raise the default to 512 MiB, resolve the limit in a testable helper that
covers GOMEMLIMIT/override/disable precedence, and declare the same value in
the packaged service plus the example configs so a deployment can tune it
without a rebuild.
matrix.service lists space-separated file names ("sower.service
sowerd.service"), but the .github/ prefix only applied to the first,
so every Linux job failed with 'cannot stat sowerd.service' in
Prepare packaging files. Broken since 1e44871; first exercised by
the v1.6.0 tag. Loop over the list and prefix each file individually.
- replace hand-rolled make build loop with a strategy.matrix across 11
targets: linux (amd64, arm64, armv7, riscv64, loong64, mips, mipsle),
darwin (amd64, arm64), windows (amd64, arm64)
- add dedicated web job so the admin console is built once and reused
- aggregate all tarballs in a single release job to avoid concurrent
release edits from matrix jobs
- drop stale sower.yaml references (config is TOML-only) and the
bun-less make build that would fail on runners