Contributing to Sadame¶
Thank you for helping. This guide covers setting up a development checkout, running the tests on both Ruby runtimes, the rules that keep the code working under mruby, and what a pull request needs.
Development setup¶
You need:
- Ruby 3.2 or newer and Bundler, for running sadame from source and for the test suite;
- a C compiler,
gitandbison, for building the mruby binary.
git clone https://github.com/enderkus/sadame.git
cd sadame
bundle install
Running the tests¶
The same test files run under CRuby (with minitest) and inside the mruby build (with mruby-mtest). CI requires both to pass.
bundle exec rake test:cruby # fast, no compiler needed
bundle exec rake test:mruby # builds mruby with sadame into build/, then runs the suite
bundle exec rake test # both
rake build:native builds a development binary into
build/host/bin/sadame. Release binaries, static Linux builds through
Docker and the macOS builds, are described in
Building sadame.
Tests never need root: resources are tested against FakeShell
(test/support/fake_shell.rb), which records commands and returns stubbed
results.
Two more layers run sadame for real, with Docker:
rake build:linux-arm64 # or linux-amd64: the binary under test
rake "test:docker[debian,arm64]" # every example in fresh containers booting systemd
rake test:push # push mode against SSH servers in containers
CI runs both on every pull request, for five distributions and two architectures. A third layer runs on the maintainer's virtual machines and is not part of CI. Testing explains all three.
Writing code for mruby¶
Release builds are a single mruby binary, so everything under lib/ must
run on mruby with only the gems listed in build_config.rb:
- Never call
requireinlib/. To add a file, list it withrequire_relativeinlib/sadame.rb; the mruby build reads that list to compile the same files in the same order. - No standard library (JSON, YAML, ERB, Open3, FileUtils, ...). Sadame has
small replacements:
Sadame::JsonWriter,Sadame::Template,Sadame::Shell.escape. - Run commands and read files only through
Sadame::Shell. - In a
rescueclause, re-raise withraise e, not a bareraise.
The full list of pitfalls, with what to use instead, is in
Architecture.
If you think a new mruby gem is needed, explain why in the commit that adds
it to build_config.rb.
Style¶
- Clear names, small methods, plain classes. No metaprogramming beyond what the recipe DSL needs.
- Every resource reads the current state before acting and does nothing when it matches the desired state.
- Errors meant for users are
Sadame::Errorsubclasses with a message that says what to do.
Documentation and examples¶
Documentation is part of every change:
- A new feature comes with a page (or a section) in
docs/following the feature page shape: what and why, a minimal example, an option table, realistic scenarios with real output, common mistakes, see also. - Every recipe shown in the docs lives under
examples/and is embedded with--8<-- "examples/...".test/unit/examples_test.rbloads, plans and applies every example against a fake machine and checks that everyexamples/path mentioned in the docs exists. - Terminal sessions in the docs are captured, not typed. Each one is
defined in
script/transcripts/scenarios.rb, run in a fresh Docker container byrake docs:transcripts(orSCENARIO=name rake docs:transcriptsfor one), written todocs/transcripts/, and embedded with--8<-- "docs/transcripts/NAME.txt". Short excerpts, such as a diff shown on its own, are copied from those files. When a change alters output, regenerate the transcripts and commit them with the change.
Build the site locally with:
python3 -m venv .venv
.venv/bin/pip install -r docs/requirements.txt
.venv/bin/mkdocs build --strict
.venv/bin/mkdocs serve
CI also checks every internal link and anchor of the built site with lychee. The same check locally, with Docker:
docker run --rm -v "$PWD/site:/web/sadame:ro" lycheeverse/lychee --offline \
--include-fragments --index-files index.html --root-dir /web /web/sadame
Reporting bugs and proposing features¶
Use the issue templates: a bug report asks for the version, the command,
a small recipe and the output with --no-color; a new resource proposal
asks how the resource reads the current state and changes it on each
distribution. Security problems: please do not open a public issue; write
to the maintainer through the contact on their GitHub profile.
Commits and pull requests¶
- Small, focused commits using
Conventional Commits:
feat(resource): add cron resource,fix(file): keep owner on rewrite,docs(exec): explain guard order. - Keep the history as it is; do not rewrite published commits.
- A pull request passes
rake teston both runtimes andmkdocs build --strict, and updatesCHANGELOG.mdunder "Unreleased". - A new feature or resource comes with its docs page and a tested example
under
examples/; the pull request template lists what that means.
License¶
By contributing you agree that your contributions are licensed under the MIT License.