This page documents the contribution process for the Memos project, including code quality standards, testing requirements, PR workflow, and community interaction. It covers the practical mechanics of contributing code, reporting issues, and maintaining quality standards.
For setting up your development environment, see Setting Up Development Environment. For project structure and build details, see Project Structure and Build System. For testing specifics, see Testing and Quality Assurance.
Memos welcomes contributions of all types. The project is fully open-source under the MIT license, and community contributions drive its development.
| Type | Description | Entry Point |
|---|---|---|
| Bug Reports | Report issues or unexpected behavior | GitHub Issues with bug template |
| Feature Requests | Suggest new functionality or improvements | GitHub Issues with feature template |
| Pull Requests | Submit code changes (fixes, features, refactoring) | Fork repository and create PR |
| Documentation | Improve wiki pages, README, or code comments | Edit markdown files in repository |
| Translations | Add or update locale files for internationalization | Edit files in web/src/locales/ |
The README provides direct links to contribution entry points:
Sources: README.md105-116
The standard contribution workflow follows GitHub's fork-and-pull model with specific quality requirements.
Sources: README.md113
main - always deployable, protectedrelease/x.y - stable release branchesfeature/description or fix/description - for developmentThe CI workflows are triggered differently based on branch:
main: Runs all tests and builds canary Docker image .github/workflows/build-canary-image.yml4-5release/**: Builds stable Docker image with version tags .github/workflows/build-stable-image.yml4-8main: Runs all quality gates .github/workflows/backend-tests.yml6-7 .github/workflows/frontend-tests.yml6-7Sources: .github/workflows/backend-tests.yml4-7 .github/workflows/frontend-tests.yml4-7 .github/workflows/build-canary-image.yml4-5 .github/workflows/build-stable-image.yml4-8
All contributions must pass automated quality gates in CI. The project enforces strict linting, formatting, and testing standards.
Sources: .github/workflows/backend-tests.yml .github/workflows/frontend-tests.yml .github/workflows/proto-linter.yml
The backend uses GitHub Actions workflow backend-tests.yml with two job types:
The static-checks job verifies code quality without running tests:
Go Module Tidiness: Ensures go.mod and go.sum are properly maintained
go mod tidy -go=1.25 .github/workflows/backend-tests.yml36-38git diff shows changesGolangci-lint: Comprehensive linter covering multiple Go best practices
v2.4.0 .github/workflows/backend-tests.yml43.golangci.yml configurationThe tests job runs four parallel test groups to optimize CI time:
| Test Group | Command | Purpose |
|---|---|---|
store | go test -v -coverprofile=coverage.out -covermode=atomic ./store/... | Database layer tests for all drivers |
server | go test -v -race -coverprofile=coverage.out -covermode=atomic ./server/... | HTTP/gRPC service tests with race detection |
plugin | go test -v -race -coverprofile=coverage.out -covermode=atomic ./plugin/... | Plugin system tests (storage backends, etc.) |
other | go test -v -race -coverprofile=coverage.out -covermode=atomic ./cmd/... ./internal/... ./proto/... | Utility and infrastructure tests |
Key testing flags:
-v: Verbose output for debugging failures-race: Race condition detection (except store group which tests multiple DB drivers)-coverprofile: Generate coverage report-covermode=atomic: Thread-safe coverage countingCoverage reports are uploaded to Codecov on main branch pushes: .github/workflows/backend-tests.yml86-91
Sources: .github/workflows/backend-tests.yml21-91
The frontend uses workflow frontend-tests.yml with two jobs:
Lint Job: Runs Biome linter
pnpm lint in web/ directory .github/workflows/frontend-tests.yml45Build Job: Verifies production build succeeds
pnpm build in web/ directory .github/workflows/frontend-tests.yml72Both jobs use frozen lockfile installation: pnpm install --frozen-lockfile .github/workflows/frontend-tests.yml41
Sources: .github/workflows/frontend-tests.yml19-73
Protocol buffer definitions must pass buf linting and formatting:
Buf Lint: Validates proto files against style guide
bufbuild/buf-lint-action@v1 .github/workflows/proto-linter.yml31-33proto directoryFormat Check: Ensures consistent formatting
buf format -d .github/workflows/proto-linter.yml36-40buf format -wSources: .github/workflows/proto-linter.yml15-41
Before submitting a PR, ensure:
go test ./... and/or pnpm test)golangci-lint run and/or pnpm lint)buf generate)Use clear, descriptive commit messages that explain what changed and why:
Good examples:
fix: correct memo visibility filter for protected memosfeat: add webhook retry mechanism with exponential backoffrefactor: extract markdown parsing into separate servicedocs: update Docker deployment section with volume syntaxAvoid:
fix bug (too vague)update code (not descriptive)WIP (should be squashed before merging)Format:
fixes #123Keep pull requests focused and manageable:
If your PR is large, consider:
Workflow: CI checks on pull requests to main branch
All workflows use concurrency groups with cancel-in-progress: true, automatically canceling older runs when new commits are pushed to the PR.
Sources: .github/workflows/backend-tests.yml .github/workflows/frontend-tests.yml .github/workflows/proto-linter.yml
All workflows use concurrency groups to cancel in-progress runs when new commits are pushed:
This prevents wasted CI resources when rapidly iterating on a PR. Each workflow-ref combination forms a unique concurrency group.
Sources: .github/workflows/backend-tests.yml13-15 .github/workflows/frontend-tests.yml11-13 .github/workflows/proto-linter.yml11-13
Workflows only run when relevant files change:
go.mod, go.sum, or **.go files .github/workflows/backend-tests.yml8-11web/** files .github/workflows/frontend-tests.yml8-9proto/** files .github/workflows/proto-linter.yml8-9This optimization reduces CI time for PRs that only touch specific parts of the codebase.
Sources: .github/workflows/backend-tests.yml8-11 .github/workflows/frontend-tests.yml8-9 .github/workflows/proto-linter.yml8-9
Once all CI checks pass, maintainers will review your PR. The review process typically involves:
Initial Triage (~1-2 days): Maintainer assigns appropriate labels and provides initial feedback
Technical Review (~3-5 days): Detailed code review focusing on:
Iteration: Address review comments by pushing new commits to your PR branch
Approval: Once approved, maintainers will merge using either:
| Aspect | What Reviewers Check |
|---|---|
| Store Layer | Proper use of Store interface, database-agnostic SQL, transaction handling |
| Service Layer | Correct use of gRPC service methods, proper error handling with status package |
| Authentication | Token validation, permission checks, proper use of context.Context for user info |
| Error Handling | Meaningful error messages, proper error wrapping, appropriate HTTP status codes |
| Resource Management | Proper cleanup of resources, context cancellation handling |
| Aspect | What Reviewers Check |
|---|---|
| React Patterns | Proper hook usage, component composition, context provider hierarchy |
| Type Safety | Correct TypeScript types, no any usage without justification |
| State Management | Appropriate use of React Query for server state, context for global state |
| API Integration | Proper use of generated gRPC-web clients from @/grpcweb |
| User Experience | Loading states, error handling, optimistic updates where appropriate |
| Accessibility | Keyboard navigation, ARIA labels, semantic HTML |
optional, repeated, and oneofbuf generate to update generated codeIf your PR has been waiting longer than expected:
#development channel if blockedPRs may be closed without merging if they:
Maintainers will provide clear reasoning when closing a PR and may suggest alternative approaches.
The project maintains test coverage through multiple test groups. Coverage reports are generated for all test runs using:
coverage.outatomic (thread-safe)Coverage is uploaded to Codecov only on main branch pushes, flagged by test group: .github/workflows/backend-tests.yml86-91
Race condition detection is enabled for most test groups using the -race flag:
server, plugin, other groups .github/workflows/backend-tests.yml72-78store group (tests multiple database drivers which may conflict)Tests are organized by functionality:
| Directory | Test Focus | Example Tests |
|---|---|---|
./store/... | Database operations, migrations, driver compatibility | SQLite, MySQL, PostgreSQL tests |
./server/... | HTTP/gRPC services, request handling, authentication | API endpoint tests, middleware tests |
./plugin/... | Storage backends, webhook dispatchers, integrations | S3 storage tests, webhook tests |
./cmd/... | CLI entry points, command parsing | Main function tests |
./internal/... | Internal utilities, helpers | Utility function tests |
./proto/... | Protocol buffer validation | Proto message tests |
Sources: .github/workflows/backend-tests.yml64-81
The project includes test scripts demonstrating testing best practices. For example, entrypoint_test.sh shows:
trap to remove temp files scripts/entrypoint_test.sh10Sources: scripts/entrypoint_test.sh1-132
The project's Dockerfile demonstrates security best practices that contributors should follow:
Non-root User: Application runs as UID 10001, not root scripts/Dockerfile33-34
Multi-stage Build: Separates build environment from runtime scripts/Dockerfile1-29
golang:1.25-alpinealpine:3.21Minimal Dependencies: Only installs required runtime packages scripts/Dockerfile32
Static Binary: CGO disabled for portability scripts/Dockerfile20
Security Flags: Binary built with security hardening scripts/Dockerfile23-24
Sources: scripts/Dockerfile1-57
The entrypoint.sh script demonstrates secure configuration handling:
Secrets from Files: Supports _FILE suffix pattern for Docker secrets scripts/entrypoint.sh17-41
MEMOS_DSN_FILE=/run/secrets/db_password reads password from filePermission Fixing: Handles upgrade path from root-created files scripts/entrypoint.sh9-15
Privilege Dropping: Uses su-exec to drop from root to nonroot user scripts/entrypoint.sh14
Validation: Checks for conflicting configuration scripts/entrypoint.sh24-27
VAR and VAR_FILE are setSources: scripts/entrypoint.sh1-46
When reporting bugs or requesting features, use the provided templates:
Bug Reports: README.md111
Feature Requests: README.md112
Sources: README.md111-112
The project uses automated stale issue management to keep the issue tracker focused:
Configuration details:
Any comment or activity on a stale issue removes the stale label and restarts the timer.
Sources: .github/workflows/stale.yml1-19
Use the appropriate channel for different types of interaction:
| Channel | Purpose | Best For | Link |
|---|---|---|---|
| GitHub Issues | Bug reports, feature requests | Tracked work items requiring code changes | Repository issues |
| GitHub Discussions | General questions, ideas, community support | Open-ended discussions, help requests | Repository discussions |
| Discord | Real-time chat, quick questions | Immediate help, community interaction | discord.gg/tfPJa4UmAv |
| Website | Official documentation and guides | Learning about features, deployment | usememos.com |
| X/Twitter | Project announcements and updates | Following project news | @usememos |
When to use GitHub Issues vs Discussions:
Sources: README.md107
When interacting in the Memos community:
The project accepts sponsorship through GitHub Sponsors to support ongoing development: README.md91
Sponsors receive:
Individual and corporate sponsorships are welcome. Contact maintainers for custom sponsorship arrangements.
Sources: README.md89-91 README.md15-37
Versions follow semantic versioning (e.g., v0.28.1):
release/0.28) build stable images .github/workflows/build-stable-image.yml5-6Version extraction logic:
Sources: .github/workflows/build-stable-image.yml16-23
Release artifacts are distributed through multiple channels:
Docker Images:
neosmemo/memos:stable - Latest stable releaseneosmemo/memos:canary - Latest main branch buildneosmemo/memos:0.28 - Specific version tagsghcr.io/usememos/memos:* - GitHub Container Registry mirrorBinary Artifacts:
Sources: .github/workflows/build-stable-image.yml147-158 .github/workflows/build-binaries.yml97-126
A demo environment is available on Render.com:
Sources: README.md94 .github/workflows/demo-deploy.yml1-18
Contributing to Memos requires:
The automated CI pipeline enforces quality standards consistently. All contributions are reviewed by maintainers before merging. For questions about contributing, use GitHub Discussions or Discord.
Sources: README.md105-116
Refresh this wiki