Early in 2007 the other Twisted developers in Cambridge and I had a meeting about what we should do about Twisted releases. Things had been a bit chaotic since the split of Twisted into multiple components, and releases were still done on an irrelegular basis.
At the meeting we decided that a time-based release would be ideal. Given that, we would move to a time-based versioning scheme somewhat similar to Ubuntu's; the next release will be Twisted 8.0, which is the first release in 2008. That is, the version numbers will be (year - 2000) point (incremental per-year number starting at 0) point (patch level, if any, starting at 0).
We also discussed our deprecation policy, which we still haven't finished documenting, and decided to make it explicitly time-based as well. An API that is to be deprecated will be marked as such and will be supported for N months or years before being a candidate for deletion. We still need to come up with a convention for how the deprecation is presented to the user, and what information the deprecation message will contain, not to mention the value of N.
But none of these changes were possible; releasing was too tedious a process, fraught with numerous hiccups and changes to the procedure on every release. It would be extremely stressful to try to do this with any rapid regularity, leaving the release manager an insane fool constantly muttering about tarballs and web servers.
So while we knew we needed to switch to a more automated release system, the project had stalled before it even got on its feet. Fortunately, Jonathan Lange visited last month and "inspired" us to organize this project. We sat in the board room with a whiteboard and listed everything that needed done in order for regular releases to be possible. Since then, progress has been slow but steady; at least once a week someone is committing changes towards these goals (thank you, therve).
But we need some more help. If you know how to write software test-first, then please help out. Come join #twisted or contact me to see how you can help. Hopefully 2008 will see many Twisted releases.
Thanks so much for posting this, by the way. I think the community benefits from deliberate communication.
I do like Ubuntu's date-based version scheme. But I think part of the reason it works for them is because Ubuntu is a ginormous aggregate of things. Twisted is a component. Well, yes, it's actually an aggregate of lots of components, which makes this argument clumsy, but as a developer, a Twisted package is a dependency.
So from that perspective, it would be nice to be able to look at two version numbers and not have to wonder "oh, the major version number incremented, did they change all the APIs or did they just do a few bugfixes and New Year's happened?"
Rubygems has written a bit on something they refer to as a Rational Version Policy, and it lets you write dependencies like ">= 2.3, < 3.0", which is a nice feature, I think.
not have to wonder "oh, the major version number incremented, did they change all the APIs or did they just do a few bugfixes and New Year's happened?"
That is the thing, though. We won't change major APIs without a strict time-based deprecation period, period. There is no need for the "major API change vs minor API change" == "major version vs minor version". In fact, the only reason we don't release with something like "Twisted 2008-05-24" is that it would terrify users. Oh, and it's hard to remember and type.
Yeah, but, if your deprecation period is anything less than, say, the support lifetime of an Ubuntu LTS release, I'm still going to have the same question, aren't I?
I'm trying to decide if it's a valid assumption that all developers are tracking every release of your package. Maybe. Maybe not.
I think if you're tracking LTS, you will *definitely* have to care about API changes in Twisted when you upgrade.
Now I'm imagining a web application which lets you select two releases and get a list of all API incompatibilities in between those releases and thorough descriptions of what users should do about them.
What I should do here is tell an actual real-life story.
Plone, or some component thereof, depends on a library I maintain, python-openid. Through the magic of <strike>prismatology</strike> setuptools, plone (or plone.openid or plone.app.openid or somesuch) installs pull the python-openid record from pypi, download a package, and install it.
This means that if I upload a new release to pypi that breaks the API used by plone, I get some very unhappy mail from wichert, because he will have had to deal with a bunch of "oh the plone installer is broken" bug reports.
Fortunately, wichert is able to specify the dependency such that it only gets 2.0.x versions of python-openid, so I was able to upload a 2.1.0 (which removes a deprecated bit of functionality) without wichert killing me.
Again, I think that it wouldn't be so bad if you had a non-strict deprecation policy. If you did, you would have done a release that supports the existing API while printing a deprecation warning (or otherwise informing the user that he needs to update his code), so that wichert would have quite some time to update his code.
I do think I see the fundamental difference, though. If you do the major.minor thing, you can have users pretty much assume that no matter how long you keep putting out releases in the "3.0" series, they will keep compatible with all of your code, and if they ever break any APIs it'll be when they switch to 4.0. The annoying thing about that from the *developer's* perspective is that they need to have a single cycle for deprecations, and not allow any API breakages until the major version number bump, even if many years have passed. I also get the feeling that most projects that do the major.minor thing are pretty lax with their guarantee that no APIs will break during the major series. To name an example, Python.
Uh, I failed at grammar in the last post. Assume I said "strict" instead of "non-strict".
Post a Comment