input-output-hk / cardano-engineering-handbook

A handbook covering cross-project policies and information for projects in the Cardano Open Source Consortium
14 stars 0 forks source link

Write a policy about Haskell package versioning #14

Open michaelpj opened 1 year ago

michaelpj commented 1 year ago

Notably, are we using PVP or not?

lehins commented 1 year ago

I suggest all Haskell packages should use PVP, while packages in other languages use SemVer or whatever else is appropriate for that language.

Reasons for me suggesting PVP for Haskell packages:

In other words, we should not add more confusion and just go with the same approach that is used everywhere else in Haskell ecosystem.

eyeinsky commented 1 year ago

The release policy draft leans toward SemVer at the moment, although it does say we could easily go either way.

michaelpj commented 1 year ago

I'm also in favour of PVP. My argument is roughly:

When looking at a package version for a Haskell package, I am normally looking at it in the context of many other Haskell package version numbers, which will be using PVP. So the least confusing thing is to also use it for my version numbers, otherwise you have to remember which packages use PVP and which don't.

This is in contrast to executables, where the version numbers might appear in e.g. a package distributor's versioning system. Then it might be less confusing to use SemVer. I could see the argument for versioning e.g. the actual cardano-node executable with SemVer.

andreabedini commented 1 year ago

:+1: for PVP (for Haskell packages at least).

zliu41 commented 1 year ago

The downside of PVP is Haskell executables used primarily by non-Haskell users, e.g., node. If we use 4 components, then users will have to deal with 4 numbers in their heads. If we use the first 3 (major.major.minor), it would be easily confused with SemVer.

lehins commented 1 year ago

@zliu41 I don't think cardano-node follows PVP, nor does it have to. In this context we are talking about Haskell packages as libraries. The edge case of Haskell package as executable can be documented and we can enforce SemVer or PVP, it doesn't really matter as long as it is documented. In fact having the same version for a package that has a library and executable at the same time does not make sense. Often a breaking change to the CLI does not mean there is a breaking change in the library, and vise versa, the breakage in the library can have no impact on the end user of the executable.

then users will have to deal with 4 numbers in their heads.

Who cares? There are plenty of ~terrible~ complicated versioning schemes out there, for example have you seen one for Windows operating system? Version is mainly intended for the developers that work on that piece of software, while curious users can read the documentation to interpret what the version means if they do care about it.

zliu41 commented 1 year ago

In fact having the same version for a package that has a library and executable at the same time does not make sense

It seems standard practice to have all components in the same git repo versioned and released in sync. In fact I'm not aware of a counter example. Even for only two components where one depends on the other, versioning and releasing them independently can be quite complicated.

while curious users can read the documentation to interpret what the version means if they do care about it.

They probably indeed can. I have the tendency to avoid telling users to do something non-standard if it's avoidable.

lehins commented 1 year ago

It seems standard practice to have all components in the same git repo versioned and released in sync.

In my practice it is quite the opposite. Here is a short list of mega repos of top my head:

All of them have many packages with different versions. Some have the main product that is versioned with git tags as well (eg. ghc, hls)

lehins commented 1 year ago

I have the tendency to avoid telling users to do something non-standard if it's avoidable.

There is nothing wrong with telling user to read some documentation.

zliu41 commented 1 year ago

Here is a short list of mega repos of top my head

Thanks, good to know. Yes, one can release a downstream package A without simultaneously releasing an upstream package B if they want to, but since they are in the same repo, the CI always tests A and B at the same commit (unless they have additional tests for different combinations), which makes it natural to release them together.

Anyway, the versioning scheme decision is one that's cheap to reverse so I wouldn't mind either way.

michaelpj commented 1 year ago

In fact having the same version for a package that has a library and executable at the same time does not make sense.

This is a bit of an annoyance with cabal, since they'll have the same version so long as they're in the same package. So we might have to do something a little silly like move the cardano-node executable to a separate package so it can be versioned separately. But that's not the end of the world.

ch1bo commented 1 year ago

Okay. Seems like I need to refer to some comments made so far:

This is in contrast to executables, where the version numbers might appear in e.g. a package distributor's versioning system. Then it might be less confusing to use SemVer. (@michaelpj)

Exactly, this is why the hydra-node should also be versioned in a way that our users do understand it. They won't be familiar with Haskell necessarily and consume it via a docker image.

There is nothing wrong with telling user to read some documentation. (@lehins)

Why introduce friction, if it can be avoided?

Who cares? (@lehins)

I do care. About my users. And I do use versions & changelogs to communicate to them.


Seems like we are getting ourselves into the same old version policy discussion as Hackage is facing. Yes, PVP has been specified before. But Semver is just more popular and every developer knows about it by now. Our users are developers and not necessarily Haskell developers. So why not using the most widely adopted thing?

If we even need to write a policy about it. Maybe its sufficient to be clear that 1) there needs to be a versioning scheme and 2) its documented in the respective repositories?

Fact is, your users will tell you if your versioning does not make sense. As a developer writing Haskell and using Haskell libraries, I don't care if my upstream dependencies are using PVP or SemVer - I know both - as long as its used consistently (switching is not so cheap as you might think @zliu41). BUT, I will not impose Haskell's NIH syndrome on my users downstream if you let me.

michaelpj commented 1 year ago

@ch1bo what do you think about the ugly compromise of:

  1. Version libraries with PVP
  2. (Optionally) version executables with SemVer, create a new package if necessary to put the version number on

I think that lets us do the familiar thing for everyone at the cost of being weird.

ch1bo commented 1 year ago

Well.. all our packages contain executables, so I think we get to do SemVer then? It would force us to version some packages different than others despite they getting released at the same time from the same repo, which we otherwise would have not (e.g. a hydra-sdk containing a Haskell sdk next to the hydra-node package). But this would be "just" some internal work on separating things (which we otherwise wouldn't) and doing more tags like documenting two versioning policies in our repository.

Let me ask though: Why? Why do we need to decide on one versioning policy (for all cardano haskell packages)?

michaelpj commented 1 year ago

Well.. all our packages contain executables, so I think we get to do SemVer then?

I think the idea is that you're bound by the two constraints:

That may necessitate splitting packages, and is weird, yeah. It's an ugly compromise.

Let me ask though: Why? Why do we need to decide on one versioning policy (for all cardano haskell packages)?

Because otherwise it's going to be a huge pain figuring out what anything means? People will put X < 3 instead of X < 2.4 because they don't realise that the second component is a major version. Do you really want to have comments on top of each of your version bounds saying "uses SemVer", "uses PVP", so you don't mess it up? It's just confusion for no benefit.

lehins commented 1 year ago

@michaelpj 100% support you here. I think using SemVer for executables and PVP for libraries is a very good compromise.

People will put X < 3 instead of X < 2.4 because they don't realise that the second component is a major version. Do you really want to have comments on top of each of your version bounds saying "uses SemVer", "uses PVP", so you don't mess it up?

I am really surprised that everyone who suggests SemVer for Haskell libraries do not realize this problem!

I do care. About my users. And I do use versions & changelogs to communicate to them.

@ch1bo I did not suggest you should not care about users, please do. I do however suggest stop worrying about useless stuff like this and calling it friction: "users will have to deal with 4 numbers in their heads" (which is what my comment was about).

michaelpj commented 1 year ago

I'd like some input from @HeinrichApfelmus , since the wallet is currently (uniquely?) using date-based versioning.

HeinrichApfelmus commented 1 year ago

I'd like some input from @HeinrichApfelmus , since the wallet is currently (uniquely?) using date-based versioning.

I very much prefer the PVP.

Date-based versioning has the drawback that you can't know the version number until the day you actually release the package. 🔁 🤪 I mean, it's serviceable, but I'd be happy to switch to the PVP. I'll ask for advice from the team.

SemVer has this weird corner-case of 0.b.c versions being allowed to break backwards-compatibility. Also, the major version number of becomes very large, e.g. Firefox is at 101.0.5. Back when the PVP was decided for Hackage, I made an argument on the mailing list to have two numbers A.B for specifying the major version. I still believe in that argument (can't find it otoh, though).

michaelpj commented 1 year ago

Note that our current version bounds policy permits omitting upper bounds, so we wouldn't be fully compliant with the PVP so long as we do that. But we could follow the MAJOR.MAJOR.MINOR version number convention and the conditions for bumping version numbers.

michaelpj commented 1 year ago

See further discussion about speculative upper bounds in https://github.com/input-output-hk/cardano-ledger/pull/3381