Many organizations treat release management as a nonexistent field or an “also-ran.” Reproducibility is near the bottom of the list of concerns, let alone thinking about other parts of the discipline. But, release management fundamentals still apply regardless of the size or type of your organization. By starting with centralized distribution, an organization can make massive strides towards managing releases.
Understanding Centralized Distribution
Centralized distribution means there's a single, known source for distributables. It means that nothing is released without hitting the named server and that customers can never have a patch, a file, a complete install, or even a document that has not been sent to the centralized distribution server. Further, through centralized distribution, you help ensure that an organization has a single source of truth for its binaries, much like revision control is for sources. Most importantly, it means that everything sent to the customer (distributables) can be tracked down to a single source.
This doesn't mean that all files are distributed from a single server or over a single protocol. Rather, centralized distribution means that all distributables are made available from a single known system, presented to users as if the distributions are centralized. This system could be a single desktop, a server with a SAN, or even six servers acting together, sharing files over HTTP, RSYNC, FTP, and every other protocol under the sun. The mechanism doesn't matter nearly as much as the fact that distribution is centralized—that nothing releases outside of this single source of truth.
Starting at the Beginning
Centralized distribution is easy to achieve even if the build process isn't reproducible, automated, or existent. Simply place all binaries on a single server. Whether developers copy files or the build process automatically does it for you, the end result is the same: "Where do I get it?" conversations go away. Communication immediately flows more easily, and builds no longer have to be passed around.
Improving Your Distribution
Ideally, build systems would be responsible for ensuring that distributables end up on the central server. Centralizing distribution in the following way can also help reduce development time by simplifying the aftermath of a build. Every company has a different concept of build, but most agree on the notion of source code compiling executables. In an ideal world, a build would produce at least the following outputs:
- Cut—The entire build output, potentially for repackaging into an installer
- Installer Symbols—Whether you use PDBs (C#) or pre-stripped binaries (C++), having symbols around from a production build reduces the time developers have to spend rebuilding the product.
- Documents—All PDFs or text files that would be released with the product. This forces revision control for documentation as well.
- Logs—Even after the fact, build logs are surprisingly useful.
- Build details file—A file (in my case an INI, since it's cross-platform and nearly all languages have a great INI support) with details about the build: build server, source location (revision control), revision, build date, and build number.
Tracking Sources of Distribution
Regardless of what ends up in distribution, we need the ability to know where it came from. More importantly, we're probablygoing to want to do something with that data programmatically, so having reasonably generic cross-platform access is key.
This is where we reuse the ancient technology called property files.
Property files are files of the format variable=value, with each variable appearing on its own line. In terms of build data, I like to store product name, revision control location, revision, branch, version, and date information. Here's an example:
product=My Mythical Product
As property files are easy to manipulate in most languages and can be directly loaded in Python, Perl, and Java, we'll have a very low barrier to entry with regards to their use by others. They're also easy to generate, meaning that regardless of how new or old the target build platform is, there won't be issues creating them. Finally, they're also in a format that can be easily hand-crafted. Even if your organization has yet to institute production builds or if developers are manually crafting builds, this file format is easy to create. Plus, it prepares us for a worst-case, lightweight release process.
Knowing precisely what went out the door is a big part of releasing software—especially enterprise software. The steps described above definitely help, but having a lightweight release process based on our distribution, takes it a step further. I'll stress that the process I'm going to outline is not an "ideal" release process; rather, it is a lightweight one. The important part is the reliance on centralized distribution, which ensures that nothing can leave the building without at least some amount of tracking.
Lightly releasing when following the notions of centralized distribution is a three-step process:
- Copy the full release (including sub-parts, such as the cut) into the release tree within the centralized distribution service, using a distinct versioning system.
- Make a tag in the revision control system.
- Let everyone know that Elvis has left the building.
Maintaining a single tree of releases within the centralized distribution server achieves the same benefits with regards to releases. There will never be a question regarding release location, release contents, or which release is correct. The tag in revision control helps others in the future find the original source. While the properties file from above will contain that information, developers are more attuned to searching revision control rather than a server tree.
Finally, your Elvis email. Releases are the best part of developing software. Sharing the joy is a great thing! Inform the expanded team, and let them know where they can pick up the release.
Ultimately, the software release process becomes an automated process. At the end of the day, we're going to want to have checksums, code signing, and many other things. But, for now, we've achieved lightweight distribution with minimal impact to the development process.