The last 8-9 years I've had the luxury of pretty much staying current with the Delphi versions. We usually skip the first releases like 10.2 or 10,3 and migrate when the 10.2.1 or 10.3.1 arrive. This has become a little harder as the so-called minor upgrades now also have a lot of changes and even new stuff., but we tend to wait for the first "fix pack". That allows the new versions mature for a while so that TMS, EurekaLog, FastReports, and others can work out any new quirks, and the bleeding edge crowd can draw first blood, but as I said, we do aspire to move on to the latest version as soon as it seems tried and tested. Back in the day, skipping several versions often raised headaches when finally deciding to migrate as you had to deal with multiple incompatibilities or breaking changes, so I much prefer the current approach.
To be honest, in some cases I actually wish that EMBT would be bolder and more often introduce breaking changes to tidy up old sins.
On the topic of unit dependency cycles, I tend to view them as a design weakness. It is a quick workaround for properly designing with DI and other tools that eliminate unit inter-dependencies. Yet, working with code that has evolved over a long time, they can be hard to eliminate as they are so deeply ingrained. We have one particular unit that causes a compiler internal error whenever we change something in its interface section and do a compile in the IDE. At that point only a Build All resolves the problem.