Multi-app codebase git structure recommendations

To start, let me say that I’ve seen the comments in Multiple apps from 1 codebase? already. Apart from any template-app type concerns, I’m wondering about more structural best practices.

We’re converting our native Android/iOS app codebase to be Ionic-based. Our business mostly white-labels the same codebase for each of our customers, sometimes with occasional specific tweaks/changes.

Our old native codebases are organized such that there are development, testing, and production branches. These exist to isolate bug fixes and feature development work away from customer builds.

Each customer build exists in the same repo as the above 3 branches - as it’s own uniquely named branch. So, branches in the repo:

development
↳ feature branch 1
↳ bugfix branch 2

testing

production
↳ customer-123
↳ customer-456
↳ customer-789
...

We rebase any changes from dev -> testing -> production -> each customer branch and then release new builds.

As we’re trying to use Ionic Pro to ease deployment, this structure needs to change so we don’t auto deploy changes that we want our customers to test before pushing live to their users, so I’m thinking something like this:

development
↳ feature branch 1
↳ bugfix branch 2

testing

production
↳ customer-123-testing
↳ customer-123-production
↳ customer-456-testing
↳ customer-456-production
↳ customer-789-testing
↳ customer-789-production
...

Each customer-relative testing and production branches would map to Ionic Pro ‘channels’ that are used to auto-deploy code changes. Sounds great in theory… but:

We use Github as our canonical source control (ie. the origin repo). Each Ionic Pro ‘App’ (project) has its own git repo (hosted by Ionic). So, in order to push to those ionic git repos, I need to add their repo locally as a remote. Every developer would need to do this. Pushing branches to the wrong repo is entirely possible (unless I haven’t figured out remote branch tracking properly…?)

I have other concerns which I haven’t fully examined yet, but I’m starting to get a bad feeling about this approach.

Does this make sense to you? It might be more work to maintain each customer in the their own git repo, instead of just branches in the one repo - but perhaps less error prone?

If anyone has a system that they’ve figured out that works for them, I’d appreciate the feedback!

See:

Or you could “try to introduce a configuration system such that these differences can be removed”. Something analogous to language translation: https://softwareengineering.stackexchange.com/questions/302147/maintain-hundreds-of-customized-branches-over-master-branch

Great response - makes for some solid reading.

I’m familiar with git-flow. Much of what I describe has roots in it. However, it doesn’t actually ease the pain very much of managing multiple customers in a single repo. Like my approach, there is still room for error when dealing with Ionic Pro’s multiple repos (a repo per Ionic ‘app’).

Still, I’ll read those links a time or two more to glean possible improvements. At first glance, it feels like they followed a similar line of thinking overall.

Hey @jaddison13k, how did you end up implementing this? I was thinking of doing the same thing. My initial idea was to actually have a code base that had all the features and trigger off the package name to get the company’s specific parameters.

@trackitforward - great question. I’ve since handed it off to another on my team (who’s handling it well, and extending it as necessary), but I’ll try to recount some of the details:

  • we use Github for our primary source control
  • we have two ‘primary’ branches, (contains all features/possibilities):
    • master branch is the app ‘base’ code, where we develop and test, merge feature branches into
    • production branch is where master gets promoted to after testing, all vendors are based on this branch - this is our ‘stable’ codebase
  • we (obviously?) use ionic git as our deployment method
  • each vendor has two branches:
    • <vendor-specific ID>-master, this is based on the above production; this is where we develop and test, merge vendor-specific feature branches into (of which there should be very few!)
    • <vendor-specific ID>-production is the stable codebase for this vendor; code from <vendor-specific ID>-master is promoted here.
    • each of these branches correspond to ionic git branches that are associated with Master and Production Deploy Channels.
    • these uniquely named branches are also pushed up to Github for posterity/backup
  • if a feature request comes in from a vendor, we try to include it in the ‘core’ codebase (master & production), and have feature flags, etc
  • we have a ‘central’ configuration file where we can define various names, descriptions, colours, font sizes - to easily whitelabel the vendor specific nature/requirements
  • the app hits our server for additional configuration and dynamic data on startup, pre-display - so we can hide/gray-out UI components that have no results/data, etc.

To summarize:

  • our origin git repository is Github
  • each vendor has its own ionic git repository, with master and production branches
  • each vendor’s branches are based on the ‘stable’ branch from origin
  • all code (vendor specific as well) is in Github as well, not just ionic’s git

Here’s a screenshot of our Github repo branch listing:
40%20AM

Hope this helps - let me know if I can further clarify.

1 Like

Wow yah, that helps alot! Really detailed, thanks for taking the time to do that! Some follow up questions if you have a moment:

  • Is your central config file in master? or is different for each client?
  • If most of your code is done in central config / config’s in the app server, what’s the main difference of the client app versus the main app? Theoretically you could just have all functionality in master and just enable/disable it with config and server config?
  • Also when you have to a large update on master, do you update all the clients individually and deploy all of them? or do you just pick and choose?
  • Lastly, do you have or know of any way of deploying a bunch of the client apps at the same time?

Thanks for following up on this! My hope is to do a similar workflow!

I’m more than happy to share!

  • Is your central config file in master? or is different for each client?

The idea is that there is minimal difference between production (from the origin repo in Github) and any vendor’s repo in Ionic. The configuration format is ‘stable’, but the configuration values change per vendor and are committed to each vendor’s repo. The repo-committed ‘config’ is just a JSON or YAML doc (I don’t recall) with ‘standard’ format.

  • If most of your code is done in central config / config’s in the app server, what’s the main difference of the client app versus the main app? Theoretically you could just have all functionality in master and just enable/disable it with config and server config?

There is additional styling, different images/logos (although we try to draw from the server via API where possible). Ideally, minimal differences. In fact, any time changes are requested for a given client, we need to ask ourselves if it is something that ought to be included in the core codebase first, then ‘promoted through the ranks’. If we didn’t, it will become more cumbersome in manage the code. Technical debt, and all that.

I believe we are looking for ways to move more of the repo-committed config file settings to the API-driven, mainly so that clients can update settings without a code deployment (also more convenient/efficient for us) - but we aren’t there yet… in time.

  • Also when you have to a large update on master, do you update all the clients individually and deploy all of them? or do you just pick and choose?

Ideally, all of them; if we don’t we create technical debt for ourselves. Yes, this sounds onerous, and it likely will be (we don’t have a LOT of vendors yet, but it’s a growing list).

  • Lastly, do you have or know of any way of deploying a bunch of the client apps at the same time?

Perhaps Ionic has APIs that would enable this? But, with their auto-deploy functionality (via Channels), once you push to the appropriate Ionic repo branch, it will get distributed to app installs as per Ionic’s methodology.

1 Like