From 12f89c81cf6fda2501c8e15497fc19d93880dfc4 Mon Sep 17 00:00:00 2001 From: Swordsteel Date: Tue, 9 Sep 2025 14:06:25 +0200 Subject: [PATCH] add service, service-container, service-process-resource, and test-integration --- README.md | 56 ++++++++++++++++ build.gradle.kts | 1 + ...common-plugin.service-container.gradle.kts | 66 +++++++++++++++++++ ...plugin.service-process-resource.gradle.kts | 27 ++++++++ ...plugin.service-test-integration.gradle.kts | 38 +++++++++++ ...lz.plugin.common-plugin.service.gradle.kts | 6 ++ 6 files changed, 194 insertions(+) create mode 100644 src/main/kotlin/ltd.lulz.plugin.common-plugin.service-container.gradle.kts create mode 100644 src/main/kotlin/ltd.lulz.plugin.common-plugin.service-process-resource.gradle.kts create mode 100644 src/main/kotlin/ltd.lulz.plugin.common-plugin.service-test-integration.gradle.kts create mode 100644 src/main/kotlin/ltd.lulz.plugin.common-plugin.service.gradle.kts diff --git a/README.md b/README.md index 0c84193..d8e93b2 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,13 @@ * [Plugin Library.](#plugin-library) * [Plugin Library Manifest.](#plugin-library-manifest) * [Plugin Library publish.](#plugin-library-publish) + * [Service](#service) + * [Plugin Service](#plugin-service) + * [Plugin Service Container](#plugin-service-container) + * [Configuration](#configuration) + * [Gradle Tasks](#gradle-tasks) + * [Plugin Service Test Integration](#plugin-service-test-integration) + * [Plugin Service Process Resource](#plugin-service-process-resource) * [Publish gradle plugin locally.](#publish-gradle-plugin-locally) * [Releasing gradle plugin.](#releasing-gradle-plugin) * [Publish gradle plugin to repository.](#publish-gradle-plugin-to-repository) @@ -73,6 +80,55 @@ id `ltd.lulz.plugin.common-plugin.library-publish` Configuration for publishing project artifacts to a remote Maven repository. +### Service + +#### Plugin Service + +id `ltd.lulz.plugin.common-plugin.service` + +Default setting and tasks for services. + +#### Plugin Service Container + +id `ltd.lulz.plugin.common-plugin.service-container` + +Configuration for running project in docker locally during development. + +##### Configuration + +* properties `container.network`, environment `CONTAINER_NETWORK`, or default `develop` +* properties `container.port.expose`, environment `CONTAINER_PORT_EXPOSE`, or default `8080` +* properties `container.port.host`, environment `CONTAINER_PORT_HOST`, or default `8080` +* properties `container.profiles`, environment `CONTAINER_PROFILES`, or default `docker` +* properties `docker.port.expose`, environment `DOCKER_PORT_EXPOSE`, or default `8080` + +container and docker ports can be a single port (e.g., 8080) or multiple ports separated by commas (e.g., 8080,8443) + +##### Gradle Tasks + +* `containerCreate` create docker container with network and spring boot profile. +* `containerStart` starts docker container. +* `containerStop` stops docker container. +* `containerNetworkCheck` check if network exist. +* `containerNetworkCreate` creates network. +* `containerNetworkRemove` removes network. + +#### Plugin Service Test Integration + +id `ltd.lulz.plugin.common-plugin.service-test-integration` + +Adding task `testIntegration` to run integration test, add to `verification` group and add to task `check`. + +Adding intellij support `src/test-integration/java`, `src/test-integration/kotlin`, and `src/test-integration/resources` as test module in intellij. + +Adding dependencies support `testIntegrationImplementation()`, and `testIntegrationRuntimeOnly()` as part of Gradle. + +#### Plugin Service Process Resource + +id `ltd.lulz.plugin.common-plugin.service-process-resource` + +Assign values to `application.yml` from Gradle. + ## Publish gradle plugin locally. ```shell diff --git a/build.gradle.kts b/build.gradle.kts index 4d6230a..9b737f3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,6 +11,7 @@ plugins { } dependencies { + implementation(aa.plugin.docker) implementation(aa.plugin.core) implementation(aa.plugin.detekt) implementation(aa.plugin.ktlint) diff --git a/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-container.gradle.kts b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-container.gradle.kts new file mode 100644 index 0000000..d03fd6b --- /dev/null +++ b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-container.gradle.kts @@ -0,0 +1,66 @@ +import com.bmuschko.gradle.docker.tasks.container.DockerCreateContainer +import com.bmuschko.gradle.docker.tasks.container.DockerStartContainer +import com.bmuschko.gradle.docker.tasks.container.DockerStopContainer +import com.bmuschko.gradle.docker.tasks.network.DockerCreateNetwork +import com.bmuschko.gradle.docker.tasks.network.DockerInspectNetwork +import com.bmuschko.gradle.docker.tasks.network.DockerRemoveNetwork + +plugins { + id("com.bmuschko.docker-spring-boot-application") + id("ltd.lulz.plugin.core-plugin") +} + +fun configurationPorts( + property: String, + environment: String, +): List = config.findOrDefault(property, environment, "8080").split(',') + +fun exposeDockerPorts(): List = configurationPorts("docker.port.expose", "DOCKER_PORT_EXPOSE") + .mapNotNull { it.toIntOrNull() } + +fun exposeContainerPorts(): List = configurationPorts("container.port.host", "CONTAINER_PORT_HOST") + .zip(configurationPorts("container.port.expose", "CONTAINER_PORT_EXPOSE")) + .map { (containerPort, exposedPort) -> "$containerPort:$exposedPort" } + +docker.springBootApplication { + baseImage.set("eclipse-temurin:17-jre-alpine") + ports.set(exposeDockerPorts()) + images.set(listOf("${project.name}:${project.version}")) +} + +tasks { + register("containerCreate", DockerCreateContainer::class) { + group = "lulz" + targetImageId("${project.name}:${project.version}") + containerName.set(project.name) + hostConfig.autoRemove.set(true) + hostConfig.network.set(config.findOrDefault("container.network", "CONTAINER_NETWORK", "develop")) + hostConfig.portBindings.set(exposeContainerPorts()) + withEnvVar( + "SPRING_PROFILES_ACTIVE", + config.findOrDefault("container.profiles", "CONTAINER_PROFILES", "docker"), + ) + } + register("containerStart", DockerStartContainer::class) { + group = "lulz" + dependsOn(findByPath("containerCreate")) + targetContainerId(project.name) + } + register("containerStop", DockerStopContainer::class) { + group = "lulz" + targetContainerId(project.name) + } + register("containerNetworkCheck", DockerInspectNetwork::class) { + group = "lulz" + targetNetworkId(config.findOrDefault("container.network", "CONTAINER_NETWORK", "develop")) + onError { println("Network does not exist.") } + } + register("containerNetworkCreate", DockerCreateNetwork::class) { + group = "lulz" + networkName.set(config.findOrDefault("container.network", "CONTAINER_NETWORK", "develop")) + } + register("containerNetworkRemove", DockerRemoveNetwork::class) { + group = "lulz" + targetNetworkId(config.findOrDefault("container.network", "CONTAINER_NETWORK", "develop")) + } +} diff --git a/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-process-resource.gradle.kts b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-process-resource.gradle.kts new file mode 100644 index 0000000..2143868 --- /dev/null +++ b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-process-resource.gradle.kts @@ -0,0 +1,27 @@ +import org.gradle.kotlin.dsl.support.uppercaseFirstChar + +plugins { + id("ltd.lulz.plugin.core-plugin") +} + +tasks { + withType { + val projectName = project.name + val projectVersion = project.version + filesMatching("**/application.yml") { + filter { + it.replace( + "%APP_NAME%", + projectName.split("-").joinToString(" ") { word -> word.uppercaseFirstChar() }, + ) + } + filter { it.replace("%APP_VERSION%", projectVersion as String) } + filter { it.replace("%APP_BUILD_TIME%", info.utcTimestamp) } + filter { it.replace("%APP_BUILD_OS_NAME%", System.getProperty("os.name")) } + filter { it.replace("%APP_BUILD_OS_VERSION%", System.getProperty("os.version")) } + filter { it.replace("%APP_BUILD_GIT_COMMIT%", git.currentShortHash()) } + filter { it.replace("%APP_BUILD_GIT_BRANCH%", git.currentBranch()) } + } + onlyIf { file("src/main/resources/application.yml").exists() } + } +} diff --git a/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-test-integration.gradle.kts b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-test-integration.gradle.kts new file mode 100644 index 0000000..377ad43 --- /dev/null +++ b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service-test-integration.gradle.kts @@ -0,0 +1,38 @@ +plugins { + id("idea") + + kotlin("jvm") +} + +@Suppress("unused") +fun DependencyHandler.testIntegrationImplementation( + dependencyNotation: Any, +): Dependency? = add("testIntegrationImplementation", dependencyNotation) + +@Suppress("unused") +fun DependencyHandler.testIntegrationRuntimeOnly( + dependencyNotation: Any, +): Dependency? = add("testIntegrationRuntimeOnly", dependencyNotation) + +sourceSets.create("test-integration") { + compileClasspath += sourceSets["main"].output + runtimeClasspath += sourceSets["main"].output + idea.module { + testSources.from(sourceSets["test-integration"].kotlin.srcDirs, sourceSets["test-integration"].java.srcDirs) + testResources.from(sourceSets["test-integration"].resources.srcDirs) + } + configurations.let { + it["testIntegrationImplementation"].extendsFrom(configurations.implementation.get()) + it["testIntegrationRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get()) + } +} + +tasks { + register("testIntegration") { + description = "Runs test integration." + group = "verification" + testClassesDirs = sourceSets["test-integration"].output.classesDirs + classpath = sourceSets["test-integration"].runtimeClasspath + } + check { dependsOn(getByName("testIntegration")) } +} diff --git a/src/main/kotlin/ltd.lulz.plugin.common-plugin.service.gradle.kts b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service.gradle.kts new file mode 100644 index 0000000..25a4f03 --- /dev/null +++ b/src/main/kotlin/ltd.lulz.plugin.common-plugin.service.gradle.kts @@ -0,0 +1,6 @@ +plugins { + id("ltd.lulz.plugin.common-plugin.common") + id("ltd.lulz.plugin.common-plugin.service-container") + id("ltd.lulz.plugin.common-plugin.service-process-resource") + id("ltd.lulz.plugin.common-plugin.service-test-integration") +}