There are several possible approaches, each with pros and cons, depending on your preferences, experience, actual development process, app structure, etc.
- Using multiple branches in a single VCS repository.
The shared code would go in a master branch. Each customer-specific artifacts and customisations (possibly including code deltas as well) would go in a customN branch pulled off the master branch. The fix could be initially committed into one of these customN branches (for example in order for the customer to validate the fix or multiple iterations of a fix before they're propagated to all customers). If so then the fix would have to be double-committed to the master branch. Or it could go directly in the master branch. From there the fix would be propagated to all the other customN branches via syncs, most of which should be trivial. Followed by a re-build of the respective customer package in a workspace which contains the respective customN repo branch.
- Building a customer package would be done in a workspace containing 2 repositories:
- a
shared repository containing the shared code
- a
customN repository containing the customer-specific artifacts
The fix would only be committed once, in the shared code repo, distributing the update to a customer would simply mean pulling the respective customer workspace (which automatically gets the updated shared repo) and building the package.
It might be possible to just symlink the shared repo inside a workspace instead of instantiating a copy of it, potentially speeding up the package builds.
This approach doesn't work (well) if you need per-customer code deltas as well.
- Use a "nested repository" approach, if your VCS system supports it. For git see Nested git repositories?. I didn't actually use this approach, IMHO it's unnecessarily complicated.