Skip to content

Commit 6a2b742

Browse files
authored
Reshuffle contributing sections, add more detail (#687)
* Reshuffle contributing sections, add more detail * update deps * Heavily expand start contributing guide * Remove style guide * Update docs page * More details * some style * Reorder contributing pages
1 parent 8810628 commit 6a2b742

9 files changed

Lines changed: 499 additions & 267 deletions

File tree

Manifest.toml

Lines changed: 78 additions & 48 deletions
Large diffs are not rendered by default.

_quarto.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,17 @@ website:
108108
- tutorials/gaussian-processes-introduction/index.qmd
109109
- tutorials/gaussian-process-latent-variable-models/index.qmd
110110

111-
- section: "Developers"
111+
- section: "Contributing"
112112
contents:
113-
- developers/contributing/index.qmd
113+
- contributing/start-contributing/index.qmd
114+
- contributing/documentation/index.qmd
115+
- contributing/tests/index.qmd
116+
- contributing/code-formatting/index.qmd
117+
- contributing/pull-requests/index.qmd
118+
- contributing/core-developers/index.qmd
114119

120+
- section: "Developers"
121+
contents:
115122
- section: "DynamicPPL's Compiler"
116123
collapse-level: 1
117124
contents:
@@ -214,7 +221,12 @@ usage-tracking-extra-quantities: usage/tracking-extra-quantities
214221
usage-troubleshooting: usage/troubleshooting
215222
usage-varnamedtuple: usage/varnamedtuple
216223

217-
contributing-guide: developers/contributing
224+
contributing-start: contributing/start-contributing
225+
contributing-documentation: contributing/documentation
226+
contributing-tests: contributing/tests
227+
contributing-pull-requests: contributing/pull-requests
228+
contributing-code-formatting: contributing/code-formatting
229+
contributing-core-developers: contributing/core-developers
218230
dev-model-manual: developers/compiler/model-manual
219231
contexts: developers/compiler/minituring-contexts
220232
minituring: developers/compiler/minituring-compiler
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
title: Code Formatting
3+
---
4+
5+
The TuringLang ecosystem currently uses [JuliaFormatter.jl](https://github.com/domluna/JuliaFormatter.jl) to ensure consistent code style across the codebase.
6+
All code must be formatted before submitting a pull request, and ideally with every commit.
7+
8+
# Basic usage
9+
10+
We use v1 of JuliaFormatter (as of the time of writing, JuliaFormatter v2 is still somewhat unreliable).
11+
Make sure to install it in your *global* Julia environment (not the project environment, as adding it to the `Project.toml` would make it an invalid dependency of the project):
12+
13+
```julia
14+
# Do not include `--project=...` here
15+
julia -e 'using Pkg; Pkg.add(name="JuliaFormatter", version="1"); Pkg.pin("JuliaFormatter")'
16+
```
17+
18+
To format all Julia files in the current directory and subdirectories:
19+
20+
```julia
21+
julia -e 'using JuliaFormatter; format(".")'
22+
```
23+
24+
Run this command from the root of the repository before committing your changes.
25+
26+
# Faster Formatting
27+
28+
:::{.callout-note}
29+
This section is optional, but highly recommended if you are comfortable with Julia and are working on Turing codebases regularly.
30+
:::
31+
32+
Running `julia -e ...`, especially on v1 of JuliaFormatter, can be very slow due to Julia's TTFX.
33+
To get around this, you can use [PackageCompiler.jl](https://julialang.github.io/PackageCompiler.jl/) to create a custom sysimage, which already includes cached compiled versions of JuliaFormatter's functions.
34+
In our experience, this has led to drastic improvements in formatting speed: for example, on DynamicPPL.jl it slashes the formatting time from around 6 seconds to 0.5 seconds.
35+
36+
The easiest way to do so is to directly copy [the code in this GitHub Gist](https://gist.github.com/penelopeysm/9338c160eeb05437205535c2edcf80ee) into your shell configuration file (e.g. `~/.bash_profile`).
37+
You can of course modify this as you see fit.
38+
Once you have done this (and started a new shell session), you can simply use the `jf1` command to format your code, which will be *much* faster than the previous method.
39+
40+
# Pre-commit hook
41+
42+
We do not currently have [pre-commit hooks](https://pre-commit.com/) for code formatting, but you can include your own if you wish.
43+
44+
To do so, add this to `.pre-commit-config.yaml` at the top level of the repository, and then run `pre-commit install` to set up the hook.
45+
46+
```yaml
47+
repos:
48+
- repo: "https://github.com/domluna/JuliaFormatter.jl"
49+
rev: "v1.0.62"
50+
hooks:
51+
- id: "julia-formatter"
52+
```
53+
54+
:::{.callout-note}
55+
If you are intending to format on every commit, you will likely find that the basic `julia -e ...` method is intolerably slow!
56+
We therefore recommend using the PackageCompiler-enabled method for the pre-commit hook.
57+
:::
58+
59+
If you are using the faster PackageCompiler-enabled method, use the following instead (adapt as necessary if you made any changes to the function):
60+
61+
```yaml
62+
repos:
63+
- repo: local
64+
hooks:
65+
- id: format
66+
name: format
67+
language: system
68+
entry: bash -c 'source ~/.bash_profile; jf1'
69+
```
70+
71+
However, in either case, please make sure that you do not commit this file to the repository.
72+
To avoid accidentally doing so, you can add `.pre-commit-config.yaml` to `.git/info/exclude` (which is like a local `.gitignore` that is not part of source control).
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: For Core Developers
3+
---
4+
5+
This page contains notes that are specific to core developers of TuringLang.
6+
Everything on the other Contributing pages applies to core devs too; this is just the extra stuff.
7+
8+
# Branches and PRs
9+
10+
You don't need to make your own fork of the package you are editing.
11+
Just make a new branch on the main repository, usually named `your-username/change-you-are-making` (we don't strictly enforce this convention though).
12+
You should definitely still make a branch and a PR, and never push directly to `main` or `breaking`.
13+
14+
All code should generally be reviewed by another core developer and pass continuous integration (CI) checks.
15+
Exceptions can be made in some cases though, such as ignoring failing CI checks where the cause is known and not due to the current pull request, or skipping code review when the pull request author is an experienced developer of the package and the changes are trivial.
16+
17+
# Making a release
18+
19+
You can make a release of the package after your work is merged into `main`.
20+
This is done by leaving a comment on the latest commit on `main`, saying
21+
22+
```
23+
@JuliaRegistrator register
24+
25+
Release notes:
26+
27+
[YOUR RELEASE NOTES HERE]
28+
```
29+
30+
It is often easiest to take the release notes right from the `HISTORY.md` file (which is why we ask that PRs include changelog entries).
31+
32+
If you are making a breaking release, your release notes must also contain the string `Breaking changes` somewhere in them (this is mandated by the `@JuliaRegistrator` bot).
33+
34+
The `@JuliaRegistrator` bot will handle creating a pull request into the Julia central package repository and tagging a new release in the repository.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
title: Documentation
3+
---
4+
5+
# Navigating Turing's documentation system
6+
7+
Each of the packages in the Turing ecosystem (see [Libraries](/library)) has its own documentation, which is typically found in the `docs` folder of the corresponding package.
8+
For example, the source code for DynamicPPL's documentation can be found in [its repository](https://github.com/TuringLang/DynamicPPL.jl).
9+
10+
On top of the library-specific documentation, we also have a general documentation repository, which is what builds the website you are currently reading!
11+
Anything that appears in `turinglang.org/docs` is built from the [`docs` repository](https://github.com/TuringLang/docs).
12+
13+
Other sections of the website (anything that isn't a package, or a tutorial) – for example, the list of libraries – is built from the [`turinglang.github.io` repository](https://github.com/TuringLang/turinglang.github.io).
14+
15+
*In general, we prefer documentation for Turing users to be written on the `docs` repository.*
16+
This is because it is more easily discoverable for users via the search bar and sidebar.
17+
18+
Documentation written on the individual package repositories can be found via the main site's search bar (due to a GitHub workflow that scrapes all the packages' contents and indexes them here), but once you navigate to a package's documentation, you cannot then use the sidebar to come back to the main documentation site.
19+
As such, we tend to only use package-specific documentation for developer notes and API docs.
20+
21+
## Documenting unreleased features
22+
23+
There are sometimes cases where it is not possible to add docs to the `docs` repository.
24+
In particular, because the `docs` repo builds from a released version of Turing and all its dependencies, new features in unreleased versions cannot be documented here.
25+
However, it's always better to document things as you go along rather than to wait for a release and then play catch-up!
26+
27+
In such instances, we recommend first adding documentation to the relevant package's internal documentation (using Documenter.jl as usual), and later copying it over to the main `docs` repository (adjusting for the Quarto format) once the new version is released.
28+
Note that because the `docs` repository is tied to a specific version of Turing.jl, if you have updated the documentation for a new dependency of Turing (e.g. DynamicPPL or Bijectors), you also need to ensure that there is a version of Turing.jl that is compatible with that new version.
29+
30+
# How to contribute to the docs repo
31+
32+
## Local development
33+
34+
The `TuringLang/docs` repository uses Quarto.
35+
You can add a new page by creating a new `.qmd` file and including its filepath in the top-level `_quarto.yml` file, which defines the structure of the website.
36+
Generally, we prefer adding individual `index.qmd` files in new folders, as this leads to cleaner URLs.
37+
38+
When you create a new page, you can test it locally by running `quarto render /path/to/mynewpage/index.qmd`, and then launching a HTTP server from the folder containing the rendered HTML file (for example, using `cd _site/path/to/mynewpage && python -m http.server`).
39+
40+
Note that if you use `quarto preview`, this may take a very long time since Quarto will attempt to render the entire site!
41+
You can see the [repository README](https://github.com/TuringLang/docs) for some information on how to get around this using the `_freeze` folder.
42+
43+
## The docs environment
44+
45+
The `docs` repository is built from a single Manifest file, which contains a pinned version of Turing.jl.
46+
All notebooks are run with the same environment, which ensures consistency across the documentation site.
47+
48+
In general, you should **not** add new packages to this environment which **depend** on Turing (i.e., reverse dependencies of Turing), or packages that have Turing extensions.
49+
The reason for this is because such packages will have compatibility bounds on Turing.
50+
Thus, we will be unable to update the docs to use the newest Turing version, until and unless those packages also update their compatibility bounds.
51+
52+
Whenever a new version of Turing.jl is released, the Manifest file should ideally be updated (with a single `] up` in the Julia REPL), and the new docs published.
53+
This process is not yet automated, though, so sometimes the version of Turing may fall behind the latest release.
54+
Usually for minor versions we make sure to update the docs as soon as practicable, but less so for patch versions.
55+
56+
## GitHub CI
57+
58+
Each PR to the `docs` repository will trigger two GitHub Actions workflows:
59+
60+
1. The workflow that builds the documentation. If this workflow fails, it's usually due to an error in the code, or some environment resolution issues.
61+
62+
:::{.callout-tip}
63+
If you specifically want to demonstrate the *presence* of an error, you can add `#| error: true` to the top of the code block in question.
64+
:::
65+
66+
2. The workflow that checks that the version of Turing is the newest possible version.
67+
If this workflow fails, it's because the Manifest file contains an older version of Turing.
68+
69+
Note that the build-docs workflow utilises a lot of caching in order to speed up the build process (a full docs build can take 1.5 hours).
70+
However, this caching is dependent on the Manifest file not changing.
71+
Therefore, be aware that if you update the Manifest file, the next workflow run will require a full build!
72+
73+
**If you are writing new docs that do not rely on a newer version of any dependency, it is often better to avoid updating the Manifest file, and instead just add the new docs.**
74+
In this case, it's fine to let the check-version CI workflow fail.
75+
You can add a Manifest update in a separate PR.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
title: Pull Requests, Versions, and Releases
3+
---
4+
5+
Don't worry about getting everything right on your first PR — we're happy to help you through the process.
6+
Even an imperfect or half-finished PR is welcome; it's often easier to discuss changes with code in front of us.
7+
8+
Once you open a PR, someone from the dev team will review your code (if they don't, ping `@TuringLang/maintainers` in a comment to get their attention).
9+
If all looks good, we'll merge it. If not, we'll help you fix it and then merge it.
10+
11+
# Which branch should I target?
12+
13+
All TuringLang repositories follow [semantic versioning](https://semver.org/); however, the way we manage this differs between repositories.
14+
15+
**Turing.jl and DynamicPPL.jl** retain two long-lived branches: `main` and `breaking`.
16+
17+
When choosing a target branch for your PR, consider whether your change is breaking:
18+
19+
- **`main`** is for non-breaking changes: bug fixes, new features that don't change existing behaviour, documentation, etc.
20+
- **`breaking`** is for changes that lead to incompatibilities with previous versions' public API.
21+
Because we don't like introducing breaking changes too frequently, we tend to aggregate multiple breaking changes into a single release.
22+
This is why we have a separate `breaking` branch: it allows us to merge breaking changes as they come in without having to wait for a release.
23+
24+
If you're unsure about whether your change is breaking, just let us know in the PR: we can help you figure it out.
25+
26+
**Other repositories** don't have separate `main` and `breaking` branches.
27+
In this case, if you have a breaking change, just target `main` and make sure to increment the appropriate version in the `Project.toml` file (see below).
28+
29+
# Version numbers
30+
31+
For packages which have a version number of `0.x.y`:
32+
33+
- If the change you're making is non-breaking, you should increment the patch version (the last number) in the `Project.toml` file.
34+
For example, 0.3.4 would go to 0.3.5.
35+
36+
- If it's a breaking change, you should increment the minor version (the middle number) and reset the patch version to zero.
37+
For example, 0.3.4 would go to 0.4.0.
38+
39+
For packages which have a version number of `1.x.y` or higher:
40+
41+
- If you are only providing a bug fix, and not introducing any new features, you can increment the patch version (the last number) in the `Project.toml` file.
42+
For example, 1.2.3 would go to 1.2.4.
43+
44+
- If you are introducing new features but not breaking any existing functionality, you should increment the minor version (the middle number) and reset the patch version to zero.
45+
For example, 1.2.3 would go to 1.3.0.
46+
47+
- If you are introducing breaking changes, you should increment the major version (the first number) and reset the minor and patch versions to zero.
48+
For example, 1.2.3 would go to 2.0.0.
49+
50+
# Changelogs
51+
52+
When you make a PR, please add an entry to `HISTORY.md` describing the change.
53+
You can see existing entries for examples of the style.
54+
55+
If you are working on a repo that does not already have a `HISTORY.md` file, please consider creating one at the root of the repository!
56+
A changelog that's started late is still better than no changelog at all.
57+
58+
# What happens after I open a PR?
59+
60+
## Code review
61+
62+
A maintainer will review your code.
63+
This is a collaborative process: don't worry if you get comments or change requests, that's normal and expected.
64+
65+
## CI checks
66+
67+
We run the test suite in GitHub Actions for several Julia versions.
68+
Generally, all tests and code formatting checks should pass before merging.
69+
70+
If the formatting check fails, please follow [the instructions on the Code Formatting page]({{< meta contributing-code-formatting >}}) to fix it.
71+
72+
Some CI checks are allowed to fail:
73+
74+
- **Julia prereleases:** These inform us of upcoming issues but don't block merging.
75+
76+
- **Code coverage:** It's often helpful to inspect these, but we don't enforce specific coverage numbers.
77+
78+
- **Upstream bugs:** Occasionally CI fails due to issues in dependencies or base Julia.
79+
A good indicator is if the same test fails on the base branch too.
80+
Do ping a maintainer if you're unsure about whether a CI failure is expected.

0 commit comments

Comments
 (0)