Contributing
Thank you for wanting to contribute to nmrs!
Guidelines
I'm fairly accepting to all PRs, only with a couple caveats:
- Do not submit low-effort or autogenerated code. If you absolutely must, please disclose how you used AI otherwise I will close the PR.
- Please try to (when possible) contribute to an issue. This is not a hard ask, I'll still consider your contribution if it makes sense.
Requirements
To run or develop nmrs you need:
- Rust (stable) via
rustup - Linux and NetworkManager only for environmental integration tests
I also provide a Dockerfile you can build if you don't use Linux and use MacOS instead.
To run tests:
docker compose run --rm test
This starts an isolated system D-Bus and NetworkManager instance, runs the workspace tests, and executes the NM-only integration contract. It does not use the host system bus.
To run an interactive shell:
docker compose run shell
If you decide to run the shell, ensure you run all commands from within the nmrs directory, not root.
cargo test -p nmrs --lib # run library unit tests
cargo build -p nmrs # build the library
cargo check # you get the point...
When your branch falls behind master
If the respective branch for a PR goes out of sync, I prefer you rebase. I've exposed this setting for you to automatically do so as a contributor on any PR you open.
Issues and Commit Message Hygiene
When you've made changes and are ready to commit, I prefer that you follow the standards explained at Conventional Commits.
I additionally request that you format your commits as such:
type((some issue number)): changes made
For example:
fix(#24): fixed bug where something was happening
Obviously, if there is no issue number to attach, no need to add anything there.
Lastly, please ensure you make atomic commits.
All issues are acceptable. If a situation arises where a request or concern is not valid, I will respond directly to the issue.
Tests
All unit, documentation, and applicable environmental tests must pass before a merge takes place.
Unit and documentation tests
cargo test --locked --lib --all-features --workspace
cargo test --locked --doc --all-features --workspace
Integration tests are #[ignore]. A normal cargo test compiles them without
contacting or mutating the host NetworkManager.
Isolated NetworkManager integration
docker compose run --build --rm test-integration
This provisions private D-Bus and NetworkManager processes plus a veth-backed DHCP network. It validates saved-profile CRUD, schema decoding, exact settings events on both event APIs, an actual NetworkManager-to-agent secret exchange, native WireGuard activation and classification, wired discovery, activation details, disconnect, and cleanup.
Deterministic WiFi integration
The WiFi contract uses one hwsim radio for a WPA2 access point with DHCP and a second radio as NetworkManager's station:
sudo modprobe mac80211_hwsim radios=2
docker compose run --build --rm test-wifi-integration
sudo modprobe -r mac80211_hwsim
Missing facilities and unexpected operations fail once the harness declares its capabilities. The lifecycle also drives both network and device callback monitors. Tests never accept an arbitrary error or silently skip.
To run the NM-only contracts against a deliberately selected local daemon:
NMRS_REQUIRE_NETWORKMANAGER=1 \
cargo test --test integration_test --all-features \
networkmanager_ -- --ignored --test-threads=1
These create and delete a NetworkManager profile and register a temporary secret agent. Prefer the isolated Docker harness unless those operations on the selected daemon are intentional.
Documentation
When adding new features or changing existing APIs:
- Update rustdoc comments in the source code
- Add or update examples in the
examples/directory - Update this mdBook documentation if user-facing changes are made
- Update the CHANGELOG.md
To build the documentation locally:
# API documentation
cargo doc --open --no-deps
# User guide (this book)
cd docs
mdbook build
mdbook serve --open
Code Style
- Follow standard Rust formatting:
cargo fmt - Pass clippy checks:
cargo clippy -- -D warnings - No unsafe code (enforced by workspace lints)
- Add doc comments for public APIs
- Write tests for new functionality
License
All contributions fall under the dual MIT/Apache-2.0 license.
Getting Help
- Join our Discord server
- Open an issue for questions or bugs
- Check existing issues and PRs for similar work