Parameterize plugin version from imported script

Our team has the need to set up a common base build structure that identifies the blessed repositories, standard plugins, etc. for a suite of Spring Boot microservices. We are migrating away from Maven and it’s parent POM structure and have discovered how to replace almost all the functionality we need except for one.

The Spring Boot plugin cannot be applied, it must be declared in a plugin block:

plugin {
    id 'org.springframework.boot' version '2.3.4.RELEASE'
}

The problem is that we want to decide when we are upgrading Spring Boot and make that change in one repository instead of 40+. We also have one microservice that can’t be upgraded because of limitations of one of our libraries. Se we need to be able to set the version in the imported build script, and override it for the one microservice.

I’ve attempted to declare a variable in the imported script and use it in the plugin declaration, but I got a build error. I can’t put the plugin declaration in the imported script either, or I get a build error.

We are using Gradle 6.6.3, if that helps.

What I want to do is to either specify the Spring Boot plugin in the imported build file, or parameterize the version number in the local build script. I’ve figured out everything else I need to do.

To help understand what the imported build script is doing I am including it here. I’ve tested this and it does work. NOTE: I’ve removed the sections dealing with our repositories because it’s long and not germane to the topic.

/* repositories declaration removed for brevity */

apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'maven-publish'
apply plugin: 'io.spring.dependency-management'


group = 'product-group'

/* hack required to publish to maven repo due to Spring Boot plugin defect */
configurations {
	[apiElements, runtimeElements].each {
		it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
		it.outgoing.artifact(bootJar)
	}
}

java {
	sourceCompatibility = JavaVersion.VERSION_11
	targetCompatibility = JavaVersion.VERSION_11
	withJavadocJar()
	withSourcesJar()
}

ext {
	set('springBootVersion', '2.1.17.RELEASE')
	set('springCloudVersion', "Greenwich.SR6")
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}

jacoco {
	toolVersion = "0.8.5"
	reportsDir = file("$buildDir/reports/jacoco")
}

test {
	finalizedBy jacocoTestReport // report is always generated after tests run
}

jacocoTestCoverageVerification {
	violationRules {
		rule {
			limit {
				minimum = 0.2
			}
		}
	}
}

jacocoTestReport {
	dependsOn test // tests are required to run before generating the report
	
	reports {
		xml.enabled true
		html.destination file("${reportsDir}/jacocoHtml")
		xml.destination file("${reportsDir}/jacocoReport.xml")
	}
}

tasks.withType(JavaCompile) {
	options.encoding = 'UTF-8'
}

/* Publishing declaration omitted for brevity */

And this is how the common build is being imported in a single project file:

/* Build error if this is after the apply from declaration below */
plugins {
	id 'org.springframework.boot' version '2.1.17.RELEASE'
}

apply from: "https://mycentral.repo/project-common/develop/build.gradle"

dependencies {
	implementation  'org.springframework.boot:spring-boot-starter-actuator'
	implementation  'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
	implementation  'ch.qos.logback:logback-classic'
	implementation  'javax.annotation:javax.annotation-api:1.3.2'
	implementation  'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
	implementation  'org.glassfish.jaxb:jaxb-runtime:2.4.0-b180830.0438'
	testImplementation  'org.springframework.boot:spring-boot-starter-test'
}

version = '0.0.2-SNAPSHOT'

Ideally I would like to change the plugin to be like this, and use the value declared in the parent script:

plugins {
	id 'org.springframework.boot' version springBootVersion
}

… or put that whole declaration in the parent script

Correction, we are using Gradle 6.6.1