Mono-repo or multi-repo? Why choose one, when you can have both?
Many are still debating “mono-repo” or “multi-repo”. For those of you who have no idea what a mono or multi repo is, I’m referring the the organization of your repositories. Traditionally, there have been two camps, with supporters on both sides on the aisle.
Mono-repos are a source control pattern where all of the source code is kept in a single repository. This makes it super simple to get all of your employees access to everything in one shot. Just clone it down, and done. Multi-repos on the other hand, refers to organizing your projects each into their own separate repositories.
I was surprised when I learned that Google, one of the most advanced technology companies in the world, uses a monorepo. I was used to making many repositories, one for each of my services, and with good reason.
- I hire contractors frequently, and giving them access to ALL of the source code doesn’t make sense, and isn’t secure. Having multiple repositories makes it easy to give access to subsets of repositories on a “need to code” basis.
- I set up Continuous Deployment for my projects. It’s much easier to let each repository have it’s own process for being deployed. When using a mono-repo, there needs to be additional logic for sorting through the directories that make up the different projects within the mono-repo.
For me, it seems obvious, but, what happens when you get to 10 different repositories.. 20? 50? 100? more? It gets very difficult to manage. No one wants to git clone a whole bunch of different repositories one at a time.
I’m not the first to encounter this issue, and from the struggle emerged a (now defunct) tool called gitslave. Gitslave provided a new command gits
which could be used just like git, except across many directories at once. The “meta-repo” was born. And today, thanks to Matt Walters, there is a new, even simpler choice: meta.
Meta is a plugin-powered tool whose purpose is to make building distributed systems/libraries/codebases easier. It does so by providing commands which can be executed against any number of projects in your solution at once. Need to create a branch on five projects at once?
meta git checkout -b feature/my-new-branch
Want to commit all changes for the feature you are working on that spans several services?
meta git commit -m 'made the feature'
meta
will loop through the projects you’ve added to your .meta
file, and apply the command to each of them. However, meta works for much more than just git. In fact, all meta really does, is organize your projects into a JSON file, and provide an extensible core for easily providing new functionality through plugins. meta ships with a few plugins built into the core, and more are available from the community.
Below I will walk you through the simple process of creating your first meta-repo.
Making a `meta` repository
First, let’s install meta
.
npm i -g meta
Then, let’s create a new meta-repository.
mkdir yourProject && cd yourProject
meta init
This creates a .meta
file with the following content.
{
"projects": {}
}
Next, head on over to GitHub and create a new repository and push our repo.
git init
git add -A
git commit -m “init meta repo”
git remote add origin git@github.com:you/yourProject.git
git push -u origin master
Adding projects to your meta repo
Now, all you need to do is add some projects, which is as simple as running the following command, provided by the meta-project
plugin. Let’s imagine we have a few services we want to add: userService
, graphqlService
, and appService
.
meta project add userService git@github.com:you/userService.gitmeta project add graphqlService git@github.com:you/graphqlService.gitmeta project add appService git@github.com:you/appService.git
The above will modify the .meta
file and .gitignore
file to look like the following:
// .meta
{
"projects": {
"userService": "git@github.com:you/userService.git",
"graphqlService": "git@github.com:you/graphqlService.git",
"appService": "git@github.com:you/appService.git"
}
}// .gitignore
userService
graphqlService
appService
Commit, and push.
Sharing
Now, when you have a new developer to onboard, you can simply give them access to an appropriate meta-repo. You can make many meta-repos if you’d like. One for DevOps related projects, one with everything for an admin, one with just services for a backend engineer, or even a meta repo full of other meta repos. Slice it any way you’d like!
To clone a meta repo, simply run the following:
meta git clone git@github.com:you/yourProject.git
To sync the additional repos defined in the .meta
file, run:
meta git update
Conclusion
When asked multi-repo or mono-repo, my answer is usually “meta”.
If you are interested in how to build your own meta plugin, check out my other post “Developing a plugin for meta”.
Interested in hearing MY DevOps Journey, WITHOUT useless AWS Certifications? Read it now on HackerNoon!