Thank you for your interest in mdPress! We welcome all forms of contribution.
If you find a bug, please file an issue on GitHub Issues with:
- OS and version
- Go version (
go version) - Chrome/Chromium version
- mdPress version (
mdpress --version) - Steps to reproduce (ideally with a minimal
book.yamland Markdown files) - Expected vs. actual behavior
- Relevant logs (use
--verbosefor detailed output)
Feature suggestions are welcome. Please describe in the issue:
- The problem you want to solve
- Your proposed solution
- Possible alternatives
- Which version this feature fits into (see ROADMAP)
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Install pre-commit hooks:
make hooks - Write code and add tests
- Commit changes:
git commit -m "feat: add new feature"The pre-commit hook automatically runs gofmt, go vet, golangci-lint, build, and fast tests. - Push the branch:
git push origin feature/my-feature - Open a Pull Request describing your changes and motivation
- Go 1.26 or later
- Chrome or Chromium browser (for PDF generation tests)
- GNU Make
- (Optional) golangci-lint for linting
# 1. Clone the repo
git clone https://github.com/yeasy/mdpress.git
cd mdpress
# 2. Build
make build
# 3. Run tests
make test
# 4. Run example to verify build
make examplemake build # Build binary to bin/mdpress
make test # Run all tests (with race detection)
make check # Run fmt + lint + build + fast tests (pre-commit gate)
make lint # Static analysis (go vet + golangci-lint)
make fmt # Format code (gofmt)
make coverage # Generate test coverage report (coverage.html)
make clean # Clean build artifacts
make example # Build example PDF using examples/- Follow standard Go code style, use
gofmtfor formatting - Line width should not exceed 120 characters (recommended)
- All exported functions, types, and methods must have documentation comments
- Comments should be in English for consistency
| Directory | Purpose | Notes |
|---|---|---|
cmd/ |
CLI commands (cobra) | Name files by function, no business logic |
internal/ |
Internal packages, not exported | Each sub-package has a single responsibility |
pkg/utils/ |
Shared utility functions | Pure utility functions with no business dependencies |
tests/ |
Integration and e2e tests | Unit tests go in _test.go files within packages |
themes/ |
Theme YAML configs | New themes must also update internal/theme/builtin.go |
examples/ |
Example project files | Used for documentation and make example |
- Use
fmt.Errorf("xxx: %w", err)to wrap errors, preserving the call chain - Return meaningful error messages to help users identify issues
- Avoid
panicexcept for unrecoverable errors during initialization
- Use standard library
log/slogfor logging --verbosemode outputs Debug level logs- Normal mode only outputs Info level and above
Follow Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer]
Common types:
| type | Description |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation changes |
style |
Code formatting (no logic changes) |
refactor |
Refactoring |
test |
Test-related changes |
chore |
Build/toolchain changes |
perf |
Performance improvements |
Example:
feat(config): add SUMMARY.md auto-discovery support
When chapters are not defined in book.yaml, automatically look for
SUMMARY.md in the same directory and parse chapter structure.
Closes #42
- New features must include corresponding unit tests
- Test files go in the corresponding package directory with
_test.gosuffix - Use Go's standard testing framework (
testingpackage) - Test function naming:
TestXxx_Description(e.g.,TestParseConfig_EmptyChapters)
- Core packages (config, markdown, renderer, toc, crossref) target ≥ 80% coverage
- New code should not lower existing coverage levels
- Run
make coverageto view the coverage report
- Features involving multiple modules should have integration tests in
tests/ - Integration tests should use test data in
tests/testdata/
- Features involving CLI commands and file I/O should have e2e tests
- PDF generation tests can use build tags (e.g.,
//go:build e2e) to skip when Chromium is not available in CI
Golden tests are snapshot-based regression tests that capture the expected output of HTML generation. They help catch unintended changes to rendering output.
- Run golden tests:
go test ./tests/golden/... - Update golden files:
go test ./tests/golden/... -update - When to update: Only update golden files after intentional changes to HTML output (styling, structure, features). Golden files are stored in
tests/golden/testdata/golden/ - How they work: Tests render markdown input to HTML, normalize volatile fields (dates), and compare against previously captured golden files. On first run, golden files are created and the test is skipped for manual review.
- Changes to GitBook compatibility, chapter links, TOC parsing, or multi-language features should be regression-tested against at least one real book sample
- Recommended samples:
docker_practice(deep SUMMARY.md, images, chapter cross-links) andlearning_pickleball(LANGS.md, bilingual directory behavior) - Document any edge cases or limitations in README or ROADMAP rather than leaving them implicit in code
- CI automatically runs tests and lint when a PR is created
- At least one maintainer must approve the Code Review
- All CI checks must pass
- PR description should include: changes made, motivation, and testing approach
- Breaking changes must be explicitly noted in the PR description
- Project documentation is written in Markdown
README.mdandREADME_zh.mdare maintained separately for English and Chinese- New features must also update the feature list and CLI commands in both README files
- Architecture changes must also update
docs/ARCHITECTURE.mdanddocs/ARCHITECTURE_zh.md
By contributing to mdPress, you agree that your contributions will be licensed under the MIT License.