A lot of teams use tools that can do this sort of thing OK out of the box. I've set up CI to only run affected tests and use incremental builds in the past. My current project has incremental CI.
The core problem is actually dev teams. Every time I've tried to implement incremental CI when I wasn't in a position to force it through, people fought against it, complained, moaned etc until higher level management gave in. The problems were:
1. People liked the feeling of every test passing every change. It made them feel safe and like they could point the finger at CI if something went wrong, because if every test passed it's definitely not their fault, right? But this leads to slow builds and then they complain about that instead. However this is preferable because slow builds are the project manager/TL's problem to solve, not theirs, so there's a built-in bias towards over-testing.
2. If there's any issue with the build system that causes one test run to affect another in some way (shared state of any kind), then incrementality can cause hard to understand flakes. Sometimes tests will just fail and it'll go away if you force a truly clean rebuild. Devs hate this because they've been taught that flaky tests are the worst possible evil.
3. Build systems are generally hard-wired for correctness, so if you make a change in a module that everything transitively depends on, they'll insist on retesting everything. This is reasonable from a theoretical perspective, but again, leads to very slow builds and people finding ways around them.
4. Work-shifting. Splitting stuff out into separate build systems (separate repos is not really the issue here), may appear to solve these issues, but of course in reality just hides them. Now if you change a core module and break things, you just won't know about it until much later when that other team updates to the new version of the module. But at that point you're working on another ticket and it's now their problem to deal with, not yours, so you successfully externalized the work of updating the use sites to someone else.
Competent firms like Google have found solutions to these problems by throwing hardware at it, and by ensuring nobody was able to create their own repositories or branches. If your company uses GitHub though, you're doomed. No way to enforce a monorepo/unified CI discipline in such a setup.
Out of curiosity, how long is a full build on that place?
I wonder what does it take to give up those points, as they are very good things to have. I can't imagine I would give up on them if builds took around an hour, maybe a day.
I don't quite recall. IIRC it was an hour maybe, so it wasn't like the builds were extremely slow, but it means people didn't want to run the tests locally, so if you're trying to get your work committed and then there's some failure CI picked up that you didn't each iteration can be an hour, and that made people feel unproductive and slow because some of them struggled with context switching back and forth and even the ones who could do it didn't like it. Which I totally agree with, context switching and small delays can be painful to feeling productive.
Obviously full test coverage is a very good thing to have. But, people hate waiting. They ended up having a proliferation of smaller repos and replacing it with manual rec/sync work which was IMO not a good idea, but probably felt more like "work" rather than waiting.
The core problem is actually dev teams. Every time I've tried to implement incremental CI when I wasn't in a position to force it through, people fought against it, complained, moaned etc until higher level management gave in. The problems were:
1. People liked the feeling of every test passing every change. It made them feel safe and like they could point the finger at CI if something went wrong, because if every test passed it's definitely not their fault, right? But this leads to slow builds and then they complain about that instead. However this is preferable because slow builds are the project manager/TL's problem to solve, not theirs, so there's a built-in bias towards over-testing.
2. If there's any issue with the build system that causes one test run to affect another in some way (shared state of any kind), then incrementality can cause hard to understand flakes. Sometimes tests will just fail and it'll go away if you force a truly clean rebuild. Devs hate this because they've been taught that flaky tests are the worst possible evil.
3. Build systems are generally hard-wired for correctness, so if you make a change in a module that everything transitively depends on, they'll insist on retesting everything. This is reasonable from a theoretical perspective, but again, leads to very slow builds and people finding ways around them.
4. Work-shifting. Splitting stuff out into separate build systems (separate repos is not really the issue here), may appear to solve these issues, but of course in reality just hides them. Now if you change a core module and break things, you just won't know about it until much later when that other team updates to the new version of the module. But at that point you're working on another ticket and it's now their problem to deal with, not yours, so you successfully externalized the work of updating the use sites to someone else.
Competent firms like Google have found solutions to these problems by throwing hardware at it, and by ensuring nobody was able to create their own repositories or branches. If your company uses GitHub though, you're doomed. No way to enforce a monorepo/unified CI discipline in such a setup.