Release Management – Version Control Best Practices

deploymentrelease-managementversion control

We recently experienced a deployment issue where it turned out that the version objects were not in sync in one of the environments.

We have a large database group and different teams have different responsibilities and ownerships – I might code on schema X, Y, Z but I also will have dependancies on objects owned by other groups. This is the same no matter what technology – java libraries having different versions and what not.

My aim is to have something be in a webpage or a database table or something that I can see that for object A I have version X installed in Production, X + 1 in UAT and QA, and X + 2 installed in DEV.

How do other folks handle this? How do you pick up version changes? Do you rely on SCM? Build numbers? Hash value of the source code?

I'm interested in managing version consistency across technologies – java to db for instance.

Best Answer

From what I see, you are referring to configuration management, however, if there are different parts to your system and you want to put them in version control to keep them consistent, the best I can think of is:

A) To maintain a file (in XML, JSON or whatever serialization format you like) where you describe what version of each thing you need for each component.

{
  "JAVA": ">1.7.0_05",
  "MYSQL": ">=5.0.28",
  ...
}

Have each component import this file into constants and assert their values against the environment they are running on, there are ways to get this information from wherever your application is deployed. If they don't match the desired values (or value ranges even), throw a warning.

B) If you have different components and you use something like Mercurial for version control, then you could use something like the subrepository feature, where your top/manager repository essentially does configuration management, this is, the top repository will keep track what versions of each component are being used across in a given moment in time. Picture this:

project_x #250 <- top repository at changeset 250
|--component_a #1232 <-component a at changeset 1232
|--component_b #23 <- component b at changeset 23
|--component_c #32 <- component c at changeset 32

And then with component_a's new version (say 1233) you need a new version of component_c, but not component_b, so you update component_a and component_c and commit project_x to a new version that records those changes

project_x #251 <- top repository at changeset 251, recording 1233 and 33 for a and c
|--component_a #1233 <-component a now at at changeset 1233
|--component_b #23 <- component b at changeset 23
|--component_c #33 <- component c now at changeset 33

Keep in mind that it might not be the best idea to store java or mysql itself in version control, but as mentioned earlier, this would be effective configuration management for project-independent components.

If you want to keep track of Java, MySQL, etc, "A)" provides a good mechanism to assert that configuration.

The "project_x" repo can have a development branch and a production branch where it tracks different component configurations.

In summary

Have a manifest to which you can code against and assert your configuration, and for your project independant components you can use Mercurial subrepos (or git submodules) to keep track of the version configuration among them.

Related Topic