Our current method of creating a product release is to tag all of our component repositories with the next appropriate version and then modify a master build script with these new version numbers for each component. The master build script will then be run and it will perform a SCM checkout of each component, then modify the AssemblyInfo.cs file so that the compiled .exe (or .dll) has the correct version number, and then compile the component. All of these components are then coalesced into a product release which is "versioned" with a pure marketing decided number.
So our process falls under the "tags drive the build" description, but I am not certain that is the best method. Specifically, where I see this failing us is if we were to integrate our release build into the CI process, it seems like it would be backwards.
Not just that, but where in a typical release-management process does the decision for the new component version numbers come in? Someone has to decide when component A goes from 2.1.4 to 3.0.0 and if library B should change from 6.3.2 to 6.3.3 or 6.4.0. Where are these version numbers stored and at what stage are they decided? Currently, we make these decisions at the "last moment" and they are stored in the master build script. The master build script itself is versioned and is tagged with the "marketing" version number.