You can do it using any dependency management system like Maven, internal artifact repository for production-ready components (like Nexus) and release branches for hot-fixes (if you have to ship updates in a near realtime way).
Using this approach you get:
- Testing of any complete release (including integration tests) which you ship to a customer.
- Dependency-broken versions are not to build, because you can switch to production-ready repository for pre-ship build.
- You can mark production packages with SCM tags and know what exactly is pushed to a customer.
- You can simply make a diff between shipped and current package.
In few words: Divide development and production releases and you protect yourself to build a dependency broken production package.