naturally suspicious person, I would typically grub around in the code looking at differences between the release version and the previous version and trying to match changes with the official list. This would frequently turn up extras, or omissions. All in all, a rather painful activity, especially as it was usually left until near the deadline when things were being madly rushed out the door.
Life is much easier if task-based development  is followed.
- Firstly the release contents are planned - the list of open bugs and planned new features is tracked and they are assigned to developers. No code changes are made without associated tasks (this doesn't need to be enforced by a tool though it needs to be made easy to find out, since appropriate carrot and stick techniques work wonders).
- Then you need some simple workflow to track code fixes and whether they have been coded, tested and verified. The linking of tasks to code changes (or change sets ideally) should be made as easy as possible.
- Finally, it is helpful to have good tool support to track associations across release lines. See the discussion by Gareth Rees in "Can we ship yet?" .
Practice makes perfect...
Not surprisingly, a key way to release better is to do it more frequently! Frequent releases highlight the problems, and force you to address them. Manual steps or painful processes that are possible once or twice a year, become unmanageable on a more frequent basis. This alone focuses the mind and leads to improvement.
Agile Development lends itself to this with the following practices (see  and ):
- Small, Frequent releases (regular cycle)
- Release Plan
- Iteration Plan
- Continuous Integration
- Test-driven development
- Unit testing
- Acceptance testing
- Code should always work!
Don't forget to balance these practices against your current project by taking into consideration your organization's "culture" and project's context. Boehm and Turner's "Balancing Agility and Discipline"  and Larman's "Agile and Iterative Development: A Manager's Guide"  can prove helpful in doing this.
Automation is a basic requirement for frequent releases. Automation of unit testing in agile methods leads to much greater confidence that the system works and that bugs have not been introduced. Automated builds catch integration problems early making them much easier to fix. Automation of the production of release notes as discussed above makes the project much more controlled and less subject to surprise. Automation of installs and upgrades are also key requirements for systems these days.
A frequently underestimated part of Agile methodologies, is that of "information radiators" - a central whiteboard or similar for the team where current status and progress are shown in an easily visible manner. This makes it obvious what needs to be done, and who is currently doing what.
See "The Pragmatic Programmer" by Hunt and Thomas  for more recommendations on automation (including their new book on Project Automation ).
Also, the BCS has an event on the 12th October 2004 addressing Agile methods and CM (see http://www.bcs-cmsg.org.uk ).
One company I have been involved with over the last 2-3 years produces a large treasury system used to trade billions on a daily basis. When I first started working with them, they had 15 clients spread over 3 versions of their system (which had many, many configuration possibilities). The system had a VB front end and a 4GL backend. The interesting thing was that they had a single development workspace to work on all 15 releases of the system. This meant that a customer using an older release who wanted a single bug fix was forced to