Thanks for considering a contribution! This document covers how to get set up, how we review changes, and how releases are produced.
A Makefile provides common developer targets:
make build # build all crates
make test # run all tests
make ci # fmt-check + clippy + test (local CI)
make check # same as 'ci' — shorter alias for quick verification
make audit-example # build the example plugin rule (.so)
make plugin-pack # pack example-rule-1.0.0.sdktplugin
make plugin-verify # verify the bundle
make compat # run compatibility CI matrix locally- Fork and clone the repository.
- Install Rust (stable toolchain, edition 2021):
rustup toolchain install stable rustup default stable
- Install the WASM target (required to build Soroban contracts):
rustup target add wasm32-unknown-unknown
- Build to verify your environment:
cargo build
- Create a branch for your change (e.g.
feat/fooorfix/bar). - Write tests for any new functionality or bug fix.
- Format & lint before committing:
cargo fmt --all cargo clippy --workspace --all-targets -- -D warnings
- Test:
# Run the full workspace suite cargo test --workspace # Or test a single crate (faster for iteration) cargo test -p sdkt-cli
- Open a pull request against
mainfrom your branch.
To pack and verify a plugin bundle locally:
# Build the example plugin
cargo build -p sdkt-audit-example-rule --features plugins
# Pack
sdkt plugin pack crates/sdkt-audit-example-rule --output myrule.sdktplugin
# Verify (unsigned — fine for local dev)
sdkt plugin verify-bundle myrule.sdktplugin
# Sign with Ed25519 secret key (32 raw bytes)
sdkt plugin pack <plugin-dir> --output myrule.signed.sdktplugin --secret-key key.bin
# Verify signed bundle
sdkt plugin verify-bundle myrule.signed.sdktplugin --public-key pubkey.bin
# Install into local store
sdkt plugin install <artifact.so> --id my-rule
# Audit with --rules <id>
sdkt audit src/lib.rs --rules my-rulesdkt relies on Cargo.lock being checked into source control at the workspace root to ensure strictly reproducible builds.
- MSRV Policy: The Minimum Supported Rust Version (MSRV) must not be increased without strict dependency or security justification. If a bump is completely unavoidable, contributors must:
- Document the required update in
CHANGELOG.mdandREADME.md. - Bump
rust-versioninCargo.toml. - Update the
msrvjob configuration in.github/workflows/ci.yml. - Explain precisely why the bump was necessary in the pull request description.
- Document the required update in
- Adding Dependencies: When adding a new library to
Cargo.toml, ensure that the dependency is genuinely necessary (check if standard library solutions exist first). Use optional dependencies and features extensively to prevent artifact bloat. - Pinning & Updating: Our
Cargo.lockis pinned manually and updated holistically during specific maintenance phases. Do not runcargo updateindiscriminately in PRs unrelated to dependency updates.
- Unit tests live next to the code (
#[cfg(test)] mod tests). - CLI integration tests use
assert_cmdundercrates/sdkt-cli/tests/. Fixture paths are resolved fromCARGO_MANIFEST_DIR, so they work regardless of the current directory. - Run the full suite:
cargo test --workspace - Before claiming a CLI change is done, run the actual binary against a
real fixture in both formats:
cargo run -q --bin sdkt -- diff --old-wasm a.wasm --new-wasm b.wasm --format pretty cargo run -q --bin sdkt -- diff --old-wasm a.wasm --new-wasm b.wasm --format json
- Keep PRs focused on a single change.
- Update
CHANGELOG.mdunder the relevant version (or[Unreleased]). - Add tests that verify your change.
- If adding dependencies, update the workspace root
Cargo.toml([workspace.package]/ member crates inherit versions). - Ensure public API signatures are clear and documented (
///doc comments). - Verify CI checks pass (fmt / clippy / test / docs) before requesting review.
- Use
rustfmt(cargo fmt --all). - Clippy must pass with
-D warnings. - Keep unit tests near the code they test.
- Add doc tests (
///) for public library functions.
- Bug reports with reproduction steps.
- Feature requests with motivating examples / use cases.
- Pull requests triaged through review.
- Documentation and onboarding improvements.
- Test coverage improvements.
sdkt is tested on CI (ubuntu-latest, macos-latest, windows-latest):
- Linux (x86_64; aarch64 via CI/source)
- macOS (Intel, Apple Silicon)
- Windows (x86_64)
GitHub Release v2.5.0 ships linux-x86_64 and both macOS tarballs.
Windows is installable via cargo install sdkt-cli (or source). A Windows
Release zip is produced by release.yml on the next v* tag, not on v2.5.0.
Looking for a place to start? Self-contained, low-risk tasks:
- Docs: add a copy-paste recipe to
docs/examples.md, or improve a section inREADME.md/docs/. - Fuzz crate: add a mutation operator or an oracle condition, following
crates/sdkt-fuzz/README.md(the extension guide). - CLI polish: improve
--helptext or error messages incrates/sdkt-cli/src/main.rs(no behavior change). - Tests: add an integration test under
crates/sdkt-cli/tests/for an existing subcommand. - Plugin bundle tests: add a round-trip test in
crates/sdkt-cli/tests/plugin_bundle_cli_test.rs(e.g. signed bundle with--forceoverwrite, orplugin updateafter pack). - Windows: verify a command or documentation path works on Windows (PowerShell).
- CI: tighten a workflow without changing release behavior.
Use the Good First Issue issue template and label so we can triage.
Releases are cut from main on a v* tag. The pipeline (see
.github/workflows/release.yml):
validate— runsfmt --check,clippy -D warnings,test.publish-dry-run—cargo publish --dry-run --workspace(packages all crates locally; does not contact crates.io for unpublished siblings).build-binaries— cross-compiles release binaries (linux / macos intel+arm) and uploads them as artifacts.github-release— creates the GitHub Release from the tag.publish-crates— publishes crates in dependency order (sdkt-core → sdkt-xdr → sdkt-wasm → sdkt-rpc → sdkt-storage → sdkt-audit → sdkt-audit-example-rule → sdkt-cli) whenCARGO_REGISTRY_TOKENis set.
Versioning follows SemVer from [workspace.package] as the single source of
truth. Contributors do not bump versions or tag releases — maintainers do
that as part of the release milestone.
This project follows the Contributor Covenant Code of Conduct. By participating, you agree to uphold it.