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>
116 lines
3.6 KiB
Markdown
116 lines
3.6 KiB
Markdown
# 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](./CODE_OF_CONDUCT.md). 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:
|
|
|
|
```sh
|
|
git clone https://git.librete.ch/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:
|
|
|
|
```sh
|
|
docker build -f Dockerfile.dev -t librenotes-dev .
|
|
docker run --rm -it -v "$PWD:/workspace" librenotes-dev
|
|
```
|
|
|
|
See the [README](./README.md) 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](https://semver.org). The
|
|
maintainer creates the tag and the deploy workflow handles the
|
|
build and registry push automatically. Individual contributors
|
|
are not expected to tag releases.
|