"This is becoming a pain for management, and it will only get worse as more and more customers start using our Software."
The only way to really solve this part is to make sure your software has an architecture that supports settings as a layer on top of your main product. Ideally, they will simply be runtime configuration parameters (colors, logos, and on / off are ideal for this). If you get (or want) a very large number of customers, push the configuration directly into the main product and give customers the opportunity to configure themselves.
During the upgrade, you create (and verify) the main product once and create custom versions, simply linking (referring) to the already built main product as a library. You can have each client in a separate assembly, or you can have one build process that generates updates for all currently supported client assemblies (the latter is probably better for more clients). If you have a version of "vanilla", you can create it as part of the kernel or together with client versions, it will depend on your specific case.
Depending on your technology, it may be possible that a customization level will be created regardless of the main product. In this case, customer recovery will rarely be necessary (perhaps only for certain significant changes) - you can simply refer to the updated main product at runtime. For deployment to the client, you will only need to deploy the updated kernel if you have a deployment method that supports this.
It is difficult to say in more detail, not knowing your platform, but you have kindly kept this question agnostic.
source share