As I mentioned in an earlier post, I have been messing with developing a plugin for Hudson, which is in my opinion the best open-source continuous integration tool out there. It’s phenomenally easy to set up, it does most everything you need it to do right out of the box, and has a large number of plugins available to extend its function, such as support for Emma, Cobertura, PMD, Checkstyle, and even more unexpected things such as Nant and NUnit, Jira, even Ruby (which I’m sure my friend Mike just loves).
But it doesn’t have something I would like to see. I’d like to be able to define (in my job config) a descriptive name and location in the workspace of specific artifacts generated during my build - a sort of “General Publisher”. For example, if my build generates a test PDF, I would like to have a link titled “Test PDF” show up in the central part of the build results page similar to the “Test Results” link, or to the left like the console output links. Same for if my build generates numerous HTML files (there have been numerous times when I needed to do XSL transforms off of source XML files to make a documentation mini-site similar to Javadoc).
Now, of course there is a way to do something kinda close already. You can tell Hudson to keep the desired files in the “Archive the Artifacts” box under “Post-build Actions” and it will make a link for your artifacts on the page. But there’s a couple ways in which this falls short. One is that you don’t get a descriptive name for what you’re archiving and what Hudson displays. A second is that if you want to display a generated multi-page site you need to put the name of the base directory in the “Archive the Artifacts” box — and when Hudson sees multiple artifacts in the list, you basically just get a clickable directory listing of the archived files, from which you need to pick out “index.htm” or whatever to really view the web pages.
So I decided to try writing a plugin to do what I wanted.
Hudson plugins are built using Maven. They provide a Maven project file which can be used to download everything you need to start building plugins. This was my first real experience with Maven. After downloading Maven and the starting pom.xml file, I wasted a whole lot of time not being able to download the files needed to make a plugin — but this was nobody’s fault but my own, since my firewall was not configured to allow the network traffic needed. Once I sorted this out and started downloading large numbers of files to my local repository, I found that there were many items still not visible, and that there were version conflicts, so that I had to manually download specific versions of files and install them to my local repository.
Once I escaped Maven’s clutches, I started working with it. Architecturally speaking, the Hudson source is quite elegant. You implement specific, well-named interfaces (”Builder”, “Publisher”, etc.), and make some HTML fragments (in the form of Jelly files) that Hudson assembles together to form the UI — merging your fragments right in with the stuff that Hudson ships with, so it looks exactly like the rest of it.

One nice aspect of the whole thing was that you hook things together by naming them the same. The code and the html are associated by having the same filename (except the extension). Any fields you define for your plugin’s UI that need to get persisted just need to have a property defined with the same name in the plugin’s DescriptorImpl (a nested class that defines the plugin to Hudson rather than some obnoxious XML file).
Pretty soon I had it doing something very close to what I wanted. It was hooked into the job config page, and saving my settings. It was making links on the left hand menu, with the text I wanted, and when you clicked the links, it opened the main page of the HTML “site” that my build had generated. But there was a problem. My site had multiple directories and the urls in my site’s links and img tags were relative — but the link being rendered in Hudson had a trailing slash (e.g., “foo/bar/index.html/”) which made the browser treat the page as a directory rather than a page, and all the links broke. It wasn’t my plugin that was putting the slash there — Hudson appends it.
“Well, that sucks, but I’ll just change the file in Hudson that renders that link.” This meant more Maven (ick). Started downloading - and downloading - and downloading. Nothing would build properly. Version conflicts and unavailable yet required resources all over the place. At this point I said “screw it.”
Now, in fairness, my problems were really related far more to Maven than Hudson — but that’s the build system that was chosen. Even the primary author of Hudson, Kohsuke Kawaguchi, acknowledges what a pain Maven is to deal with at the Hudson developer wiki. He insists it was a deliberate decision made with good reason, and I take him at his word. But it actually amazes me that a product as good as Hudson comes out of that mess, and it’s enough to make me turn my back on trying to get involved. I simply can’t devote that kind of time wrestling with Maven just to write 50 lines of code.

Entries (RSS)
[...] an earlier post I wrote about my experiences trying to write a plugin for Hudson. In that article, I wrote about [...]
Hi, can you post some of the source code you wrote for this. I have similar need.
thanks!
Wish I could. I never did finish that plugin, and I don’t have the source anymore since I didn’t finish it. Sorry!