docs/user-guide.md — magic-link sign-in, note basics, wikilink syntax, keyboard shortcuts, offline behaviour, and privacy notes (sessionStorage for tokens, tenant-scoped localStorage). docs/self-hosting.md — system requirements, Docker Compose quick-start, the full LIBRENOTES_* env-var matrix (which are required, which conditional), reverse proxy snippets for Caddy and nginx, volume layout, the in-binary healthcheck, and update/rollback procedure. docs/api.md — every public endpoint: auth (login/verify), notes CRUD, /api/whoami, /healthz. Status codes per endpoint, the optimistic-locking ?base=<unix> contract for PUT/DELETE, note-ID regex, and the rate-limit policy. CONTRIBUTING.md — dev setup (Nix flake .#dev, plain Go, Docker), package layout overview, coding standards (one-way dep flow, tenant FS gateway requirement), branch naming, commit format, and the PR process. Also points security reports at security@librete.ch rather than public issues. Closes #29. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.6 KiB
Contributing
Thank you for your interest in librenotes. This document covers the developer workflow: setup, conventions, commit messages, and how to land a pull request.
Code of conduct
Participation in this project is governed by the Contributor Covenant 2.1. Please read it before opening issues or PRs.
Development setup
The fastest path is the Nix flake. The dev shell drops you
into a working Go toolchain without any sandbox wrapping:
git clone ssh://tengo@git.librete.ch:41240/public/librenotes.git
cd librenotes
nix develop .#dev
make build && make test
If you don't use Nix:
- Install Go 1.22 or later.
- Install
make,git. - Optional:
staticcheck(Go),sqlite3(for backup tooling).
A Docker-based dev environment also exists:
docker build -f Dockerfile.dev -t librenotes-dev .
docker run --rm -it -v "$PWD:/workspace" librenotes-dev
See the README for the full layout. In short:
cmd/librenotes/ Binary entry + serve cmd + frontend assets
internal/auth/ Magic-link auth + JWT
internal/storage/ SQLite + user model
internal/tenant/ Per-user filesystem sandbox
internal/httpapi/ Routes, middleware, notes CRUD
internal/notesium/ Forked Notesium core (notes engine)
docs/ User-facing docs (this guide, ops, api, ...)
scripts/ Backup, prune, restore tools
Coding standards
- Match the existing style. We don't have a custom linter beyond
go vet;gofmtandgoimportsare enforced via the toolchain. Runmake lintbefore pushing. - Keep packages focused. Cross-package dependencies should flow
one way:
httpapi -> auth/storage/tenant, never the reverse. - Tests live next to the code they exercise (
*_test.go). Aim for table-driven tests for input parsing and behavioural tests withhttptest.NewRecorderfor handlers. - New runtime configuration goes through
LIBRENOTES_*env vars with a corresponding--flagonlibrenotes serve. - All filesystem operations on tenant data must go through
internal/tenant. Neveros.Opena path containing a user ID.
Branch naming
feat/<short-slug>for new featuresfix/<short-slug>for bug fixesdocs/<short-slug>for documentationchore/<short-slug>for tooling, CI, refactorsphase-N/<topic>for issues belonging to a roadmap phase
Commit messages
Imperative mood, present tense. First line ≤72 characters. Body
explains the why, references the issue with Closes #N or
Refs #N so Gitea can auto-link. Example:
Add tenant-scoped notes REST API
Backed by tenant.FS so all reads/writes go through the per-user
sandbox. ?base=<unix> drives optimistic-locking conflict
detection for PUT/DELETE.
Closes #11.
Pull request process
- Open an issue first for anything non-trivial. Reference it from the PR.
- Branch off
main, push, open a PR againstmain. - CI must pass (
make lint && make test). Failed CI blocks review. - Fill out the PR template — at minimum: what changed, why, how it was tested.
- Squash on merge unless the history is genuinely useful.
Reporting issues
Use the bug-report or feature-request templates from the New issue page on Gitea. The templates ask for the right things; filling them out gets faster responses.
For security issues please do not open a public issue. Email
security@librete.ch with details.
Releases
Tagged releases follow SemVer. The maintainer creates the tag and the deploy workflow handles the build and registry push automatically. Individual contributors are not expected to tag releases.