For one, a relatively stable API from the Gradle folks. OK so they have sometimes broken things accidentaly, but they are good at managing deprecations.
Secondly, there are things a plugin author can do to deal with compatibility over a wide range of releases. To elaborate will take far more than a reply here, but a couple of highlights should do for now:
- The Grolifant library aids plugin authors to deal with recurring themes and keep compatibility. Up to 0.16 it supports Gradle 3.0 - 6.3.
- Test for compatibility using Gradle’s own TestKit library, the GradleTest plugin or the Stutter library
- Understanding that if you write plugins in Groovy that you might have to forego certain Groovyisms as they do not survive major changes in Groovy versions.
- Writing plugins in Java & Kotlin can help in a certain way with the previous issue, but that also have drawbacks especially when there are breaking changes in the API ebtwwen major Gradle versions.
- Understanding that when Java/Kotlin is the obstacle, using Groovy actually works better again by a combination of statically compiled APIs, but some internal methods implemented dynamically.