This document describes some best practices for collaborating on repositories. Following these practices makes it easier for contributors (new and old) to understand what is expected of them. It should be linked to in the README.md.
There are many good practices that this document does not cover. These include other members of the wider community reviewing pull requests (PRs) they are interested in, and maintainers encouraging and supporting people who open issues to make PRs to solve them. This document facilitates these other good practices by clarifying what can seem a mysterious process to those who are unfamiliar with it.
This document is also only intended for community practices, it is not suitable for solo projects with one maintainer.
Interactions with people in the community must always follow the community standards,
including in pull requests, issues, and discussions.
This page offers some further guidance on conventions that can be helpful when collaborating on projects. This is an expansion on the Collaborative Practices, with more details and extra guidance. Anything detailed here should be considered less important than the main Collaborative Practices.
PRs that move code should not also change code, so that they are easier to review.
If only moving code, review for correctness is not required.
If only changing code, then the diff makes it clear what lines have changed.
PRs with large improvements to style should not also change functionality.
@test_broken
macro.You should not squash down commits while review is still on-going.
You should help review your PRs, even though you cannot approve your own PRs.
Review comments should be phrased as questions, as it shows you are open to new ideas.
suggested change
feature.
Following the Collaborative Practices, when there are unreleased changes in the repository for an extended period of time the version number in the Project.toml should be suffixed with -DEV
.
This makes it clear that there are unreleased changes.
Which is useful for many things, including quickly understanding why a bug is still occurring, and working out if a bugfix may need to be backported.
Some more details on the use of -DEV
.
After/during/before the PR making the first change of the release, the version number in the Project.toml should be changed to the intended release number should suffixed -DEV
.
-DEV
for a non-breaking change.
-DEV
suffix and make a new release once this PR is merged.pkg”dev Foo...”
to install particular unreleased versions to an environment, Pkg ignores suffixes to the version number.
Pkg treats 0.7.0-DEV
identically to 0.7.0
.
This means you can update the [compat]
section of a group of packages and test them together.5.4.0
then we can still go back and release 5.3.1
.Do not panic, these things sometimes slip through.
It is important to fix it as soon as possible, as otherwise people start using the breaking change, and reverting it later causes more problems (c.f. Murphy’s law).
To fix it:
Once the change is reverted you can take stock and decide what to do. There are generally 2 options:
Consider a package which is currently on v1.14.2. I made a PR to add a new feature and tagged release v1.15.0. The next evening, we get bug reports that the new feature actually broke lots of real uses.
Maybe I changed what I thought was an internal function, but one that was actually part of the public API; maybe I accidentally changed the return type, and that was something people depended on. Whatever it was, I broke it, and this was not caught in code review.
To fix it, I revert the change, and then tag release v1.15.1. Hopefully, I also can add a test to prevent that part of the API being broken by mistake.
Now I look at my change again. If I can add the same functionality in a non-breaking way - for example, make a new internal function for my use - then I would do so and tag v1.15.2 or v1.16.0 depending on what had to change. If I cannot make an equivalent non-breaking change, then I would have to make the breaking change and tag v2.0.0.
Many of these guidelines can and should be enforced automatically.
Everything on this list can, in theory, break users’ code. See XKCD#1172. However, we consider changes to these things to be non-breaking from the perspective of package versioning.
Exceptions may be replaced with non-error behavior. For instance, we may change a function to compute a result instead of raising an exception, even if that error is documented.
New exports: Adding a new export is never considered breaking.
However, one should consider carefully before exporting a commonly used name that might clash with an existing name (especially, if clashing with Base
).
A <: B
to A <: B <: C
or A <: C <: B
.
This includes adding a supertype to something without one, i.e. with supertype Any
.Union
constant may be replaced by an abstract type that covers all elements of the union.print
/string
or show
/repr
on a type may change at any time.
Users should not depend on the exact text, but rather on the meaning of the text.
Changing the string representation often breaks downstream packages tests, because it is hard to write test-cases that depend only on meaning (though unit tests with mocking can be shielded from this kind of breaking).(This guidance on non-breaking changes is inspired by https://www.tensorflow.org/guide/versions.)
As mentioned at the top, community repositories following ColPrac, should link to it in their README.md
.
One way to do that is with a GitHub badge.
[](https://github.com/SciML/ColPrac)
In many-cases ColPrac serves in the places of a CONTRIBUTING.md
, having all the common guidance that you would otherwise put there.
If your package has its own CONTRIBUTING.md
then you should also link to ColPrac there, and indicate how the contents of ColPrac relates to the CONTRIBUTING.md
.
For example by stating:
We follow the ColPrac guide for collaborative practices. New contributor should make sure to read that guide. Below are some additional practices we follow.