Consolidate imported plugins to custom plugin using Kotlin

I have microservices that will share some of the same configuration between all of them, mainly Jib, publish, and release. Not sure if it’s possible to do the same for dependencies but it would be beneficial to include actuator and log4j2 in each. Here is the build.gradle.kts for one of my projects.

import net.researchgate.release.BaseScmAdapter
import net.researchgate.release.GitAdapter
import net.researchgate.release.ReleaseExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("com.gorylenko.gradle-git-properties") version "1.5.1"
    id("com.google.cloud.tools.jib") version "1.6.1"
    id("io.spring.dependency-management") version "1.0.7.RELEASE"
    id("net.researchgate.release") version "2.8.1"
    id("org.sonarqube") version "2.7.1"
    id("org.springframework.boot") version "2.1.6.RELEASE"
    kotlin("jvm") version "1.2.71"
    kotlin("plugin.spring") version "1.2.71"
    jacoco
    `maven-publish`
}

java.sourceCompatibility = JavaVersion.VERSION_1_8

springBoot {
    buildInfo {
        group = project.properties["group"].toString()
        version = project.properties["version"].toString()
        description = project.properties["description"].toString()
    }
}

repositories {
    maven(url = uri(project.properties["nexus.url.gateway"].toString()))
    mavenCentral()
}

dependencies {
    // Kotlin
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    // Spring
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.boot:spring-boot-starter-log4j2")
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.cloud:spring-cloud-config-server")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR3")
    }
}

configurations.all {
    exclude(group = "ch.qos.logback", module = "logback-classic")
    exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}

tasks {
    withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "1.8"
        }
    }

    build { dependsOn(clean) }
    afterReleaseBuild { dependsOn(publish) }
    publish { dependsOn(build) }
    jibDockerBuild { dependsOn(build) }
    jacocoTestReport {
        reports {
            html.isEnabled = false
            xml.isEnabled = true
        }
    }
}

publishing {
    publications {
        create<MavenPublication>(project.name) {
            from(components["java"])
            pom {
                scm {
                    connection.set("scm:git:git@github.com:company/${project.name}.git")
                    developerConnection.set("scm:git:git@github.com:company/${project.name}.git")
                    url.set("https://github.com/company/${project.name}/")
                }
            }
            versionMapping {
                usage("java-api") {
                    fromResolutionOf("runtimeClasspath")
                }
                usage("java-runtime") {
                    fromResolutionResult()
                }
            }
        }
    }
    repositories {
        maven {
            val releasesRepoUrl = "${project.properties["nexus.url.publish"].toString()}/releases"
            val snapshotsRepoUrl = "${project.properties["nexus.url.publish"].toString()}/snapshots"
            url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
            credentials {
                username = project.properties["nexus.user"].toString()
                password = project.properties["nexus.password"].toString()
            }
        }
    }
}

fun ReleaseExtension.git(configureFn : GitAdapter.GitConfig.() -> Unit) {
    (propertyMissing("git") as GitAdapter.GitConfig).configureFn()
}

release {
    scmAdapters = mutableListOf<Class<out BaseScmAdapter>> ( GitAdapter::class.java )

    git {
        requireBranch = "develop"
        pushToRemote = project.properties["release.git.remote"].toString()
        pushReleaseVersionBranch = "master"
        tagTemplate = "${project.name}.${project.version}"
    }
}

jib {
    from {
        image = "openjdk:8-jdk-alpine"
    }
    to {
        image = "host:port/${project.name}:${project.version}"
        auth {
            username = project.properties["nexus.user"].toString()
            password = project.properties["nexus.password"].toString()
        }
    }
    container {
        workingDirectory = "/"
        ports = listOf("8080")
        environment = mapOf(
                "SPRING_OUTPUT_ANSI_ENABLED" to "ALWAYS",
                "SPRING_CLOUD_BOOTSTRAP_LOCATION" to "/path/to/bootstrap.yml"
        )
        useCurrentTimestamp = true
    }
    setAllowInsecureRegistries(true)
}

I was able to get a custom plugin created and added to this project using git@github.com:klg71/kotlintestplugin.git and git@github.com:klg71/kotlintestpluginproject.git but I have no idea how to implement these existing plugins and their configurations. In the main Plugin class in the apply function I am able to call the project.pluginManager.apply(PublishingPlugin::class.java) which causes the task to show in the project referencing the custom plugin but I can’t figure out how to configure it and it does not successfully publish to the nexus server. I can publish the plugin itself to the nexus server and reference it in the microservice but it skips running the task, which I assume is caused by the configuration not being included. Also, when trying to apply/configure the Jib plugin, all of the classes are not visible when attempting to import.

1 Like

Here’s a stackoverflow link showing some progress on this https://stackoverflow.com/a/58699141/6659006. Got maven-publish working but am still looking for help with jib and others.

My answer here on stackoverflow now does encompass everything.