Compare commits
5 Commits
v0.1.0
...
aad0003e5b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aad0003e5b | ||
|
|
50d9712496 | ||
| 238e4b0a66 | |||
| 2e264a7ea9 | |||
| 75c1331793 |
122
README.md
122
README.md
@@ -2,14 +2,132 @@
|
|||||||
|
|
||||||
<!-- TOC -->
|
<!-- TOC -->
|
||||||
* [Common Plugin.](#common-plugin)
|
* [Common Plugin.](#common-plugin)
|
||||||
* [Plugins](#plugins)
|
* [Plugins.](#plugins)
|
||||||
|
* [Common.](#common)
|
||||||
|
* [Plugin Common.](#plugin-common)
|
||||||
|
* [Plugin Common Build.](#plugin-common-build)
|
||||||
|
* [Plugin Common Detekt.](#plugin-common-detekt)
|
||||||
|
* [Plugin Common Ktlint.](#plugin-common-ktlint)
|
||||||
|
* [Plugin Common Project.](#plugin-common-project)
|
||||||
|
* [Library.](#library)
|
||||||
|
* [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)
|
* [Publish gradle plugin locally.](#publish-gradle-plugin-locally)
|
||||||
* [Releasing gradle plugin.](#releasing-gradle-plugin)
|
* [Releasing gradle plugin.](#releasing-gradle-plugin)
|
||||||
* [Publish gradle plugin to repository.](#publish-gradle-plugin-to-repository)
|
* [Publish gradle plugin to repository.](#publish-gradle-plugin-to-repository)
|
||||||
* [Global gradle properties.](#global-gradle-properties)
|
* [Global gradle properties.](#global-gradle-properties)
|
||||||
<!-- TOC -->
|
<!-- TOC -->
|
||||||
|
|
||||||
## Plugins
|
## Plugins.
|
||||||
|
|
||||||
|
### Common.
|
||||||
|
|
||||||
|
#### Plugin Common.
|
||||||
|
|
||||||
|
id `ltd.lulz.plugin.common-plugin.common`
|
||||||
|
|
||||||
|
Set core Java and Kotlin settings and overweight project version with git version.
|
||||||
|
|
||||||
|
#### Plugin Common Build.
|
||||||
|
|
||||||
|
id `ltd.lulz.plugin.common-plugin.common-build`
|
||||||
|
|
||||||
|
Display name and version, add `buildInfo` to `build` task.
|
||||||
|
|
||||||
|
#### Plugin Common Detekt.
|
||||||
|
|
||||||
|
id `ltd.lulz.plugin.common-plugin.common-detekt`
|
||||||
|
|
||||||
|
Detect is a code smell analysis for your Kotlin projects.
|
||||||
|
|
||||||
|
#### Plugin Common Ktlint.
|
||||||
|
|
||||||
|
id `ltd.lulz.plugin.common-plugin.common-ktlint`
|
||||||
|
|
||||||
|
Ktlint enforces consistent code style and formatting across Kotlin codebases.
|
||||||
|
|
||||||
|
#### Plugin Common Project.
|
||||||
|
|
||||||
|
id `ltd.lulz.plugin.common-plugin.common-project`
|
||||||
|
|
||||||
|
Display project, Gradle, and Java information.
|
||||||
|
|
||||||
|
### Library.
|
||||||
|
|
||||||
|
#### Plugin Library.
|
||||||
|
|
||||||
|
id `ltd.lulz.plugin.common-plugin.library`
|
||||||
|
|
||||||
|
Default setting and tasks for libraries.
|
||||||
|
|
||||||
|
#### Plugin Library Manifest.
|
||||||
|
|
||||||
|
id `ltd.lulz.plugin.common-plugin.library-manifest`
|
||||||
|
|
||||||
|
Extend manifest in library jar file.
|
||||||
|
|
||||||
|
#### Plugin Library publish.
|
||||||
|
|
||||||
|
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.
|
## Publish gradle plugin locally.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,15 @@ plugins {
|
|||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(aa.plugin.docker)
|
||||||
|
implementation(aa.plugin.core)
|
||||||
|
implementation(aa.plugin.detekt)
|
||||||
|
implementation(aa.plugin.ktlint)
|
||||||
|
implementation(aa.plugin.kotlin)
|
||||||
|
implementation(aa.plugin.springboot)
|
||||||
|
}
|
||||||
|
|
||||||
description = "Lulz Common Plugin"
|
description = "Lulz Common Plugin"
|
||||||
group = "ltd.lulz.plugin"
|
group = "ltd.lulz.plugin"
|
||||||
version = git.version()
|
version = git.version()
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
version=0.1.0-SNAPSHOT
|
version=0.2.0-SNAPSHOT
|
||||||
catalog=0.1.0-SNAPSHOT
|
catalog=0.1.0
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
plugins {
|
||||||
|
id("ltd.lulz.plugin.core-plugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
named("build") {
|
||||||
|
dependsOn("buildInfo")
|
||||||
|
}
|
||||||
|
register("buildInfo") {
|
||||||
|
group = "lulz"
|
||||||
|
description = "Prints the project name and version"
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
println(info.nameVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import io.gitlab.arturbosch.detekt.Detekt
|
||||||
|
import io.gitlab.arturbosch.detekt.extensions.DetektExtension.Companion.DEFAULT_SRC_DIR_KOTLIN
|
||||||
|
import io.gitlab.arturbosch.detekt.extensions.DetektExtension.Companion.DEFAULT_TEST_SRC_DIR_KOTLIN
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("io.gitlab.arturbosch.detekt")
|
||||||
|
}
|
||||||
|
|
||||||
|
detekt {
|
||||||
|
buildUponDefaultConfig = true
|
||||||
|
basePath = projectDir.path
|
||||||
|
source.from(
|
||||||
|
DEFAULT_SRC_DIR_KOTLIN,
|
||||||
|
DEFAULT_TEST_SRC_DIR_KOTLIN,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Detekt> {
|
||||||
|
reports {
|
||||||
|
html.required = false
|
||||||
|
md.required = false
|
||||||
|
sarif.required = true
|
||||||
|
txt.required = false
|
||||||
|
xml.required = false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType.SARIF
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("org.jlleitschuh.gradle.ktlint")
|
||||||
|
}
|
||||||
|
|
||||||
|
ktlint {
|
||||||
|
verbose = true
|
||||||
|
filter {
|
||||||
|
exclude("**/generated/**")
|
||||||
|
include("**/kotlin/**")
|
||||||
|
}
|
||||||
|
kotlinScriptAdditionalPaths {
|
||||||
|
include(fileTree("scripts/*"))
|
||||||
|
}
|
||||||
|
reporters {
|
||||||
|
reporter(SARIF)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import org.gradle.kotlin.dsl.kotlin
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("ltd.lulz.plugin.core-plugin")
|
||||||
|
kotlin("jvm")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("projectInfo") {
|
||||||
|
group = "lulz"
|
||||||
|
description = "Prints project information"
|
||||||
|
|
||||||
|
val groupValue = project.group.toString()
|
||||||
|
val nameValue = project.name
|
||||||
|
val versionValue = project.version.toString()
|
||||||
|
val descriptionValue = project.description ?: "N/A"
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
println()
|
||||||
|
println("UTC Time: ${info.utcTimestamp}")
|
||||||
|
println()
|
||||||
|
println("Project group: $groupValue")
|
||||||
|
println("Project name: $nameValue\"")
|
||||||
|
println("Project version: $versionValue")
|
||||||
|
println("Project description: $descriptionValue")
|
||||||
|
println()
|
||||||
|
println("Gradle version: ${GradleVersion.current().version}")
|
||||||
|
println("Java JVM version: ${JavaVersion.current()}")
|
||||||
|
println("Java toolchain version: ${java.toolchain.languageVersion.orNull ?: "N/A"}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
plugins {
|
||||||
|
id("ltd.lulz.plugin.common-plugin.common-build")
|
||||||
|
id("ltd.lulz.plugin.common-plugin.common-detekt")
|
||||||
|
id("ltd.lulz.plugin.common-plugin.common-ktlint")
|
||||||
|
id("ltd.lulz.plugin.common-plugin.common-project")
|
||||||
|
|
||||||
|
id("ltd.lulz.plugin.core-plugin")
|
||||||
|
|
||||||
|
kotlin("jvm")
|
||||||
|
}
|
||||||
|
|
||||||
|
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
|
||||||
|
kotlin.compilerOptions.freeCompilerArgs.addAll("-Xjsr305=strict")
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
version = git.version()
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
plugins {
|
||||||
|
id("ltd.lulz.plugin.core-plugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Jar>().configureEach {
|
||||||
|
manifest.attributes.apply {
|
||||||
|
put("Implementation-Title", project.name.split("-").joinToString(" "))
|
||||||
|
put("Implementation-Version", project.version)
|
||||||
|
put("Implementation-Vendor", info.vendorName)
|
||||||
|
put("Built-By", System.getProperty("user.name"))
|
||||||
|
put("Built-Git", "${git.currentBranch()} #${git.currentShortHash()}")
|
||||||
|
put("Built-Gradle", project.gradle.gradleVersion)
|
||||||
|
put("Built-JDK", System.getProperty("java.version"))
|
||||||
|
put("Built-OS", "${System.getProperty("os.name")} v${System.getProperty("os.version")}")
|
||||||
|
put("Built-Time", info.utcTimestamp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
plugins {
|
||||||
|
id("ltd.lulz.plugin.core-plugin")
|
||||||
|
|
||||||
|
`maven-publish`
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = uri("https://gitea.lulz.ltd/api/packages/aura-ascend/maven")
|
||||||
|
name = "GiteaPackages"
|
||||||
|
credentials {
|
||||||
|
username = config.find("repository.gitea.user", "REPOSITORY_USER")
|
||||||
|
password = config.find("repository.gitea.token", "REPOSITORY_TOKEN")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
publications.register("mavenJava", MavenPublication::class) { from(components["java"]) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("ltd.lulz.plugin.common-plugin.common")
|
||||||
|
id("ltd.lulz.plugin.common-plugin.library-manifest")
|
||||||
|
id("ltd.lulz.plugin.common-plugin.library-publish")
|
||||||
|
id("org.springframework.boot")
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
withSourcesJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
named<Jar>("jar") {
|
||||||
|
archiveClassifier.set("")
|
||||||
|
}
|
||||||
|
withType<BootJar> {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<String> = config.findOrDefault(property, environment, "8080").split(',')
|
||||||
|
|
||||||
|
fun exposeDockerPorts(): List<Int> = configurationPorts("docker.port.expose", "DOCKER_PORT_EXPOSE")
|
||||||
|
.mapNotNull { it.toIntOrNull() }
|
||||||
|
|
||||||
|
fun exposeContainerPorts(): List<String> = 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 = "container"
|
||||||
|
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 = "container"
|
||||||
|
dependsOn(findByPath("containerCreate"))
|
||||||
|
targetContainerId(project.name)
|
||||||
|
}
|
||||||
|
register("containerStop", DockerStopContainer::class) {
|
||||||
|
group = "container"
|
||||||
|
targetContainerId(project.name)
|
||||||
|
}
|
||||||
|
register("containerNetworkCheck", DockerInspectNetwork::class) {
|
||||||
|
group = "container"
|
||||||
|
targetNetworkId(config.findOrDefault("container.network", "CONTAINER_NETWORK", "develop"))
|
||||||
|
onError { println("Network does not exist.") }
|
||||||
|
}
|
||||||
|
register("containerNetworkCreate", DockerCreateNetwork::class) {
|
||||||
|
group = "container"
|
||||||
|
networkName.set(config.findOrDefault("container.network", "CONTAINER_NETWORK", "develop"))
|
||||||
|
}
|
||||||
|
register("containerNetworkRemove", DockerRemoveNetwork::class) {
|
||||||
|
group = "container"
|
||||||
|
targetNetworkId(config.findOrDefault("container.network", "CONTAINER_NETWORK", "develop"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import org.gradle.kotlin.dsl.support.uppercaseFirstChar
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("ltd.lulz.plugin.core-plugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
withType<ProcessResources> {
|
||||||
|
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() }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<Test>("testIntegration") {
|
||||||
|
description = "Runs test integration."
|
||||||
|
group = "verification"
|
||||||
|
testClassesDirs = sourceSets["test-integration"].output.classesDirs
|
||||||
|
classpath = sourceSets["test-integration"].runtimeClasspath
|
||||||
|
}
|
||||||
|
check { dependsOn(getByName("testIntegration")) }
|
||||||
|
}
|
||||||
@@ -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")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user