Files
restic-manager/CONTRIBUTING.md
T

7.1 KiB
Raw Permalink Blame History

Contributing to restic-manager

Thanks for your interest in restic-manager. This document covers how to set up a development environment, the conventions the project follows, and how to contribute through issues as well as patches that make it from your machine into main.

Project status and scope

restic-manager is in pre-1.0. Core functionality (Phases 04) is landed; OSS-readiness polish is in progress. The top of tasks.md tracks what's next; spec.md is the canonical design doc and the source of truth for any "why is it built this way" question.

The project is single-maintainer, hobbyist-scale, and licensed under PolyForm Noncommercial 1.0.0. That has two practical implications:

  1. Big PRs without prior discussion may be declined for fit reasons even when they're correct — opening an issue first lets us check alignment cheaply.
  2. Commercial use is not permitted by the license. Bug reports and patches from operators of personal/community deployments are very welcome.

Getting started

Prerequisites

  • Go 1.25 or newer (go.mod is the source of truth)
  • make
  • For the front-end CSS bundle: nothing extra — make build downloads a pinned tailwindcss standalone binary into bin/.
  • For the docs site: nothing extra — make docs does the same trick with mdbook.
  • For end-to-end tests: Docker + Docker Compose, plus npx for Playwright.

One-time setup

git clone https://gitea.dcglab.co.uk/steve/restic-manager.git
cd restic-manager
make build          # compiles bin/restic-manager-{server,agent}
make test           # full unit + integration test sweep
make lint           # gofumpt + goimports + golangci-lint

Running locally

For most development, the smoke environment is the path of least resistance:

make smoke-restart  # rebuilds, launches as a systemd --user unit
make smoke-logs     # tail of the server log

Then point a browser at http://127.0.0.1:8080. The first run prints a one-time bootstrap token to the log; use it to create the admin user.

Code conventions

Style

  • gofumpt for formatting; goimports for import grouping. Both run via the pre-commit hook in this repo.
  • golangci-lint with .golangci.yml defaults; CI rejects on lint errors.
  • UK English in identifiers, comments, log messages, and UI strings (the misspell linter is configured for the UK locale — see P3-X5 for the original sweep).
  • Comments explain why, not what; avoid restating the code. A surprising invariant or an external constraint is worth writing down. "Adds 1 to x" is not.
  • slog for structured logs. Never log secrets — and especially never the merged-creds rest-server URL (see CLAUDE.md).

File and package layout

  • cmd/server and cmd/agent are the two binary entry points.
  • internal/ holds everything that's not part of the public Go API (which is none of it — restic-manager isn't a library).
  • Per-feature packages live under internal/server/... for the control plane and internal/agent/... for the agent.
  • web/templates/ are HTML templates rendered with the standard library; embedded via web.FS.

Tests

  • Unit tests live alongside the code as *_test.go. Use the in-process sqlite store (store.Open(":memory:")) when you need state — there is no test mock layer to maintain.
  • HTTP handlers test through httptest.NewServer against the real router; see internal/server/http/auth_test.go for the canonical fixture pattern.
  • End-to-end tests live in e2e/ and run against a Docker Compose stack. See docs/e2e.md.

Database migrations

  • Migrations are hand-rolled SQL in internal/store/migrations/ and embedded via embed.FS.
  • Prefer column-level ALTER TABLE over rebuilds — see CLAUDE.md "Migrations" section for the FK-cascade trap that bit migration 0007's first draft.

Workflow

Opening an issue

Issues are contributions too. Use them to report a bug, suggest a feature, improve the documentation, or start a design discussion even if you do not plan to submit a patch.

Before opening one, search the existing issues and check tasks.md to see whether the topic is already tracked. Then choose the closest issue template:

  • Bug report for behaviour that does not match the documentation or expected operation.
  • Feature request for a new capability or a change to existing behaviour.

Give the issue a specific title, keep it to one problem or proposal, and complete the relevant template fields. If no template is an exact fit, open a regular issue and explain the context, desired outcome, and any alternatives you have considered. Maintainers may ask follow-up questions or close requests that duplicate existing work or fall outside the project's scope.

Security-sensitive reports are the exception: follow the SECURITY.md disclosure process and do not open a public issue.

Before opening a PR

  1. Open an issue first for non-trivial changes. The design is still moving; an issue lets us agree on direction cheaply.
  2. Run make lint test locally — both must pass.
  3. Match existing code style (see above).
  4. Keep commits focused: one logical change per commit. Imperative subject lines, body explaining why if it isn't obvious.
  5. Don't add Co-Authored-By trailers — repo policy. If you used AI assistance in writing the patch, that's fine; we just don't pollute every commit message with attribution boilerplate.

Pull requests

PRs target main. CI runs lint + tests on Linux amd64/arm64 and Windows amd64; all three must be green to merge. Squash-merge is the default; the PR title becomes the merge-commit subject, so keep it short and informative.

The PR template asks for:

  • A short description of what changed and why.
  • A test plan (commands run, scenarios verified).
  • Anything reviewers need to know to assess the change (related issue, follow-up work, deferred concerns).

Reporting bugs

Use the bug report issue template and include:

  • restic-manager version (server --version) and agent version.
  • restic version on the affected host.
  • Steps to reproduce.
  • Server and agent logs (sanitise any tokens before pasting).

For security-sensitive bugs, use the private disclosure process noted above.

Suggesting features

Use the feature request issue template and describe the use case (not just the proposed solution). The roadmap in tasks.md shows where the project is heading; if the suggestion fits a future phase we'll wire it in there. If it falls outside the project's scope (multi-tenancy, SaaS, non-restic backends — see spec.md §2 non-goals) we'll say so early to save your time.

Code of conduct

Project participation is governed by CODE_OF_CONDUCT.md. The short version: be civil; assume good faith; harassment is not tolerated.

License

By contributing you agree that your contributions are licensed under the PolyForm Noncommercial 1.0.0 license.