One trick that works nicely is to embed the build information into each component as a part of the build process and at the time of collation into the release get the information back out.
There are a number of possible ways of embedding the information into each component, (exact details may depend on the language that the component is written in):
- As a part of the fetch/checkout process create one or more files containing the branch/tag & version information.
- At build time query the version control system and the status of the directory to either ensure that there are no uncommitted changes or to include the fact that there are and process this into similar files. Personally I prefer to allow builds of modified code with the fact that it is modified embedded so as to allow the developers to test their code.
The generated file(s) are then used to embed the information during the build process, note that it is a good idea to use a different file extension to the usual ones so that you can tell the version control system to ignore it.
If the built components are executable in the build environment they can each be given a
--version option that reports their name and the generated information then exits. They can then all be run with the --version flag and this can be piped into a file that is an input to your BOM.
If your components are not executable in your build environment, e.g. you are cross compiling for an embedded target, then you can mark your version information and extract it from the binaries. One standard way of doing this is to use the old
sccsid id string format, e.g. for C/C++ you could use:
static char sccsid = "@(#)ls.c 8.1 (Berkeley) 6/11/93";
This consist of the characters
@(#) followed by your version information and terminated with any of a null character or a newline.
You can then use the
what utility to extract this information from the binaries at any point in time and again pipe it into your BOM. What is available on a number of operating systems or you can write your own.
If your build environment is Unix/Linux based then generating this information can be done with
sed and pipes or you can do it quite simply with python scripting as is creating your BOM from the resulting information. Jenkins can happily run python scripts as a step in your build/release processes. Additionally your tests can use the same facility to embed the exact version tested into the test results.