Files
librenotes/CONTRIBUTING.md
Michael Czechowski 61edef9483 Add user guide, self-hosting, API, and contributing docs
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>
2026-04-28 22:52:09 +02:00

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; gofmt and goimports are enforced via the toolchain. Run make lint before 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 with httptest.NewRecorder for handlers.
  • New runtime configuration goes through LIBRENOTES_* env vars with a corresponding --flag on librenotes serve.
  • All filesystem operations on tenant data must go through internal/tenant. Never os.Open a path containing a user ID.

Branch naming

  • feat/<short-slug> for new features
  • fix/<short-slug> for bug fixes
  • docs/<short-slug> for documentation
  • chore/<short-slug> for tooling, CI, refactors
  • phase-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

  1. Open an issue first for anything non-trivial. Reference it from the PR.
  2. Branch off main, push, open a PR against main.
  3. CI must pass (make lint && make test). Failed CI blocks review.
  4. Fill out the PR template — at minimum: what changed, why, how it was tested.
  5. 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.