Skip to content

Instantly share code, notes, and snippets.

@pbrisbin
Created February 16, 2018 00:31
Show Gist options
  • Save pbrisbin/4b31ce9cac904cb7ce515ee1fa50969d to your computer and use it in GitHub Desktop.
Save pbrisbin/4b31ce9cac904cb7ce515ee1fa50969d to your computer and use it in GitHub Desktop.
Versioning Haskell: Semver <> PVP

I personally prefer Semver. I think it's reasonable, simple, and makes sense. But as a good Haskell citizen, I'd like to be PVP-compliant as well. Here is a bit of a graphic showing how the two systems are almost the same:

PVP:            A . B     . C     . ...
Semver:             Major . Minor . Patch
                    ^       ^       ^
                    |       |       |
                    |       |       ` increment for other changes
                    |       |
                    |       ` increment on non-breaking change
                    |
                    ` increment on breaking change

Basically, PVP's A is useless from a compatibility standpoint. It's just a bystander in the "increment A.B for breaking changes" rule. So I just set it to 0 and never change it. The remaining 3 components then follow Semver.

So for any of my packages, you can interpret versions as: 0.Major.Minor.Patch

@jcornaz
Copy link

jcornaz commented Apr 23, 2020

Okay, I think I know what I will do.

I follow semantic versioning just the "normal" way. And my automated release process only has to be slightly more complex than it usually is.

For each release:

  • Generate the change log, create the git tag (semver style), and github release (as usual)
  • If, and only if, the version is a stable version (not starting at 0 and not suffixed with a pre-release tag):
    • publish to hackage by prefixing the version number with 0.. Or maybe I will pick something different in order to remove the "unstable" feeling that we have when looking at version number starting with 0. Maybe I will prefix it either 1. or 42.

And finally, I simply don't publish non-final versions to hackage, forcing users to depend on the git repository directly.
For versions that are not published, I don't write any version number in the cabal/stack file.

Not being able to share work in progress is a shame, but I don't see what else I could do...

@pbrisbin
Copy link
Author

do you create tag after semver or PVP version? In other words, do your tags contain the leading 0. ?

It contains the leading A..

Regardless of how I'm bringing a SemVer perspective, or being PVP compliant, the version is the version: whatever string comes after version: in my package.yaml. Intention or perspective doesn't matter once it's been set for the package.

Okay, I think I know what I will do.

That's a nice process. You're sort of leaning into them being two different things and using SemVer generally, but "converting" to a PVP version specifically for Hackage. This is different than my goal, which is to just have one versioning scheme that makes sense through both lenses.

I agree it's probably not great to intentionally not be PVP-compliant in any pre0.1.0.0 versions. I'll continue to consider it and probably do it less often, only in extremely not-used packages. For anything with users that may be impacted I would probably just push 0.1.0.0 sooner and follow PVP thereafter. I'm like you in that I work in the open and publish immediately, regardless of polish.

@jcornaz
Copy link

jcornaz commented Apr 23, 2020

Regardless of how I'm bringing a SemVer perspective, or being PVP compliant, the version is the version: whatever string comes after version: in my package.yaml. Intention or perspective doesn't matter once it's been set for the package.

Well, we cannot write arbitrary version numbers after version: in package.yaml. Stack fails to build if I write 1.0.0-alpha.1 in my package.yaml.

That's why I have to include how to deal with this limitation in my process :-/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment