Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ bin/
.vscode/

### Mac OS ###
.DS_Store
.DS_Store

settings.local.json
Empty file modified gradlew
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pluginManagement {
mavenLocal()
maven("https://repo.slne.dev/repository/maven-public/") { name = "maven-public" }
}

}

plugins {
Expand All @@ -30,5 +31,4 @@ include("surf-microservice-client:surf-microservice-client-velocity")
include("surf-microservice-microservice")

// Gradle Plugin
include("surf-microservice-gradle-plugin")
include("surf-microservice-client:surf-microservice-client-common")
include("surf-microservice-gradle-plugin")
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
package dev.slne.surf.microservice.gradle.plugin

import dev.slne.surf.microservice.gradle.generated.Constants
import dev.slne.surf.microservice.gradle.plugin.docker.DockerExtension
import dev.slne.surf.microservice.gradle.plugin.docker.DockerRepository
import dev.slne.surf.microservice.gradle.plugin.task.docker.GenerateDockerDockerfileTask
import dev.slne.surf.microservice.gradle.plugin.task.docker.GeneratePterodactylDockerfileTask
import dev.slne.surf.microservice.gradle.plugin.task.workflow.GenerateBuildWorkflowTask
import dev.slne.surf.microservice.gradle.plugin.task.workflow.GenerateDockerWorkflowTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.register

abstract class MicroservicePlugin : Plugin<Project> {
override fun apply(target: Project) = with(target) {
val extension = extensions.create<MicroserviceExtension>("surfMicroservice")
val dockerExtension = extensions.create<DockerExtension>("surfMicroserviceDocker")

dockerExtension.baseImage.convention("ghcr.io/graalvm/jdk-community:25")
dockerExtension.port.convention(8080)
dockerExtension.jvmArgs.convention(emptyList())
dockerExtension.repository.convention(DockerRepository.PRIVATE)

tasks.register<GenerateDockerDockerfileTask>("generateDockerDockerfile") {
baseImage.convention(dockerExtension.baseImage)
port.convention(dockerExtension.port)
jvmArgs.convention(dockerExtension.jvmArgs)
outputFile.convention(layout.projectDirectory.file("Dockerfile"))
}

tasks.register<GeneratePterodactylDockerfileTask>("generatePterodactylDockerfile") {
baseImage.convention(dockerExtension.baseImage)
jvmArgs.convention(dockerExtension.jvmArgs)
outputFile.convention(layout.projectDirectory.file("Dockerfile"))
}

tasks.register<GenerateBuildWorkflowTask>("generateBuildWorkflow") {
moduleRegex.convention("")
outputFile.convention(layout.projectDirectory.file(".github/workflows/build.yml"))
}

tasks.register<GenerateDockerWorkflowTask>("generateDockerWorkflow") {
registryUrl.convention(dockerExtension.repository.map { it.registryUrl })
usernameSecret.convention(dockerExtension.repository.map { it.usernameSecret })
passwordSecret.convention(dockerExtension.repository.map { it.passwordSecret })
outputFile.convention(layout.projectDirectory.file(".github/workflows/docker.yml"))
}

afterEvaluate {
extension.module.orNull?.let { moduleDependency ->
Expand Down Expand Up @@ -46,4 +84,4 @@ abstract class MicroservicePlugin : Plugin<Project> {
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dev.slne.surf.microservice.gradle.plugin.docker

import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property

abstract class DockerExtension {
abstract val baseImage: Property<String>
abstract val port: Property<Int>
abstract val jvmArgs: ListProperty<String>
abstract val repository: Property<DockerRepository>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.slne.surf.microservice.gradle.plugin.docker

enum class DockerRepository(
val registryUrl: String,
val usernameSecret: String,
val passwordSecret: String
) {
PUBLIC(
"repo.slne.dev/slne-docker-public",
"SLNE_RELEASES_REPO_USERNAME",
"SLNE_RELEASES_REPO_PASSWORD"
),
PRIVATE(
"repo.slne.dev/slne-docker-private",
"SLNE_SNAPSHOTS_REPO_USERNAME",
"SLNE_SNAPSHOTS_REPO_PASSWORD"
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dev.slne.surf.microservice.gradle.plugin.task.docker

import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

abstract class AbstractGenerateDockerfileTask : DefaultTask() {
@get:Input
abstract val baseImage: Property<String>

@get:Input
abstract val jvmArgs: ListProperty<String>

@get:OutputFile
abstract val outputFile: RegularFileProperty

init {
group = "microservice"
}

@get:Internal
protected abstract val workdir: String

@get:Internal
protected abstract val jarName: String

protected abstract fun buildDockerfileContent(): String

protected fun buildEntrypoint(): String {
val args = jvmArgs.get()

return if (args.isEmpty()) {
"""ENTRYPOINT ["java", "-jar", "$jarName"]"""
} else {
val jvmArgsStr = args.joinToString(", ") { "\"$it\"" }
"""ENTRYPOINT ["java", $jvmArgsStr, "-jar", "$jarName"]"""
}
}

@TaskAction
fun generate() {
val content = buildDockerfileContent()
outputFile.get().asFile.writeText(content)
logger.lifecycle("Generated Dockerfile at ${outputFile.get().asFile.absolutePath}")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package dev.slne.surf.microservice.gradle.plugin.task.docker

import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input

abstract class GenerateDockerDockerfileTask : AbstractGenerateDockerfileTask() {
@get:Input
abstract val port: Property<Int>

init {
description = "Generates a Dockerfile for running the microservice in Docker/Kubernetes"
}

override val workdir = "/app"
override val jarName = "app.jar"

override fun buildDockerfileContent() = buildString {
appendLine("FROM ${baseImage.get()}")
appendLine()
appendLine("WORKDIR $workdir")
appendLine()
appendLine("COPY build/libs/*-all.jar $jarName")
appendLine()
appendLine("EXPOSE ${port.get()}")
appendLine()
appendLine(buildEntrypoint())
appendLine()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package dev.slne.surf.microservice.gradle.plugin.task.docker

import org.gradle.api.tasks.TaskAction

abstract class GeneratePterodactylDockerfileTask : AbstractGenerateDockerfileTask() {

init {
description = "Generates a Dockerfile and entrypoint.sh for running the microservice on Pterodactyl"
}

override val workdir = "/home/container"
override val jarName = "app.jar"

override fun buildDockerfileContent() = buildString {
appendLine("FROM ${baseImage.get()}")
appendLine()
appendLine("RUN adduser --disabled-password --home /home/container container")
appendLine()
appendLine("USER container")
appendLine("ENV USER=container HOME=/home/container")
appendLine()
appendLine("WORKDIR $workdir")
appendLine()
appendLine("COPY build/libs/*-all.jar $jarName")
appendLine()
appendLine("COPY ./entrypoint.sh /entrypoint.sh")
appendLine()
appendLine("""CMD ["/bin/bash", "/entrypoint.sh"]""")
appendLine()
}

private fun buildEntrypointContent() = buildString {
appendLine("#!/bin/bash")
appendLine()
appendLine("cd /home/container")
appendLine()
appendLine("MODIFIED_STARTUP=\$(eval echo \"\$(echo \${STARTUP} | sed -e 's/{{/\${/g' -e 's/}}/}/g')\")")
appendLine("echo \":/home/container\$ \${MODIFIED_STARTUP}\"")
appendLine("\${MODIFIED_STARTUP}")
appendLine()
}

@TaskAction
fun generateEntrypoint() {
val entrypointFile = outputFile.get().asFile.parentFile.resolve("entrypoint.sh")
entrypointFile.writeText(buildEntrypointContent())
logger.lifecycle("Generated entrypoint.sh at ${entrypointFile.absolutePath}")
}
}
Loading