Hacker News new | ask | show | jobs
by web007 1371 days ago
You get everything for free, but you also have to take EVERYTHING.

I work primarily on "cloud" stuff, so 95% of my world is Terraform and other (asynchronous) configuration-based stuff. I feel the pain more acutely because of the overhead imposed on my work that shouldn't exist, vs compiled software deployed for end-use-cases where there is an expected burden of build + test.

Because monorail, all of my changes go through the same tests and restrictions and review as executable code. We have to "pass the build" - and waste resources testing all of that executable code for every change. It's even worse being in a pseudo-regulated space (SOC2 / similar) since anything applied to any sub-part of the repo applies to everything.

You can argue that parts of the repo can use different processes, but then what's the benefit of keeping it all together vs having different repos with those different processes?

The only reason monorepos are better today is that git sucks at multi-repo (think submodules), and humans suck at separate repos. It might also be that nobody takes it far enough, where you have separate repos for everything, but that feels like the first two points both together; maybe tooling and/or a massive DevEx team could make that work. I'm pretty sure something would need to supplant git for subtree repos to work and make sense, until then the monorepo is the least bad option of all the bad options.

2 comments

Ideally a monorepo doesn’t run all tests all the time, but only the ones that need to based on a given change. Unfortunately, there’s no great tooling for this. Bazel works well sometiems depending on your project, and Nix is sort of in the same boat. Both are beasts to learn. But I think it’s mostly a solvable problem, and the reason there aren’t better offerings is because of the sheer effort involved in building these systems.
We actually do use bazel, where I have a love-hate relationship with that as well.

It's incredibly painful and a lot of overhead to bazel allthethings. Using bazel to define dependencies is another double-edged sword where you can get them enumerated, but EVERYTHING has to use it. You can't check out a repo and go, you have to check out the repo and bazel whatever you're trying to do. No "I know Python, let me venv && pip install -r requirements.txt or pipenv ...", now you have to incant the magic bazel incantations instead of native stuff. Same for NPM/Yarn, Rails, Go, etc. And that's assuming there's good support for your language/framework of choice; a Rails acquisition a few years ago was awful because bazel didn't have good support for it.

We have a double digit number of humans on our DevEx team dedicated to this stuff, and it's still painful. That speaks to the effort you're talking about.

On the love side, being able to query for "what does this dep trigger a rebuild for" without guessing is about as good as you can get, and having a requirements.txt-equivalent that magically packages itself into a standalone set of files with minimal effort is pretty sweet. The overhead to get from 0 to 1 is a lot (like... A _L_O_T_), but 1 to N is easy.

>and waste resources testing all of that executable code for every change

If it's a waste why is it even running those tests? That's it's own problem.

Of course, but how do you solve that problem in the general case?

When everything lives next to everything else it's harder to draw the line around the blast radius of a change. If there was a repo boundary, that's a really easy hard constraint.