We are committed to providing a friendly, safe and welcoming environment for all. See our Code of Conduct for details.
All contributions are appreciated! Typo fixes, bug fixes, feature requests, bug reports...
For ideas, proposals and feature request, click here, for all other contributions, read on.
For a good place to start, check out good first issues or reach out on the #contributing channel on our zulip group chat.
Before making your first pull request, create a new topic in the contributing channel on zulip to discuss what you plan to do! This can avoid duplicated effort or a rejection because the change doesn't fit with the goals of the language.
If you are interested in larger, implementation- or research-heavy projects related to Roc, check out Roc Project Ideas and reach out to us on zulip! These projects may be suitable for academic theses, internships, independent research, or just valuable projects to learn from and improve Roc with.
Check Building from source for instructions.
Build steps follow a build/run split:
build-*steps compile, install, generate files, or prepare inputs.run-*steps execute tools after their build inputs are ready.run-check-*steps run checks.run-test-*steps run tests.
Do not add duplicate alias steps. When adding CI or MiniCI coverage, wire prep
work into a build-* step and add that step to build-ci; add the executable
test or check as a leaf run-* step.
Most contributors should run MiniCI before pushing their code:
zig build miniciMiniCI is the local orchestrator for the CI-shaped set of checks and tests. It
first builds the inputs behind build-ci, then runs the leaf run-check-* and
run-test-* jobs with separate logs and report entries. It actually runs the
tests; it does not just build them.
After each run, MiniCI writes a report directory:
zig-out/minici/index.htmlis a static dashboard you can open directly in a browser. It shows the run timeline, failures, job details, slowest harness cases, and per-case timing for harness-backed tests.zig-out/minici/report.jsonis the machine-readable run summary. It containsschema_version,run_started_unix_ms,build_ci, andjobs. Each result includesstatus,start_ns,end_ns,duration_ns,log_path,command, andstats_path.zig-out/minici/logs/*.txtcontains captured stdout and stderr for each build, check, and test job.zig-out/minici/raw/*.jsoncontains harness runner statistics for jobs with astats_path. These files includerunner,summary, andeventswith case names, statuses, timings, worker indexes, parent ids, and per-stage details.
Agents and scripts should read zig-out/minici/report.json first, then follow
log_path for raw command output and stats_path for per-case statistics. If a
job fails, rerun the failed command from the report or from MiniCI's terminal
hint.
For focused local iteration, run an exact leaf step. To run a specific Zig unit test:
zig build run-test-zig -- --test-filter "name of test"- If you've never made a pull request on github before, this will be a good place to start.
- You can find good first issues here. Once you have gained some experience you can take a look at the intermediate issues.
- It's a good idea to open a draft pull request as you begin working on something. This way, others can see that you're working on it, which avoids duplicate effort, and others can give important feedback sooner rather than later. Click the button "ready for review" when it's ready.
- The Glossary file explains terms commonly used in the compiler.
If you need to do some debugging, check out our tips.
To measure eval interpreter code coverage and find untested code paths, see the eval coverage guide.
All your commits need to be signed to prevent impersonation.
Check out our guide for commit signing.
⚠️ Tip for NixOS users
On NixOS pinentry can cause problems, the following setup works well for those with a KDE desktop. From /etc/nixos/configuration.nix:
programs.gnupg.agent = {
enable = true;
pinentryFlavor = "qt";
enableSSHSupport = true;
};
Forgot to sign commits?
❗ Make sure to set up signing on your device first, then continue below.
You can view your commits on github, those without the "Verified" badge still need to be signed. If any of those is a merge commit, follow these steps instead of the ones below.
If you have only one commit, running git commit --amend --no-edit -S would sign the latest commit 🚀.
In case you have multiple commits, you can sign them in two ways:
- Switching to interactive rebase mode and editing the file:
- Enter into interactive mode, by running
git rebase -i HEAD~nwherenis the number of commits up to the most current commit you would like to see. - This would display a set of commits in a text file like below:
pick hash2 commit message 2 pick hash1 commit message 1 - On a new line below a commit you want to sign, add
exec git commit --amend --no-edit -S. Do this for all your unsigned commits.
- Enter into interactive mode, by running
- Or run git rebase recursively:
- Find the oldest commit you want to sign, using the
git log --show-signaturecommand. - Run the command
git rebase --exec 'git commit --amend --no-edit -n -S' -i HASHwhich would sign all commits up to commitHASH.
- Find the oldest commit you want to sign, using the
If you already pushed unsigned commits, you may have to do a force push with git push origin -f <branch_name>.
Feel free to open an issue if you think this document can be improved!