# Contributing to Roto

Hi! Thank you for wanting to contribute to Roto.

This document offers guidelines on how best to contribute. Following the guidelines here
give your contributions the best chance at getting merged.

## Code of Conduct

This project and everyone participating in it is governed by the [NLnet Labs
Code of Conduct]. By participating, you are expected to uphold this code.

## A note on Generative AI

We do not accept any content -- code, documentation or otherwise -- generated by
large language models or other generative AI.

## Discussion

### Asking questions

The best place to ask questions is on the [community forum]. Please look through
existing posts before creating a new thread.

### Reporting security vulnerabilities

See [SECURITY.md].

### Reporting other bugs

If you find something that is clearly a bug, you can submit it directly to the
issue tracker. Please look though existing issues before creating a new issue.
You should also check whether your issue has already been addressed on the
`main` branch.

Try to include as much as possible of the following information:

 - Version/branch/commit of Roto you are using
 - Your system (OS, architecture)
 - Any stack traces or logging messages
 - A reproducer that shows the issue

### Suggesting enhancements

If you have ideas for improving Roto, you can start a discussion about it on the
[community forum]. Please look through other posts to see whether your idea has
been discussed before.

Be sure to include clear use-cases and motivation for your idea.

## Contribution

### License and copyright

When contributing with code or other content, you agree to put your changes and
new code under the same license Roto and its associated libraries is already
using. When changing existing source code, do not alter the copyright of the
original file(s). The copyright will still be owned by the original creator(s)
or those who have been assigned copyright by the original author(s).

By submitting a patch to Roto, you are assumed to have the right to the code and
to be allowed by your employer or whatever to hand over that patch/code to us.
We will credit you for your changes as far as possible, to give credit but also
to keep a trace back to who made what changes.

### Contributing documentation

Writing documentation is very hard, but _very_ appreciated. Improving the
documentation could mean anything from adding new chapters to fixing a typo. The
documentation of Roto is split into 2 locations:

 - The `docs/` folder of this repository.
 - The API docs at <docs.rs/roto> generated from documentation comments in the
   Rust code.
 - The standard library documentation in `src/runtime/basic.rs`.

The documentation in the `docs/` folder is written in [reStructuredText] and
hosted by [ReadTheDocs] via [Sphinx]. If you have the [uv] tool installed, you can
easily build the documentation locally with

```
make html
```

You can then serve those files however you want, for example using

```
python -m http.server
```

We have extended Sphinx a bit to make it better for our use case. First, we have
Roto syntax highlighting. Second, you can link to Roto types with ``
:roto:ref:`TypeName` ``.

You can submit your changes in a pull request. A preview version of the updated
documentation will be built automatically for your PR. You can view it by
clicking on the ReadTheDocs action on the PR page or by visiting

```
https://roto--XXX.org.readthedocs.build/
```

where `XXX` is the number of your PR.

### Contributing tooling

A programming language needs a lot of additional tooling, such as syntax
definitions for code editors. You can contribute such tooling for your favorite
editor to the `tooling/` folder.

The `tree-sitter` grammar for Roto lives [in its own
repository](https://github.com/NLnetLabs/tree-sitter-roto).

### Contributing code

Before you start contributing code, ensure that the issue you are tackling has
been properly discussed either on [] or the [issue tracker]. Do not
submit pull requests for changes that have not been discussed.

You can contribute code by opening a pull request. Before you do you should
check that you code passes all tests and adheres to the [style
guide](#style-guide). You do not have to update `Changelog.md`. That will be
updated when a release is tagged.

You run the code, you'll need to have a working and recent enough Rust toolchain
installed. The [just] tool can also come in handy to run some common commands on
this repository.

Keep the following in mind while submitting your code:

 - Make sure to link the appropriate issue for your change. If there is none,
   make the issue and discuss the change before submitting the PR.
 - Make the title and description descriptive. For example, do not make the
   title just "Fix #345", but include a description.
 - Use descriptive commit messages.
 - Your code can only be merged once the CI is green.
 - Keep your PRs self-contained and do not include unrelated changes. It's
   better to submit many small PRs than one big PR with multiple changes.

See [TESTING.md] for information on how to test your changes.

### Style guide

We follow standard style guides for Rust code. That is, we require that the code
is formatted by `rustfmt` and that it passes the checks of the latest version of
the `clippy` linter. The code should also be free of warnings generated by
`rustc`.

Since Roto uses `unsafe` and generates machine code, we additionally, we require
that Valgrind does not raise any issues on test suite. Each `unsafe` block be
accompanied by a `SAFETY` comment and each `unsafe` function should have a
"Safety" section in its documentation. We generally do not rely on `unsafe` just
to achieve better performance.

## Maintenance

This section is meant for maintainers of Roto, not for all contributors.

### Dependencies

Be careful pulling in new dependencies. We should not pull in large dependencies
for small gains. The license should also be compatible with Roto's license. You
can use `cargo deny` to check that.

### Releases

The steps for releasing a new version of Roto are:

0. Optional: come up with a release name.
1. Create a PR that:
  a. Updates the changelog.
  b. Changes the `workspace.package.version` field in `Cargo.toml`
2. Once CI for that PR is green and it is approved, merge it.
3. Check that the crates are good to be published with `cargo publish
   --workspace --dry-run`.
4. Add a git tag with the format `vX.Y.Z`.
5. Push that tag to the remote.
6. Publish the crates with `cargo publish --workspace`.
7. Add a release on the repository, with the changes from `Changelog.md`.
8. Post it to the socials!

[NLnet Labs Code of Conduct]: https://www.nlnetlabs.nl/conduct
[community forum]: https://community.nlnetlabs.nl/c/roto/7
[issue tracker]: https://github.com/NLnetLabs/roto/issues
[reStructuredText]: http://www.sphinx-doc.org/en/stable/rest.html
[ReadTheDocs]: https://readthedocs.org/
[Sphinx]: http://www.sphinx-doc.org
[uv]: https://docs.astral.sh/uv/
[just]: https://just.systems/man/en/
[SemVer]: https://semver.org/
[SECURITY.md]: ./SECURITY.md
[TESTING.md]: ./TESTING.md
