feat: contact form backend for linux and freebsd servers
Test / test (push) Successful in 2m1s
Release / gates (push) Successful in 1m57s
Release / build (amd64, freebsd) (push) Successful in 1m26s
Release / build (amd64, linux) (push) Successful in 1m30s
Release / build (arm64, freebsd) (push) Successful in 1m28s
Release / build (arm64, linux) (push) Successful in 1m49s
Release / build (loong64, linux) (push) Successful in 1m30s
Release / build (riscv64, linux) (push) Successful in 1m29s
Release / release (push) Successful in 41s
Test / test (push) Successful in 2m1s
Release / gates (push) Successful in 1m57s
Release / build (amd64, freebsd) (push) Successful in 1m26s
Release / build (amd64, linux) (push) Successful in 1m30s
Release / build (arm64, freebsd) (push) Successful in 1m28s
Release / build (arm64, linux) (push) Successful in 1m49s
Release / build (loong64, linux) (push) Successful in 1m30s
Release / build (riscv64, linux) (push) Successful in 1m29s
Release / release (push) Successful in 41s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# Development
|
||||
|
||||
How to work on nuntius.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Go 1.27.1, the version recorded in `go.mod`, the newest stable release.
|
||||
- [just](https://github.com/casey/just) for the recipes.
|
||||
- gcc for `just gates`: the race detector needs cgo.
|
||||
|
||||
Nothing else. There is no Node, no Python, and no third-party Go module
|
||||
beyond the first-party [`interpres`](https://sourcedock.dev/petrbalvin/interpres)
|
||||
TOML parser.
|
||||
|
||||
## Setup
|
||||
|
||||
```sh
|
||||
git clone https://sourcedock.dev/petrbalvin/nuntius.git
|
||||
cd nuntius
|
||||
just build
|
||||
```
|
||||
|
||||
Configuration lives in TOML, read from `/etc/nuntius/config.toml` by
|
||||
default; the `NUNTIUS_CONFIG` environment variable points the server at any
|
||||
file you like, which keeps development free of root-owned paths:
|
||||
|
||||
```sh
|
||||
export NUNTIUS_CONFIG=./config.toml
|
||||
export NUNTIUS_SMTP_PASSWORD=admin # the placeholder the template references
|
||||
just run # first start writes the starter config
|
||||
```
|
||||
|
||||
The starter forms point at example.com addresses, so submissions return
|
||||
`500 send_failed` until `config.toml` carries real SMTP settings; strict
|
||||
environment expansion means every `${VAR}` the config references must be set
|
||||
before startup.
|
||||
|
||||
## Recipes
|
||||
|
||||
Every recipe in the project's file, taken from the file itself:
|
||||
|
||||
| Recipe | What it does |
|
||||
|--------|--------------|
|
||||
| `just default` | prints the recipe list |
|
||||
| `just build` | `CGO_ENABLED=0 go build -trimpath -buildvcs=true -ldflags "-s -w"` into `bin/nuntius` |
|
||||
| `just test` | the suite with no test cache, then the 80 % coverage floor over `./internal/...` |
|
||||
| `just race` | the same suite under the race detector |
|
||||
| `just unit` | fast scoped run for iterating: cached, no race, no coverage |
|
||||
| `just fuzz` | time-boxed fuzz of one target in one package |
|
||||
| `just bench` | benchmarks |
|
||||
| `just fmt` | `gofmt -w .` |
|
||||
| `just fmt-check` | zero gofmt diff; prints nothing when everything is formatted |
|
||||
| `just vet` | `go vet ./...` and `go fix -diff ./...` |
|
||||
| `just gates` | build, fmt-check, vet, test, race: the definition of done, once per task |
|
||||
| `just clean` | removes `bin/` and `coverage.out` |
|
||||
| `just install` | builds, then copies the binary into `~/.local/bin` (override with `BINDIR`) |
|
||||
| `just uninstall` | removes the installed binary |
|
||||
| `just run` | `go run -buildvcs=true ./cmd/server` |
|
||||
| `just dev` | the same as `run`: nuntius carries no watch or reload tool |
|
||||
| `just coverage-html` | HTML coverage report from the gate's profile; an extension, not a gate |
|
||||
|
||||
The test, race, unit and fuzz recipes run under a cgroup memory fence, so a
|
||||
runaway test dies at the ceiling instead of eating the machine.
|
||||
|
||||
## Running a single test
|
||||
|
||||
```sh
|
||||
go test -run TestName ./internal/handler/
|
||||
```
|
||||
|
||||
Add `-v` for the sub-test names, and `-race` when the change touches
|
||||
concurrency. `-count=1` defeats the test cache when a result looks stale;
|
||||
`just unit` keeps the cache on purpose, because a scoped iterating run wants
|
||||
to be instant.
|
||||
|
||||
## Coverage
|
||||
|
||||
```sh
|
||||
just test
|
||||
go tool cover -func=coverage.out
|
||||
```
|
||||
|
||||
The `total:` line is the number that matters, and it stays at 80 percent or
|
||||
more. Coverage is measured over the logic packages only; `cmd/server` is
|
||||
thin glue around them. For the HTML map:
|
||||
|
||||
```sh
|
||||
just coverage-html
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
```sh
|
||||
just bench
|
||||
```
|
||||
|
||||
Benchmark on an idle machine, and compare only runs made in one process
|
||||
against each other: runs in separate processes, or on a loaded machine,
|
||||
differ by more than the effects being measured.
|
||||
|
||||
## Fuzzing
|
||||
|
||||
Two fuzz targets exist: `FuzzValidate` in `internal/contactform` and
|
||||
`FuzzLoadConfig` in `internal/config`. They are exploration, never a gate;
|
||||
time-box one explicitly:
|
||||
|
||||
```sh
|
||||
just fuzz FuzzValidate ./internal/contactform 30s
|
||||
```
|
||||
|
||||
## Debugging the build
|
||||
|
||||
```sh
|
||||
go build -gcflags='-m' ./... # inlining decisions
|
||||
go build -gcflags='-S' ./... # what the compiler generated
|
||||
```
|
||||
|
||||
## Continuous integration
|
||||
|
||||
Workflows live in `.gitea/workflows/` and run on the project's own runners.
|
||||
They are written by hand rather than through `just`, but they enforce the
|
||||
same set of gates, so a green `just gates` locally is the fastest way to a
|
||||
green pipeline. The per-workflow table is in
|
||||
[CONTRIBUTING.md](../CONTRIBUTING.md).
|
||||
|
||||
## Releases
|
||||
|
||||
Releases are cut by merging `development` into `main` and tagging `vX.Y.Z`.
|
||||
The tag drives the release workflow, which builds the assets and publishes
|
||||
the notes it extracted from `CHANGELOG.md`.
|
||||
Reference in New Issue
Block a user