Skip to main content
Follow this workflow when contributing to Erst to ensure smooth collaboration and maintain code quality.

Branch naming

Create descriptive branch names based on the type of work:
  • Features: feat/my-feature-name
  • Bug fixes: fix/issue-description
  • Documentation: docs/update-description
  • Refactoring: refactor/component-name
  • Tests: test/test-description
# Create a feature branch
git checkout -b feat/add-source-mapping

# Create a bugfix branch
git checkout -b fix/handle-network-timeout

Development steps

1

Sync with main branch

Before starting work, ensure your local main branch is up to date:
git checkout main
git pull origin main
2

Create a new branch

Create a branch for your feature or bug fix:
git checkout -b feat/my-feature
3

Make your changes

Write your code following the code standards.
4

Test locally

Run all tests and linting before committing:
go test ./...
cargo test --all
Or use Make targets:
make test
make rust-test
make lint-all-strict
5

Commit your changes

Follow the commit message convention:
git add .
git commit -m "feat(sim): add transaction replay caching"
6

Push and create a pull request

Push your branch and create a PR on GitHub:
git push origin feat/my-feature
Then create a PR with a detailed description.
7

Address review feedback

Make requested changes, commit, and push:
git add .
git commit -m "fix: address review comments"
git push origin feat/my-feature

Commit message convention

Erst follows the Conventional Commits specification:
<type>(<scope>): <subject>

<body>

<footer>

Types

  • feat: A new feature
  • fix: A bug fix
  • test: Adding or improving tests
  • docs: Documentation changes
  • refactor: Code refactoring without feature changes
  • perf: Performance improvements
  • chore: Build, CI, or dependency updates
  • ci: CI/CD configuration changes

Scopes

Use specific areas of the codebase:
  • sim: Simulator (Rust)
  • cli: CLI interface (Go)
  • updater: Update mechanism
  • trace: Trace viewer
  • analyzer: Transaction analyzer
  • rpc: RPC client

Examples

feat(sim): add protocol version spoofing for harness

Implements protocol version override to allow testing
transactions from different network versions locally.

Closes #350

Commit rules

  • Keep subject under 50 characters
  • Use imperative mood: “add” not “added” or “adds”
  • No period at the end of the subject
  • Provide detailed explanation in the body if the change is non-obvious
  • Reference related issues: Closes #350, Refs #343
Never use emojis in commit messages or PR titles.

Pull request structure

Create clear, well-documented pull requests:

PR title

Follow the same format as commit messages:
feat(sim): add transaction replay caching

PR description template

## Description
Brief explanation of the changes and why they're needed.

## Related issues
Closes #350, relates to #343

## Changes made
- Added caching layer for transaction replay
- Implemented LRU eviction policy
- Added configuration options for cache size

## Testing
- Added unit tests for cache operations
- Added integration tests for replay with cache
- Tested with 1000+ transaction replays
- Verified 3x performance improvement

## Breaking changes
None

## Checklist
- [x] Code follows style guidelines
- [x] Tests added/updated
- [x] Documentation updated
- [x] No new warnings or errors
- [x] All tests pass locally
- [x] Strict linting passes

PR checks

Before submitting, ensure:
  • All CI checks pass
  • Code coverage doesn’t decrease
  • All tests pass locally
  • Strict linting passes (make lint-all-strict)
  • Documentation is updated if needed
The CI pipeline will automatically run tests, linting, and coverage checks. PRs with failing checks will not be merged.

Formatting and linting

Run formatting and linting before every commit:

Format code

make fmt-go

Run linting

make lint-strict

Using pre-commit hooks

Install pre-commit hooks to automatically check your code:
1

Install pre-commit

pip install pre-commit
2

Install hooks

pre-commit install
Or use Make:
make pre-commit
3

Run manually

Test the hooks on all files:
pre-commit run --all-files
Pre-commit hooks will automatically:
  • Format Go code with gofmt
  • Format Rust code with cargo fmt
  • Run golangci-lint
  • Run cargo clippy
  • Check for merge conflicts
  • Validate YAML files

Code review checklist

When reviewing PRs, ensure:
  • Code follows naming and style conventions
  • Error handling is appropriate
  • Tests are adequate and pass
  • Documentation is clear and complete
  • No unnecessary dependencies added
  • Performance implications considered
  • Security implications reviewed
  • Commit messages follow convention
  • No dead code or unused variables
  • Linting passes without suppressions (unless justified)

Common development tasks

# Build Go CLI
go build -o erst cmd/erst/main.go

# Or use Make
make build

# Build for release (optimized)
make build-release

# Build Rust simulator
cd simulator && cargo build --release

# Or use Make
make rust-build
# Linux AMD64
GOOS=linux GOARCH=amd64 go build -o erst-linux-amd64 ./cmd/erst

# macOS ARM64
GOOS=darwin GOARCH=arm64 go build -o erst-darwin-arm64 ./cmd/erst

# Windows AMD64
GOOS=windows GOARCH=amd64 go build -o erst-windows-amd64.exe ./cmd/erst
# Clean Go artifacts
go clean
go clean -cache

# Clean Rust artifacts
cd simulator && cargo clean

# Clean all (using Make)
make clean
# Go dependencies
go mod tidy
go mod download

# Or use Make
make deps

# Rust dependencies
cd simulator && cargo fetch
# Update Go dependencies
go get -u ./...
go mod tidy

# Update Rust dependencies
cd simulator && cargo update

Addressing review feedback

When maintainers request changes:
  1. Make the requested changes in your local branch
  2. Commit with a descriptive message: fix: address review comments on error handling
  3. Push to your branch: git push origin feat/my-feature
  4. Reply to comments explaining your changes
  5. Re-request review when ready
Don’t force-push unless you’re rebasing or squashing commits. Regular pushes preserve the review history.

Rebasing and squashing

Before merging, you may be asked to rebase or squash commits:
# Rebase onto latest main
git checkout main
git pull origin main
git checkout feat/my-feature
git rebase main

# Squash last 3 commits
git rebase -i HEAD~3

# Force push after rebase (only if necessary)
git push -f origin feat/my-feature
Only force-push to your feature branch, never to main. Be careful when force-pushing to branches others are working on.

Getting unblocked

If you’re stuck:
  • Review the documentation in docs/
  • Check existing issues for similar problems
  • Ask in GitHub Discussions for general questions
  • Create an issue for specific bugs or feature questions
  • Tag maintainers in your PR if you need guidance

Important reminders

  • No emojis in commit messages or PR titles
  • No vague messages like “fixes stuff” or “updates things”
  • Always run strict linting before pushing
  • All tests must pass before requesting review
  • Update documentation when changing functionality
  • Reference issues in commit messages and PRs