Release / build (amd64, freebsd) (push) Successful in 1m0s
Release / build (amd64, linux) (push) Successful in 1m1s
Release / build (arm64, freebsd) (push) Successful in 57s
Release / build (arm64, linux) (push) Successful in 58s
Release / build (loong64, linux) (push) Successful in 1m3s
Release / build (riscv64, freebsd) (push) Successful in 56s
Release / build (riscv64, linux) (push) Successful in 1m0s
Release / release (push) Failing after 20s
5.0 KiB
5.0 KiB
Changelog
All notable changes to nuntius are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
development
1.1.0 — 2026-07-26
Added
- RISC-V and LoongArch builds — CI now produces binaries for
linux/riscv64,linux/loong64, andfreebsd/riscv64in addition to the existing four targets. - 80 % coverage gate —
just testand CI enforce ≥ 80 % test coverage oninternal/andpkg/packages. - Handler and email test suites — 22 handler tests covering CORS, rate limiting, validation, honeypot, and send/store paths via mock interfaces. 12 email composition tests covering all four form types.
Changed
- Module migrated to sourcedock.dev — all imports and documentation now
reference
sourcedock.dev/petrbalvin/nuntius. - CI migrated from Forgejo to Gitea — workflows now live in
.gitea/workflows/, run on thefedorarunner, and use the standardactions/*short form. - Dependency bump —
interpresupdated to v1.1.1. - IPv6-first — the server now binds
[::]:portfor explicit dual-stack. - Installer rewritten in Python —
install.pyreplacesinstall.sh. - nginx → Caddy — all documentation and the installer now use Caddy as the recommended reverse proxy.
Fixed
- Rate limiter memory leak — a periodic cleanup goroutine removes expired IP entries from the token-bucket map.
- Silent template errors —
compose()now produces a fallback HTML message instead of silently discarding template execution errors. - Silent JSON encoding errors — all
json.NewEncoder(w).Encode()calls now log errors instead of discarding them. - CI formatting gate —
gofmt -lin the test workflow now actually fails when it finds unformatted files. - Missing
just fmtrecipe — addedgofmt -wtarget. - Copyright headers — added to all Go and Python source files.
- Smoke test restricted to native builds — cross-compiled binaries now skip the smoke test step since they cannot execute on the Linux amd64 CI runner.
1.0.0 — 2026-06-20
First stable release of nuntius: a small, opinionated, modular contact form backend written in Go. A single static binary, four form kinds out of the box, SMTP delivery, a JSONL newsletter log, strict TOML configuration, and env-var secrets. Its only dependency outside the standard library is the first-party interpres
Added
- Server —
cmd/server, the HTTP entry point.http.Serverwith explicitReadHeaderTimeout(10 s),ReadTimeout(15 s),WriteTimeout(30 s), andIdleTimeout(60 s). Graceful shutdown onSIGINT/SIGTERMwith a 15 s budget. Structured logging vialog/slog(JSON handler, INFO level, stdout) with one log line per request.GET /healthendpoint.--versionflag. - Four form kinds —
contact,feedback,newsletter, andgeneric, each with its own endpoint, per-IP rate limit, CORS allowlist, and honeypot field. OnePOST+ oneOPTIONShandler per form on a freshhttp.ServeMux. - SMTP delivery — stdlib
net/smtpwithPLAINauth,multipart/alternativeHTML + plain text bodies, one dedicated template per form type. - Newsletter JSONL log — append-only
data_dir/newsletter-<name>.jsonlwith crash-safeO_APPENDwrites;CountandListskip malformed lines. pkg/contactform— public Go package withRequest/Response/FieldError/ErrorResponsetypes and aValidatefunction for all four form types.- Per-IP rate limiting — in-memory token bucket per form, configurable per hour.
- Per-form honeypot — silent 200 on bot fill, no mail, no subscriber line.
- Per-form CORS — allowlist enforced on preflight and actual requests, with
echoed
Access-Control-Allow-Origin+Vary: Origin. - TOML configuration — parsed by the first-party
interpreslibrary, with strict unknown-field rejection and per-type validation that fails loud on typos at startup. - Env-var secrets —
${VAR_NAME}/$VAR_NAMEexpansion before the config is parsed, so SMTP passwords never live in the file. - Auto-generated config — a three-form TOML template is written to
/etc/nuntius/config.tomlon first start. - systemd unit — installed inline from
docs/deployment.mdwithRestart=on-failureandEnvironmentFile=. - Install script —
install.py, idempotent, handles user creation, config generation, and secrets file mode0600. - docs/ —
architecture.md,configuration.md,api-reference.md,deployment.md,security.md,library-usage.md.