I’ve spent most of the last decade working on problems in build, deployment and release management. While automation has been a focus of mine, the hard part in these domains have always been around dependency management.
A release day for many enterprise IT groups sees a number of application systems get updates. There’s a great deal of coordination required to make sure each phase of the release is executed by the right people, with dependencies between the applications accounted for.
These applications in turn, are increasingly made of multiple runtime components. These leads to dependency management challenges when service oriented architectures and the like fail to deliver on the promise of being able to upgrade just a small piece of the system at a time. Instead a change to one web service often cascades into updates to those that call it. Tests no longer validate that a single version something works. Rather, they validate that a web of dependent services are delivering desired functionality. Deciding what to promote across environments requires being very dependency aware. Likewise, at deployment time, the various pieces and parts of the system must be released in a coordinated fashion with infrastructure changes.
As we continue to look closer and closer. Our attention turns to the makeup of the runtime component of the application. Breaking it apart, we are unlikely to see just a simple standalone chunk of code that was compiled. Rather, each runtime component is made of a combination of the source code and dependencies on libraries, assemblies or headers. These dependencies can be on versioned system libraries, open source components, commercial libraries, or internally built components designed for reuse. The source code itself has interdependencies that are handled by the compiler/linker or a build script.
Despite what our friends and family tell us techies, we are good hiding complexity. The truth is, the systems we release today are extremely complex. But everywhere I look at see the same pattern repeating itself. We mask that complexity by creating composite projects. The hard part of many of our build and releases activities is keeping track of the components that make up the larger system. What version of this works with what version of that? What do we actually have in some environment? How do we get things delivered by different teams to work together? Over the next few blog entries, I’m going to look at a build, deployment and release dependencies in turn.