Thank you for your interest in contributing! This guide covers branching, commits, pull requests, and the release process.
- Code of Conduct
- Ways to Contribute
- Development Setup
- Branching Model — GitHub Flow
- Commit Messages
- Pull Requests
- Release Process & SemVer
- Labels Reference
- Tests
- Code Style
- Security
All contributors must follow the Code of Conduct.
| What | How |
|---|---|
| Report a bug | Bug Report template |
| Request a feature | Feature Request template |
| Ask a question | Question template or Discussions |
| Fix a bug / add feature | Fork → branch → PR |
| Improve documentation | Fork → branch → PR |
| Triage issues | Comment, add labels, link duplicates |
Prerequisites: Go 1.25+, GCC (Windows: TDM-GCC), Python 3.10+ with pre-commit, Node.js 18+ (E2E only).
git clone https://github.com/<your-fork>/readsync.git && cd readsync
go mod tidy && go mod download
pip install pre-commit
pre-commit install
pre-commit run --all-files
# Pure unit tests (no CGO)
go test -v ./internal/resolver/... ./internal/conflicts/... ./internal/logging/...
# All tests (CGO required)
CGO_ENABLED=1 go test -v ./...See make help for all available targets.
Pre-commit runs whitespace/config checks, gofmt, go mod tidy, and the fast no-CGO unit test set. Run pre-commit run --all-files before opening a PR if hooks were not installed locally.
ReadSync uses GitHub Flow. There is one long-lived branch: main.
main (always deployable — direct pushes blocked)
├── feat/koreader-rate-limit ← merge and delete
├── fix/moon-webdav-auth ← merge and delete
└── chore/update-actions ← merge and delete
Rules:
- Always branch from
main. - One concern per branch; keep them short-lived.
- No
develop,release/*, orhotfix/*branches (not GitFlow). - Push a
vX.Y.Ztag to trigger a release (maintainers only).
Branch naming: <type>/<short-description>
e.g. feat/koreader-push, fix/outbox-cap, deps/bump-gin-v1.11
Follow Conventional Commits (loosely):
<type>(<scope>): <imperative summary>
[body — why, not what]
[footer: Closes #123 | BREAKING CHANGE: ...]
Types: feat, fix, docs, refactor, test, chore, ci, security
- Fork, create a branch, make changes with tests.
- Ensure
go vet ./...andgo test ./...pass locally. - Open a PR against
mainusing the PR template. - Apply exactly one SemVer label.
- CODEOWNERS will request reviewers automatically.
- Push commits to address feedback; avoid force-pushing after review starts.
- A maintainer will squash-merge when approved.
ReadSync follows Semantic Versioning 2.0.0: MAJOR.MINOR.PATCH.
| Label | Bump | When |
|---|---|---|
breaking or semver-major |
MAJOR (X.0.0) | Incompatible API change |
enhancement, feature, or semver-minor |
MINOR (x.Y.0) | New backwards-compatible feature |
bug, fix, security, dependencies, or semver-patch |
PATCH (x.y.Z) | Bug fix / dependency update |
skip-changelog |
(omitted) | CI-only or internal tweak |
- Every PR merged to
mainauto-updates a draft release via Release Drafter. Release Drafter can rewrite draft content, so maintainers keep canonical notes backed up indocs/. - A maintainer reviews the draft, restores canonical notes if needed, verifies assets, then clicks Publish.
- Publishing a reviewed draft release creates or uses a
vX.Y.Ztag → triggers.github/workflows/release.yml. - The release workflow cross-compiles Windows binaries and attaches
ReadSync-vX.Y.Z-windows-amd64.zip+SHA256SUMS.txtto the release. - Tags containing
-(e.g.v1.0.0-rc.1) are marked pre-release automatically.
For the first public release, the canonical notes are backed up in
docs/release-notes-v0.1.0.md. If Release
Drafter rewrites the draft after maintenance commits, restore title v0.1.0,
tag v0.1.0, target main, those notes, and the ReadSync-v0.1.0-windows-amd64.zip
plus SHA256SUMS.txt assets before publishing.
Managed in .github/labels.yml, synced by CI.
| Label | Purpose |
|---|---|
bug / fix |
Broken behaviour |
enhancement / feature |
New capability |
documentation |
Docs only |
security |
Security fix |
dependencies |
Dependency update |
ci / build |
Automation / build system |
breaking / semver-major/minor/patch |
SemVer version bump control |
skip-changelog |
Omit from release notes |
good-first-issue |
Beginner-friendly |
help-wanted |
Community contributions welcome |
work-in-progress |
PR not ready for review |
stale |
No activity for 30–60 days (auto-closed after 14 more) |
| Make target | Scope | CGO? |
|---|---|---|
make test-unit |
Resolver, conflicts, logging, outbox, Moon+ | No |
make test-security |
CSRF, secret redaction | No |
make test-integration |
Pipeline + fake adapters | Yes |
make test-phase7 |
All P7 unit + security | No |
make test |
Everything | Yes |
make test-e2e |
Playwright wizard suite | No (Node) |
All new features and bug fixes must include tests.
gofmt/goimportsformatting (enforced by CI).go vet ./...must pass with no new warnings.- Error strings: lowercase, no trailing punctuation.
- No
panic()in production code paths. - Secrets must flow through
internal/secrets/— never hardcoded or logged.
Do not open public issues for security vulnerabilities. Read SECURITY.md for the responsible disclosure process.