Guidelines for committing to v1 release

I’m glad that we can agree on something :+1:. Two-months is a bit short for my taste, but I’ll definitely be happier if what you just wrote is out there as community recommendation.

I’d also suggest to remind SemVer spec by linking it from the recommendation and especially re-emphasize that

Software using Semantic Versioning MUST declare a public API.

Semantic Versioning 2.0.0 | Semantic Versioning

and this is commonly done by having documentation in Julia packages.

I would say that the “public API” in a Julia package is the union of {exported symbols} and {documented symbols}. As soon as you export a symbol, whether it is documented or not, it should be treated as part of the public API.

2 Likes

I should have quoted the full clause:

Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it SHOULD be precise and comprehensive.

Semantic Versioning 2.0.0 | Semantic Versioning

I’d say undocumented exported symbols have API that is as imprecise as it could be. Of course, since it is SHOULD of RFC 2119, you can technically say there is a valid reason to do this. But I have a hard time imagining that there is a reason. You can at least explicitly put one paragraph in the documentation, something like:

All exported symbols that are not mentioned in the documentation are also public API. They are not documented as their definitions are trivial. Please see the source code src/$filename.jl.

I frequently document my internal functions, but mention that they are not part of the API.

At the moment, I don’t think that we have a single unified convention for what the public API is for Julia packages. exported symbols is a reasonable guess, except that some packages (eg ForwardDiff) don’t export anything.

One can always just make this explicit in the docs, eg

https://tamaspapp.eu/DynamicHMC.jl/latest/#Versioning-and-interface-changes-1

I agree this, I just derive a different conclusion from it: this kind of “stability” is frequently meaningless in practice, and should not be a consideration.

FOSS projects usually move forward whenever someone has the time and inclination to work on them, so it is impossible to predict these things in advance. And if SemVer is adhered to, no one is actually harmed by a even complete redesign of the API three times a week: they can just choose not to upgrade, or skip versions, or do whatever they like.

Users of a package just have to consider the benefits and costs of breaking changes: they may require some minor change or a major refactoring, but there are usually benefits too: the new API can be simpler, the code faster, etc. If you find that a package breaks things every other week for no good reason, then just don’t upgrade, and consider using something else in the long run.

But if there are great benefits, I don’t actually mind breaking API changes frequently. It is hard to come up with a rule merely based on time.

1 Like

Clarification: I was referring to “documentation” in the manual as part of the public-facing API, not internal documentation.

2 Likes

I agree that FOSS projects may be slowed down in an unpredictable manner. But I don’t think it means that we can’t put reasonable upper bound in the speed for breaking things. If you don’t want to limit your development speed of the project, you can always stay in 0.x versions while still getting the compatibility checks by the package manager.

Also, there is no need for prediction. When you have time working on the FOSS project, you just have to recall when the previous major bump was and compare it to the recommended timescale.

I didn’t mean to suggest that time is the only thing that matters. If a new API is so good and if it fixes a very common complaint from users, maybe it is reasonable to make a breaking change in a relatively short time window. Or, maybe you just want to release something and don’t mind maintaining two release branches.