Mad, Beautiful Ideas
A Note About Perforce Triggers

At work we decided to go with Perforce for revision control. Now, I'm a well admitted git lover, so that I went along with this still kind of surprises me to an extent. Needless to say that we made the decision over six months ago when I believed:

  1. Git didn't work well on Windows
  2. Git didn't have good GUI tools for Windows
  3. PlasticSCM was lacking features that Perforce had (like triggers)

In the intervening months since we made that decision, all of those things turn out not to be true anymore. So, rather than having a flexible, easily-branched SCM, we're using a very capable, but wholly boring, SCM system. Oh well, as I said, it works very well, but there are certainly things I prefer about git.

In an effort to better use the tools available to us, we've also gone one step further and implemented Continuous Integration using Hudson. I'll talk more about Hudson at a later date, but I wanted to quickly cover an issue we'd had with the Perforce Integration with Hudson.

First, we've chosen to manage our own workspaces, simply because there are shared components between various projects. So, for a given project we may have:

        //depot//ProjectRoot/... //workspace/ProjectRoot/...
        //depot//SharedProjects/SubProject/... //workspace/SharedProjects/SubProject/...
        

This allows me to use the same Visual Studio SLN file on both our development workstations and the CI server, which is really convenient. Unfortunately, while the Hudson Perforce plugin should handle this sort of view situation cleanly, it didn't seem to be for me. I went through the code, and while I suppose it's possible the Perforce plugin for Hudson I installed wasn't the same as the code I read, we decided to go a different route.

We chose to go the route of the Perforce Trigger, setting up a Python script to scan a changeset once it's submitted, triggering a Hudson build if it determines it's necessary. I'll share the details of this script later, once I've had a chance to clean up a few things, there are a few potential performance issues, and while this works fine for our small installation, I can see issues with my current implementation if I were to try to use it on a larger installation.

However, I had a big problem when first setting up the trigger in Windows. I had set C:\Python25 in the System-level PATH. But when I set the following in my p4 triggers:

        Triggers:
                startci change-commit //depot/... "d:\p4scripts\P4CIBuild\P4CIClient.py %changelist%"
        

I would get an error on every submit, stating that the process could not be started. This was confusing, because that very command would work perfectly from a command terminal. Try as I might, I couldn't find any documentation from Perforce, as almost all the Trigger documentation was clearly targeted toward UNIX servers.

It turns out, that in order to get the Trigger to work correctly when executing a script, you need to call the interpreter first, and you need to declare the full path. Replacing the above with this:

        Triggers:
                startci change-commit //depot/... "c:\python25\python.exe d:\p4scripts\P4CIBuild\P4CIClient.py %changelist%"
        

Works like a dream. I've sent an e-mail to Perforce, which will hopefully result in their documentation getting updated, but if you're having trouble getting Python-based triggers to work on Windows Sever 2008, this is what it took for me.