[libvirt] [RFC] Version numbers outside of releases

Our current practice when it comes to bumping the version number for libvirt is to do so immediately after a release, eg. right after 3.4.0 is released later today someone will push a commit that changes configure.ac to use 3.5.0 instead. As a consequence, builds made from master will always carry the release number of the *upcoming* release, so from a versioning point of view there is no way to tell eg. 3.4.0-rc2 or even the final 3.4.0 release apart from a random build made at a random time from master during 3.4.0's development cycle. In particular, when creating RPMs from a git clone, you'll end up having to use either 'dnf install' or 'dnf reinstall' depending on whether or not you already installed any build during the current development cycle. I suggest we change our habits slightly: * right after X.Y.0 has been released, bump the version number to X.Y.90; * bump the version number to X.Y.91 for rc1, X.Y.92 for rc2 and so on; * only bump the version number to X.Y+1.0 as the release is being prepared, then go back to the first step and move on with development. This would make sure each step in the development cycle gets its own version number, and as a pleasant side effect you'll always be able to install newer builds using 'dnf install'. Comments welcome! :) -- Andrea Bolognani / Red Hat / Virtualization

On Thu, Jun 01, 2017 at 01:13:05PM +0200, Andrea Bolognani wrote:
Our current practice when it comes to bumping the version number for libvirt is to do so immediately after a release, eg. right after 3.4.0 is released later today someone will push a commit that changes configure.ac to use 3.5.0 instead.
As a consequence, builds made from master will always carry the release number of the *upcoming* release, so from a versioning point of view there is no way to tell eg. 3.4.0-rc2 or even the final 3.4.0 release apart from a random build made at a random time from master during 3.4.0's development cycle.
In particular, when creating RPMs from a git clone, you'll end up having to use either 'dnf install' or 'dnf reinstall' depending on whether or not you already installed any build during the current development cycle.
This is really a bug in the RPM spec file used to build from pre-released code. The recommended Fedora RPM practice for version numbers in packages from GIT snapshots, is that the release field start with a "0", and have a date stamp (and possibly git short hash) appended. The first RPM following the formal release would have a release starting with a "1". This way, every build from git you do is always newer, and the final release RPM is newer still.
I suggest we change our habits slightly:
* right after X.Y.0 has been released, bump the version number to X.Y.90;
* bump the version number to X.Y.91 for rc1, X.Y.92 for rc2 and so on;
* only bump the version number to X.Y+1.0 as the release is being prepared, then go back to the first step and move on with development.
This would make sure each step in the development cycle gets its own version number, and as a pleasant side effect you'll always be able to install newer builds using 'dnf install'.
Comments welcome! :)
This is not that attractive from POV the language bindings. eg in the Go code, I need to make usage of the new APIs conditional at compile time. For example for the new APIs added in 3.4.0 I have code like func (v *Stream) RecvFlags(p []byte, flags StreamRecvFlagsValues) (int, error) { if C.LIBVIR_VERSION_NUMBER < 3004000 { return 0, GetNotImplementedError("virStreamRecvFlags") } n := C.virStreamRecvFlagsCompat(v.ptr, (*C.char)(unsafe.Pointer(&p[0])), C.size_t(len(p)), C.uint(flags)) ...snip... } and int virStreamRecvFlagsCompat(virStreamPtr st, char *data, size_t nbytes, unsigned int flags) { #if LIBVIR_VERSION_NUMBER < 3004000 assert(0); // Caller should have checked version #else return virStreamRecvFlags(st, data, nbytes, flags); #endif } The suggested versioning scheme would require changing all these version numbers checks to 3003090 is rather unpleasant IMHO. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Thu, 2017-06-01 at 12:21 +0100, Daniel P. Berrange wrote:
This is not that attractive from POV the language bindings. eg in the Go code, I need to make usage of the new APIs conditional at compile time. For example for the new APIs added in 3.4.0 I have code like func (v *Stream) RecvFlags(p []byte, flags StreamRecvFlagsValues) (int, error) { if C.LIBVIR_VERSION_NUMBER < 3004000 { return 0, GetNotImplementedError("virStreamRecvFlags") } n := C.virStreamRecvFlagsCompat(v.ptr, (*C.char)(unsafe.Pointer(&p[0])), C.size_t(len(p)), C.uint(flags)) ...snip... } and int virStreamRecvFlagsCompat(virStreamPtr st, char *data, size_t nbytes, unsigned int flags) { #if LIBVIR_VERSION_NUMBER < 3004000 assert(0); // Caller should have checked version #else return virStreamRecvFlags(st, data, nbytes, flags); #endif } The suggested versioning scheme would require changing all these version numbers checks to 3003090 is rather unpleasant IMHO.
Well, that shouldn't be needed for released versions of the bindings as they would of course depend on a released version of libvirt, but I see how it would make it more difficult than necessary to develop the bindings in parallel to the new libvirt version. So I guess disregard my proposal :) -- Andrea Bolognani / Red Hat / Virtualization

On Thu, Jun 01, 2017 at 02:05:04PM +0200, Andrea Bolognani wrote:
On Thu, 2017-06-01 at 12:21 +0100, Daniel P. Berrange wrote:
This is not that attractive from POV the language bindings. eg in the Go code, I need to make usage of the new APIs conditional at compile time. For example for the new APIs added in 3.4.0 I have code like func (v *Stream) RecvFlags(p []byte, flags StreamRecvFlagsValues) (int, error) { if C.LIBVIR_VERSION_NUMBER < 3004000 { return 0, GetNotImplementedError("virStreamRecvFlags") } n := C.virStreamRecvFlagsCompat(v.ptr, (*C.char)(unsafe.Pointer(&p[0])), C.size_t(len(p)), C.uint(flags)) ...snip... } and int virStreamRecvFlagsCompat(virStreamPtr st, char *data, size_t nbytes, unsigned int flags) { #if LIBVIR_VERSION_NUMBER < 3004000 assert(0); // Caller should have checked version #else return virStreamRecvFlags(st, data, nbytes, flags); #endif } The suggested versioning scheme would require changing all these version numbers checks to 3003090 is rather unpleasant IMHO.
Well, that shouldn't be needed for released versions of the bindings as they would of course depend on a released version of libvirt, but I see how it would make it more difficult than necessary to develop the bindings in parallel to the new libvirt version.
So I guess disregard my proposal :)
We should none the less fix 'make rpm' to use the best practice release numbering scheme for pre-releases Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Thu, Jun 01, 2017 at 01:13:05PM +0200, Andrea Bolognani wrote:
Our current practice when it comes to bumping the version number for libvirt is to do so immediately after a release, eg. right after 3.4.0 is released later today someone will push a commit that changes configure.ac to use 3.5.0 instead.
As a consequence, builds made from master will always carry the release number of the *upcoming* release, so from a versioning point of view there is no way to tell eg. 3.4.0-rc2 or even the final 3.4.0 release apart from a random build made at a random time from master during 3.4.0's development cycle.
In particular, when creating RPMs from a git clone, you'll end up having to use either 'dnf install' or 'dnf reinstall' depending on whether or not you already installed any build during the current development cycle.
I suggest we change our habits slightly:
* right after X.Y.0 has been released, bump the version number to X.Y.90;
* bump the version number to X.Y.91 for rc1, X.Y.92 for rc2 and so on;
* only bump the version number to X.Y+1.0 as the release is being prepared, then go back to the first step and move on with development.
This would make sure each step in the development cycle gets its own version number, and as a pleasant side effect you'll always be able to install newer builds using 'dnf install'.
Not really. That is true only if you are building such RPM once between release and the next rc. If you do that twice, you need to do reinstall anyway. It could be fixed with appending the last two or three segments of the commit description. The package built now would be: libvirt-3.4.0-rc2-5-g316022183b0f or libvirt-v3.3.0-164-g316022183b0f I mean yeah, that numbering of yours is not bad, I'm all for it, (although I like .50, like QEMU has, better ;). The biggest issue is how to do this automatically. I don't know if DV has a script to do some things, but if he does, we could make it part of the tree and bump the numbers automatically (we would benefit from that even now, before this change). I'm for the change, but just for FYI, I think you can always make the install when specifying the package with a path, can't you? Like this: dnf install ./libvirt-*.rpm
Comments welcome! :)
+1 (is that how comments work nowadays?)
-- Andrea Bolognani / Red Hat / Virtualization
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (3)
-
Andrea Bolognani
-
Daniel P. Berrange
-
Martin Kletzander