Geek

Olympic Build and Packaging Pipelines

When setting up an automated continuous delivery pipeline for our current project, we decided to use RPMs and Yum – the native packaging and software updates platform of our staging, UAT and production environments – instead of more Ruby-esque solutions like Capistrano.

There were several reasons behind that, but by far the most important was the affinity we noticed the operations staff already had with RPMs and Yum: all of the system packages were being taken care of using it, with some deal of auditing thrown in: has this file changed since we installed the package? Why?

Making a decent RPM out of a Rails (or Sinatra) project wasn’t very hard: a bit of head-scratching and a few passes through Maximum RPM later, we had something we could work with.

The main headaches were working out which packages were necessary to build the RPM (the BuildRequires part), figuring out how to reliably install all of the gem dependencies from bundler into the packaged RPM (bundle install --deployment helped), and which changes needed to be made to the application to rely solely on environment variables set by /etc/default/[app]. This way, we wouldn’t have any configuration that could vary across environments coming from the package itself.

The next step was setting up a marathon of tests for those RPMs. They already contained unit tested code, and we built more obstacles: functional and integration tests, performance micro-benchmarks, metrics analysis and some manual inspection in UAT. With each step weeding out bad candidates, only truly excellent builds can get to production.

To be able to easily visualize how excellent our builds were, we came up with a simple and effective naming scheme, in time for the Olympics: precious metals.

A unit tested RPM would start out in the “tin” repository. Another step in the pipeline gets triggered and deploys it to a smoke test machine. If that works, it gets promoted to the “bronze” repository. Functional and integration tests cause it to be promoted to “silver”, and so on through “gold” (ready to go) and “platinum” (in production already).

To the operations staff, this makes a lot of sense: the production machines are fetch updates from “gold”, UAT environments look at “silver” and so on. It’s trivial to configure Yum to do that – chances are you alraedy did it when setting up your distribution –, and its output is very easy to read and understand when something goes wrong.

Looking back at the Capistrano days, my only regret is not having done this sooner!

Geek
General
Work

Comments (0)

Permalink

Balances between agile and usability

Jakob Nielsen on the use of Agile methods:

Agile’s biggest threat to system quality stems from the fact that it’s a method proposed by programmers and mainly addresses the implementation side of system development. As a result, it often overlooks interaction design and usability, which are left to happen as a side effect of the coding.

In my experience, mostly as a developer, it is really easy to dismiss interaction and usability design for two reasons.

The first comes from the developers themselves, trading prettiness and consistency of user experience for cleaner and sounder domain models whenever they go in opposite directions. Signs this is happening are developers crying YAGNI when the stakeholders ask for a zoomable chart or DTSTTCPW when a sortable, paginated data table is required.

Next time you see a system where there are enormous listings of items with no search, pagination or sorting, ask the developers if they have ever watched a typical user at work; chances are they have only thought about the system as they see it: since the testing dataset is usually small, a loop spitting out a bit of HTML for each element isn’t such a big deal. They might even say there’s a story to implement all that lovely stuff later on, but they just get moved over and over to the bottom of the backlog barrel… until everyone watches a person struggle to find needles in a tabular haystack all day. This is a simple example – almost too trivial actually, but one I’ve seen happen way too many times.

Changing the perception that usability is just the icing on the cake draws attention to all that wasted time to the stakeholders, and should enable a much better dialogue: developers get to write an application users will love, stakeholders spend their money wisely on something that will actually increase return on investment (as productivity gains), users feel empowered and less likely to make mistakes. Everybody wins.

The second reason UI design and usability get overlooked, and this is the one Frank alludes to in his latest post, is that some agile teams rely a bit too heavily on the stakeholder’s descriptions of what is wanted. It instantly reminded me of one my favourite quotes from Cars:

Lightning McQueen: All right, Luigi, give me the best set of black walls you’ve got.

Luigi: No, no, no! You don’t know what you want! Luigi know what you want. Black-wall tires, they blend into the pavement, but these white-wall tires, they say look at me, here I am, love me.

Lightning McQueen: All right, you’re the expert.

I find it rare for the stakeholders to know exactly what they want, down to what the end-user experience should be like. Thinking about a reasonably-sized application at this level of detail can only be done as a series of small, incremental steps and having someone on the team who is really obsessed about making every single pixel on the screen be in the right place. And if you read the last sentence and thought “well, that’s not exactly the role of my stakeholder!” you get the point: the stakeholders should not have the final word as to what the usability and experience details should be, in the same way they simply delegate to and rely on the expertise of the development team to flesh out the details of a persistence layer.

Have look and feel expertise in your team, and trust it, in the same way you would trust the database or network connectivity expertise.


Business
Geek
General
Work

Comments (4)

Permalink

Git Iterator

I wanted to generate some visualizations of our project’s growth, so I decided to put together a little shell script that looked at the output from git log to spit out some metrics.

So git-iterate was born: run anything through your entire project’s history, and get the results in something easily converted into a beautiful chart!

It does that by running git-reset --hard $COMMIT for every commit in the repository, and then calling the script given to it as the first argument. It passes the commit ID to the script too, so this:


git-iterate echo

…will generate a list of all your commit IDs, most recent last.

The code is on GitHub, as usual. I’m running a few stats on some projects I have access to, and will upload a few charts as soon as they’re ready. Meanwhile, feel free to send me the output of this:


git-iterate 'echo `flog app` `flog spec`' # if needed, replace "spec" for "test"

…and I’ll chart those for comparison as well. Also, it shouldn’t be difficult to port git-iterate to other source control systems (all of them have a checkout command, right?) and, if you do that, make sure to plug it in the comments.

Have fun! :)


Update: fresh off the oven, here’s Rails’ total lines of code. Neat, huh?

Geek
General

Comments (9)

Permalink

Binary Guitar


The Binary Guitar is a little experiment (took about a day or two to put together) I played with a couple of months ago, and I thought it was fun enough to share.

Installation is seriously clunky – I have never tried it on anything but MacOS X Leopard running on a MacBook Pro so far, and even then there are lots of moving parts, but if you go through the pain of setting it all up, you should have some pretty decent sounds coming out of a USB Guitar Hero Controller (mine’s the X-Plorer, which comes with Guitar Hero II for the Xbox 360).

You’ll need:

Running:

  1. Install everything
  2. Open PD to MIDI.mipi in MidiPipe
  3. Open Binary Guitar.pd in PureData
  4. Go to Pure Data / Preferences / MIDI settings… and point the MIDI inputs and outputs to MidiPipe
  5. Open Binary Guitar.qtz in Quartz Composer
  6. Connect the X-Plorer Guitar. If everything’s working correctly, the Quartz Composer viewer should be black (rather
    than a checkered pattern)
  7. Open GarageBand, select your favourite virual instrument.
  8. Rock on!

Grab it in my github repository.


Geek
General

Comments (1)

Permalink

JavaScript: Put everything in a namespace

Yes, everything. Put it in a namespace. Everything. No exceptions and no excuses, unless yours is “I have just been thawed.” In this case, I want to be the first to warmly welcome you to the 21st century.

Here’s a simple and reasonably OK way to do it and be nice to your friends, other libraries and the world at large:


var Article = Article ? Article : new Object();
Article.title = "Report: School Shootings Help Prepare Students For Being Shot In Real World";
Article.save = function() {
alert("Saving " + this.title);
}

You could save a few keystrokes, though. Just use the object literal notation directly:


var Article = Article ? Article : {
title: "Report: School Shootings Help Prepare Students For Being Shot In Real World",
save: function() {
alert("Saving " + this.title)
}
}

These two last examples are great if you’re not that concerned about exposing the ‘title’ attribute to the rest of the world. If there is a chance that problems could arise if some other piece of code changed it directly, there is a solution:


var Article = Article ? Article : function() {
var private = {
title: "Report: School Shootings Help Prepare Students For Being Shot In Real World"
};

var public = {
getTitle: function() {
return private.title;
},

save: function() {
alert("Saving " + this.getTitle());
}
}

return public;
}();

I find this a bit hard to get used to, after so many years of developing in languages that explicitly allow me to set access control. It makes sense, though: by creating an anonymous function that returns the object I want to define, and then immediately calling it (note the ‘()’ at the last line), I can hide whatever I don’t want other parts of the code to see – it’s all tucked away in the local context of that anonymous function.

Geek
General

Comments (20)

Permalink