Principals
- Automate everything except what you can't.
- Verify everything that you can.
- Manually triggered, automatically executed.
- That the build is a single step kicked off by the developer and/or release manager, including all end product output artifacts
- The source code and all required scripts and configuration are checked into some sort of source control
- That the state of the source code and software system is of a sufficiently high quality for release and well tested, both automatically, and by users/QA
Things that can't be completely automated because they're human by their very nature:
- Version if it's arbitrary, or confirmation of generated if not.
- Tag name if it's arbitrary, or generated from version if it's not.
- Tag comment (if possible, some SCMs allow this, others do not)
- Release announcement / release notes intro
- When to actually do the release, and what to do the release from.
- Quality of the build (build broken/not, unit tests executed, fail if not all there, unit test coverage sufficient/not, style checks, bug finders, etc)
- State of the repo (all files checked in, no modifications, no un-ignored files, up to date with remote repo, remote repo up to date with local copy)
- If version is configured/hard coded, incrementing of version, otherwise requesting it from the release manager/dev
- Committing of any changes such as version number/name/date stamp, if applicable
- Tagging of the repository using name and comment provided by the release manager/dev, possibly with defaults suggested
- Change log coarse (pulled out of issue tracker, or from commit comments if disciplined)
- Change log fine (pulled out of SCM)
- Build and packaging of application or component (binaries, installers and other distributables)
- Documentation from doxygen/javadoc/markdown/latex/etc into end formats such as pdf and html
- Roll forward of any configured versions etc to the next development variant
- Upload and distribution of documentation and components to either a staging location, or the final location
Ideally none, however sometimes that's not possible. In particular cross platform code that must be built on its native platform. Often you can build for windows on Linux or vice versa, but for Mac OS X, it's regularly required to use OS X to generate certain final products (eg DMG or PKG files, and native compilation against cocoa libs). In such cases, if possible, use the platform that allows the most platforms to be built for at a single time, which ever that is. For the balance, they can have binaries built from the SCM tag after-the-fact.
Release Steps
Our goal thus far has been to make this section of the guide as short as possible by engineering the system to fail for us if something's not 100% right.
- Ensure all files are checked in, or removed.
- Ensure the changes are on the server.
- Ensure changes from the server are local too.
- Ensure the system builds successfully from a hard clean environment
- Ensure all automated testing executes cleanly and returns successful results
- Smoke test the app or library by using it in as many ways as possible, preferably against a script/list of things to check/do
- Once happy, initiate the release by executing your release script/process
- Answer/fill in details requested by the release process such as version number, tag name, tag comment
- Watch the release unfold/drink coffee/drink beer/drink wine/drink water
- Download resulting binaries from automatic upload locations onto other operating systems and verify that they look correct (versions and other ids correct, etc) and work properly
- Assemble any manual documentation steps such as issue tracker dumps
- Make the announcement linking to the uploaded materials such as binaries and documentation
- Initiate the process of building other OS variants (such as OS X) from the tag, or having others build from the tag on your behalf
In the next couple of posts I'll run through two examples of the above in action.
Fred.