How do you handle versions of the software you build?

There are many ways to handle this issue. It seems so simple, but there are subtleties that generally seem to cause problems sooner or later. A naive way to handle the issue is to give the software the version you want it to have when you release, say "1.0", and then keep writing, building, and testing until you think it's ready for release. But then how do you tell which build is the final one? Sooner or later, this will bite you and you'll grab the wrong version. "Which version 1.0 should we ship?"

How do you name your release versions? You can call them "1" "2" and "3" if you want. It's more common to have major and minor release versions, e.g., "1.0" "1.1" 1.2" "2.0" "2.1", to differentiate minor enhancements from large changes. Then there are various strategies for marking bug fix releases or other changes to the build:

I don't have a "single best practice" to recommend, but I do have a list of recommendations to keep in mind.

Let me know your favorite practices.