Shipping software updates should be simple and foolproof, especially when you ship new builds all the time like I do with CraftStudio.
Case in point: I have released 35 client updates since CraftStudio Alpha was released in early June, and before that I already had shipped over 50 CraftStudio builds. If shipping a build took an hour, I’d already have spent over two weeks simply getting things out the door instead of working on new features! And probably much more since there would be plenty of occasions to get things wrong at every stage.
Here’s how I made the process completely painless and (mostly) automated.
Whenever I want to release a new build of some component, all I have to do is increment the version number in a file, commit and then tag the change in Mercurial so that I have a trace of it in my repository’s history. This is important so that I can track which features, bugs and fixes have made it into each release.
Building CraftStudio for release is a matter of selecting the proper build configuration in Visual Studio (aptly named “Release”) and clicking the Build button. That’s it.
- All content files will be processed thanks to the very awesome XNA Content Pipeline
- All projects (including the server, client, launcher, master server and runtime) and dependencies will be built
- The obfuscator will automatically run once the compiler has done its work
Note that this is pretty standard stuff, I didn’t have to put any special effort into this.
I wrote a script called “MakeRelease” which takes care of packaging.
- It starts by extracting the version number of each component (client, server or runtime) and checking if there is already a package with that version number. If there is one, no action will be taken for that particular component.
- If there is no package for this version yet, then the script selects all the required files from the build folder (with some globbing to automatically grab required files and ignore those that don’t need to be shipped) and creates a ZIP archive with a name ending with the version number.
- The script then displays a log of what has been done for each component.
This mean I can safely run the script multiple times and packaged builds will never be overwritten. This is important, because builds should be set in stone: you don’t want to have several variants of the same package with the same version number.
The script is written in Python and uses only portable libraries so it runs on all desktop platforms. I recently added a parameter which allows me to specify which platform to package for, for the upcoming Linux and OS X ports.
Publishing is a matter of uploading the packages (I simply use FileZilla for that) and restarting the master server so that it detects the new packages. This could be fully automated if only I could find a portable SSH/SFTP Python library that doesn’t rely on external tools being installed.
To write the release announcement (which I usually have ready before publishing, obviously), I look through all the changesets from the previous version’s tag to the current version’s tag.
On the user’s side, the CraftStudio launcher requests the latest version numbers for each component from the master server before starting the client. If there is a new version of some component available, it downloads the ZIP archive, unpacks it and delete the old one.
The launcher itself can be upgraded if required. When the master server reports a different protocol version than the launcher, the launcher assumes a newer version must be available and offers to upgrade. If the user accepts, then the launcher downloads the newest installer package, starts it and closes itself.
I hope you enjoyed this short tour of how CraftStudio updates are made and get delivered to your computer