Hello @wilsonyeo93 - interesting question!
For much of your basic internationalisation, hopefully you can use some libraries in your tech stack to deal with things like multi-language strings. I would guess that you already do this.
For payment methods, etc. it is worth thinking about how you might refactor those parts of the code so that either you could use polymorphism, plugins, or other forms of extension (depending on your tech stack) to manage the design complexity and bring everything into one repo.
This would hopefully mean that as a minimum, you could push out those region-specific parts of the code into separate repos and have one
main repo containing everything that can be shared between regions.
Of course, I am say this without seeing the code base, so I may be very naïve, however, I do think it should be possible for you to refactor to avoid copying and pasting code between repos by hand.
If you do want to explore this route, two books I have found extremely helpful are:
If you find that you really can’t avoid keeping everything in separate repositories, then I think you have two options:
Use one monorepo like these examples. In a monorepo you put code that would normally be separated into different repositories into one repository. You might have the different code bases separated into different directories, for example. (To be pedantic, your code isn’t /quite/ a monorepo because all your code bases are related, but I hope you can see where I’m going with this idea).
This is sometimes used by developers who are writing an iPhone/Android/Windows phone app in three code bases but pushing to one repository.
The advantage of this for you, would be that when one project merges into the default branch, the code will immediately be available to developers in all the other projects.
You would probably want to use rules:changes in your
.gitlab-ci.yml to manage the different pipelines for each project, and to make sure that one project only triggers pipelines in the other projects when that is really necessary.
You may also want to separate each project CI config into its own file. This is what GitLab does in its main repository. This helps with readability, but it also keeps your Git log clean, because you can separate out commits that only relate to one region.
Monorepos are currently popular, but not without controversy, partly because of the obvious added complexity they bring.
The other option might be to stick with something like your current set of repositories, and use multi-project pipelines to deal with automatically re-testing the code bases when one project merges into the default branch.
For example if you have:
---- region A
----- region B
and a developer merges into the default branch of
mainrepo, this might trigger a pipeline in the two region-specific repositories, which would pull the code from
mainrepo, and test/build/verify/… the code for regions A and B.
Perhaps this is what you are already doing, but maybe you can use it to automate more of your development process?
For example, if you changed absolutely nothing else, would you be able to get the pipeline to automate cherry-picking commits from one repo into another, so that your developers didn’t have to copy and paste by hand? This old blog post and this SO answer show how you can run Git operations withing a pipeline that push back to your own, or another repo.
It’s hard to say more without knowing the context, but in my (very opinionated) view, the problem you have is not that you have separate repositories, but that your repositories share common code. That’s not really a GitLab problem as such, but some of the pipeline features mentioned above might help you with it.