A quick review of both the #drupal IRC channel and the activity on the dev list is that, despite everything, Drupal’s new release system is a little confusing. And, truth to be told, it is a little confusing. In my [not so] humble opinion, this is not the fault of the implementation or the design of the system, but more the fault that Drupal users and developers have gotten accustomed to a system that sort of worked, but left a lot to be desired.
To start with, the original system worked well for Drupal core itself. This meant that a fair number of people, who primarily deal with core, never really got to get face to face with the problems that manifested on the contrib repository. But that’s a relatively small group of people, and all of them are very smart people. While it took some good arguing, the bulk of them were convinced that the new way is a better way, and thus the improvements actually came to pass.
The second matter is that a lot of Drupal contributors have no experience with formal software release cycles. And, to be fair, I think this is true in a lot of open source, though it seems to be moreso in the Drupal community than elsewhere. This lack of experience, coupled with the former difficulty in the tools, led to a very lazy, laissez-faire, method of Drupal contrib. For one, it means that a lot of people found it easiest to simply update their sites using cvs. After all, you simply need to point your system at the branch, type ‘cvs update’ and you’re done. Except of course that you don’t really have a good idea what code you have, which led to some developers getting flak for having ‘unstable’ code in a ‘stable’ branch. And so on.
None of this really matters, at this point. The new system is in, and it is now what we have to work with. Any changes to it now are going to be very minor and geared toward enhancements and refinements as opposed to any serious changes. To me, this is for the better. So here are my brief instructions on how Drupal contrib maintainers need to handle their modules.
First, you have to even be in CVS. I’m going to assume that my target audience has already figured out how to check something into CVS and has a project and Drupal has created tarballs. But I do want to explain one thing, because even people who use CVS sometimes don’t quite get this.
- A branch is a new direction of code; a fork, if you will. Your code automatically starts with one branch, and that is HEAD. When you branch, it’s a little like each repository is different. Whenever you check into a branch, the ‘branch tag’ moves up (which is how CVS describes it)…but the easiest way to think about it is that once you make a branch, it is now a different repository. Until you check into the new branch or the old branch, they happen to have the same code. But if you want them to have the same code, you will then have to perform two checkins. The most current code in a branch is often referred to as the ‘tip’ of the branch.
- A tag is a ‘stable’ snapshot of a branch. Tags shouldn’t move. They represent an instance of the code that you want to preserve. Ordinarily tags are used for releases, be they development, beta, release candidates or full-fledged releases. Using a tag lets you quickly and easily identify what code was actually running.
The Old Way
You worked in 2, possibly 3 branches, based upon the version of Drupal that your software was meant to work with.
HEAD, referred to formerly as CVS, was the newest, latest, grandest code. It was the one place you had for ‘unstable’ development code. Most often people would stay away from this, but sometimes using this code was necessary. The worst part about this, though, is that during the transition phase from one version of Drupal to another, it was (and in fact will continue to) remain impossible to tell at a glance what version of Drupal this is for. 3 times a day, the tip of the HEAD branch would be packaged into ‘module-cvs.tar.gz’ and made available for download on your project.
DRUPAL-4–6 was and will likely remain the ‘stable’ branch of code meant for Drupal 4.6. Whenever you checked into the DRUPAL-4–6 branch this code was meant to be stable. Every night the tip of this branch was packaged into ‘module-4.6-0.tar.gz’. About the only way to tell one module-4.6.tar.gz from another is by the datestamp on the download, which was often not preserved.
DRUPAL-4–7 had the exact same treatment. DRUPAL-5 was opened up but not particularly used, and was never packaged, but has the same idea.
The New Way
As a module maintainer, I have to do a little more work. Well, that’s not true. I don’t have to. In fact, if I do exactly what I did before, I’ll get relatively similar results. DRUPAL-4–7 is a branch. DRUPAL-5 is a branch. And those are the branches I check code into.
And while there’s an extra step here, I still have the snapshots that get run twice a day. But those have been renamed. They are now package into module-4.7.x-1.x-dev.tar.gz — as you can see, a little bit has been added to the filename (and the release name) to distinguish what it is. The ‘.x’ indicate sthat it’s a development version, it’s not tied to a particular version, and that the snapshot is theoretically unstable. What you get is going to depend completely on the module developer’s policy.
Now, when the system was updated, you got all of the existing DRUPAL-4–6 and DRUPAL-4–7 release for free. But you’re going to find that when you go and make your DRUPAL-5 branch that you don’t get this for free! Why not?
Well, you got them for free because the release system wanted to basically preserve what was there. When you create a new one, you have to go and create a new development release. More about that a little later.
So basically, we still use DRUPAL-4–7. But we can now also make real, actual releases. The benefits of this are many, one of the most obvious being that when people file bug reports, I can know what release they filed it against; but also, it’ll become much easier to tell when modules on your site need to be upgraded. It’s not safe to upgrade to development snapshots all the time, but if a developer actually rolls a real release, it is probably a lot safer to upgrade to it.
Actual releases are called ‘module-4.7.x-1.0–beta’, for example. 1 is the major version number, 0 is the minor version number, and as a module developer I’m allowed to put in an extra if I like. Maybe for a maintenance release or to indicate a beta, or the like. It's completely optional. I could've simply had module-4.7.x-1.0.
Super Fast How To
So what you want to know is…how do I, the module developer/maintainer, actually use the system?
- First, I commit code. cvs commit -m’this is my commit comment’.
- Now, I’m ready to create a branch because I’m about to update my module to Drupal 5: cvs tag -b DRUPAL-5 which I must immediately follow with cvs update -r DRUPAL-5 or I’ll have created a branch that I’m not using.
- I surf to my project page, and I select ‘Add new release’. The branch I just created will be visible under the Branches section in the version drop down. If it’s all that’s available it’ll be defaulted, but if I have other branches/tags hanging around that don’t have releases attached to them, they will be there too. Select the branch I just created and, and in the description I put some witty comment about how this is an unstable development branch, use at your own risk. Then drupal.org will tell me that my development branch will be available in 12 hours. I pout, because I like instant gratification. But I’ll get over it.
- Now, I’ve checked in some more code. I’m ready for people to try this. I’m going to create a release. Two steps. First cvs tag DRUPAL-5--1-0-BETA (I pick BETA because I’m not sure that it’s been tested enough and I want people to test it). Second, I go to my project, click add new release, and I select that tag. I make some notes about what I’ve changed that might matter to the consumer, and I’m done. Then drupal.org tells me that my release will be created within 5 minutes! I jump for joy, because in this case, I get my instant gratification. I can now blog post about this new release and provide links.
In the above, you’ll notice that the tag is basically some encoded information.
- DRUPAL-5 — that’s the version of Drupal. I bet you have this.
- -- That’s the indicator that’s separating the version of Drupal that my module uses from the actual version of my module.
- 1 — That’s the ‘major’ version number of my module.
- 0 — that’s the ‘minor’ version number of my module.
- BETA — that’s something extra that I can put in. I could call it the ‘underpants’ release if I were so inclined. I’d probably be scowled at heavily by the more serious developers and get a good laugh from the rest.
There’s just one piece left to talk about, and that’s the advanced usage.
So let’s use Views as an example. And let’s say after awhile I’m up to Views 1.7–2 [side note: I picked this partly out of ridiculousness, that I had Views 1.7 and I am abusing the system to have had a 1.7-2 rather than having moved to 1.8] and it’s trucking along nicely and I’m about to completely change the API. I’m going to rip it out and replace it with something 10 times better. But the downside is that every module that now uses the Views API will break. Don’t laugh, this is exactly the example that we used when we convinced people of why we need this level of complexity in the system. Because I do want to do something like that at some point.
And when it happens, I don’t want to abandon everyone using Views 1.7–2. And I don’t have to.
cvs tag -b DRUPAL-5--2
What did I just do? I created another branch. Yes, this is a somewhat confusing, complicated branch. The good news is? You’ll probably only ever see a dozen of them on drupal.org. What does this mean? Because I branched code, when I have to fix bugs or add new minor features to Views 1, I can still make a Views 1.8 release, and it’ll be independent from Views 2. What’s the downside of this?
Some bug fixes will have to go in all of these branches:
And by that time, possibly
And of course, the downside for YOU is that you now have to pick which one you’re going to use: 1.x or 2.x. But that’s the price that we’re going to have to pay so I can write new API without breaking the all the installations out there that are relying on Views and want to keep their modules up to date.