diff --git a/.gitignore b/.gitignore index 5b33b62..2618f52 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,6 @@ bin/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store + +settings.local.json \ No newline at end of file diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/settings.gradle.kts b/settings.gradle.kts index 4e20d81..7491eed 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,7 @@ pluginManagement { mavenLocal() maven("https://repo.slne.dev/repository/maven-public/") { name = "maven-public" } } + } plugins { @@ -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") \ No newline at end of file +include("surf-microservice-gradle-plugin") \ No newline at end of file diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/MicroservicePlugin.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/MicroservicePlugin.kt index 9a9dc12..c31575a 100644 --- a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/MicroservicePlugin.kt +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/MicroservicePlugin.kt @@ -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 { override fun apply(target: Project) = with(target) { val extension = extensions.create("surfMicroservice") + val dockerExtension = extensions.create("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("generateDockerDockerfile") { + baseImage.convention(dockerExtension.baseImage) + port.convention(dockerExtension.port) + jvmArgs.convention(dockerExtension.jvmArgs) + outputFile.convention(layout.projectDirectory.file("Dockerfile")) + } + + tasks.register("generatePterodactylDockerfile") { + baseImage.convention(dockerExtension.baseImage) + jvmArgs.convention(dockerExtension.jvmArgs) + outputFile.convention(layout.projectDirectory.file("Dockerfile")) + } + + tasks.register("generateBuildWorkflow") { + moduleRegex.convention("") + outputFile.convention(layout.projectDirectory.file(".github/workflows/build.yml")) + } + + tasks.register("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 -> @@ -46,4 +84,4 @@ abstract class MicroservicePlugin : Plugin { } } } -} \ No newline at end of file +} diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/docker/DockerExtension.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/docker/DockerExtension.kt new file mode 100644 index 0000000..83aa4ce --- /dev/null +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/docker/DockerExtension.kt @@ -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 + abstract val port: Property + abstract val jvmArgs: ListProperty + abstract val repository: Property +} diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/docker/DockerRepository.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/docker/DockerRepository.kt new file mode 100644 index 0000000..e221681 --- /dev/null +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/docker/DockerRepository.kt @@ -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" + ) +} diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/AbstractGenerateDockerfileTask.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/AbstractGenerateDockerfileTask.kt new file mode 100644 index 0000000..a451042 --- /dev/null +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/AbstractGenerateDockerfileTask.kt @@ -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 + + @get:Input + abstract val jvmArgs: ListProperty + + @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}") + } +} diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/GenerateDockerDockerfileTask.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/GenerateDockerDockerfileTask.kt new file mode 100644 index 0000000..e76ef79 --- /dev/null +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/GenerateDockerDockerfileTask.kt @@ -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 + + 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() + } +} diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/GeneratePterodactylDockerfileTask.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/GeneratePterodactylDockerfileTask.kt new file mode 100644 index 0000000..4b1185a --- /dev/null +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/docker/GeneratePterodactylDockerfileTask.kt @@ -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}") + } +} diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/workflow/GenerateBuildWorkflowTask.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/workflow/GenerateBuildWorkflowTask.kt new file mode 100644 index 0000000..3b09ccc --- /dev/null +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/workflow/GenerateBuildWorkflowTask.kt @@ -0,0 +1,155 @@ +package dev.slne.surf.microservice.gradle.plugin.task.workflow + +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction + +abstract class GenerateBuildWorkflowTask : DefaultTask() { + @get:Input + abstract val moduleRegex: Property + + @get:OutputFile + abstract val outputFile: RegularFileProperty + + init { + group = "microservice" + description = "Generates a GitHub Actions workflow for building JARs and publishing to Maven" + } + + @TaskAction + fun generate() { + val regex = moduleRegex.get() + + val moduleRegexEnv = if (regex.isNotEmpty()) { + "\n MODULE_REGEX: \"$regex\"" + } else { + "" + } + + val findJarsStep = if (regex.isNotEmpty()) { + """ + - name: Find and filter JAR files + id: find_jars + run: | + echo "JAR_FILES<> ${'$'}GITHUB_OUTPUT + find . -path "*/build/libs/*-all.jar" -type f | while read -r f; do + if echo "${'$'}f" | grep -qP "${'$'}{MODULE_REGEX}"; then + echo "${'$'}f" + fi + done + echo "EOF" >> ${'$'}GITHUB_OUTPUT""" + } else { + """ + - name: Find JAR files + id: find_jars + run: | + echo "JAR_FILES<> ${'$'}GITHUB_OUTPUT + find . -path "*/build/libs/*-all.jar" -type f | while read -r f; do + echo "${'$'}f" + done + echo "EOF" >> ${'$'}GITHUB_OUTPUT""" + } + + val workflow = """ +name: Build & Publish + +on: + push: + branches: + - version/** + workflow_dispatch: + +env: + SLNE_SNAPSHOTS_REPO_USERNAME: ${'$'}{{ secrets.SLNE_SNAPSHOTS_REPO_USERNAME }} + SLNE_SNAPSHOTS_REPO_PASSWORD: ${'$'}{{ secrets.SLNE_SNAPSHOTS_REPO_PASSWORD }} + SLNE_RELEASES_REPO_USERNAME: ${'$'}{{ secrets.SLNE_RELEASES_REPO_USERNAME }} + SLNE_RELEASES_REPO_PASSWORD: ${'$'}{{ secrets.SLNE_RELEASES_REPO_PASSWORD }} + DEFAULT_BRANCH: ${'$'}{{ github.event.repository.default_branch }}$moduleRegexEnv + +jobs: + build: + runs-on: ubuntu-latest + environment: production + permissions: + contents: write + packages: write + steps: + - name: Collect Workflow Telemetry + uses: catchpoint/workflow-telemetry-action@v2 + + - name: Checkout Repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: "graalvm" + java-version: 25 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + allow-snapshot-wrappers: true + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Check with Gradle + run: ./gradlew check + + - name: Publish to Maven + run: ./gradlew publish + + - name: Extract Project Version + id: get_version + run: | + VERSION=${'$'}(./gradlew properties --no-daemon \ + | grep '^version:' \ + | awk '{print ${'$'}2}') + + if [[ "${'$'}VERSION" == *SNAPSHOT* ]]; then + SNAPSHOT_FLAG=true + else + SNAPSHOT_FLAG=false + fi + + echo "VERSION=${'$'}VERSION" >> ${'$'}GITHUB_ENV + echo "SNAPSHOT_FLAG=${'$'}SNAPSHOT_FLAG" >> ${'$'}GITHUB_ENV + + - name: Determine release flags + run: | + CURRENT_BRANCH=${'$'}{GITHUB_REF#refs/heads/} + if [ "${'$'}{SNAPSHOT_FLAG}" = "true" ]; then + echo "PRERELEASE=true" >> ${'$'}GITHUB_ENV + else + echo "PRERELEASE=false" >> ${'$'}GITHUB_ENV + fi + if [ "${'$'}{SNAPSHOT_FLAG}" = "true" ] || [ "${'$'}{CURRENT_BRANCH}" != "${'$'}{DEFAULT_BRANCH}" ]; then + echo "MAKE_LATEST=false" >> ${'$'}GITHUB_ENV + else + echo "MAKE_LATEST=true" >> ${'$'}GITHUB_ENV + fi +$findJarsStep + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${'$'}{{ env.VERSION }} + name: Release v${'$'}{{ env.VERSION }} + prerelease: ${'$'}{{ env.PRERELEASE }} + make_latest: ${'$'}{{ env.MAKE_LATEST }} + generate_release_notes: true + files: ${'$'}{{ steps.find_jars.outputs.JAR_FILES }} +""".trimStart() + + val outputPath = outputFile.get().asFile + outputPath.parentFile.mkdirs() + outputPath.writeText(workflow) + logger.lifecycle("Generated build workflow at ${outputPath.absolutePath}") + } +} diff --git a/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/workflow/GenerateDockerWorkflowTask.kt b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/workflow/GenerateDockerWorkflowTask.kt new file mode 100644 index 0000000..61d8829 --- /dev/null +++ b/surf-microservice-gradle-plugin/src/main/kotlin/dev/slne/surf/microservice/gradle/plugin/task/workflow/GenerateDockerWorkflowTask.kt @@ -0,0 +1,134 @@ +package dev.slne.surf.microservice.gradle.plugin.task.workflow + +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction + +abstract class GenerateDockerWorkflowTask : DefaultTask() { + @get:Input + abstract val registryUrl: Property + + @get:Input + abstract val usernameSecret: Property + + @get:Input + abstract val passwordSecret: Property + + @get:OutputFile + abstract val outputFile: RegularFileProperty + + init { + group = "microservice" + description = "Generates a GitHub Actions workflow for building and pushing the Docker image" + } + + @TaskAction + fun generate() { + val registry = registryUrl.get() + val username = usernameSecret.get() + val password = passwordSecret.get() + + val workflow = """ +name: Publish Docker Image + +on: + push: + branches: + - version/** + workflow_dispatch: + +env: + DEFAULT_BRANCH: ${'$'}{{ github.event.repository.default_branch }} + +jobs: + docker: + runs-on: ubuntu-latest + environment: production + permissions: + contents: read + packages: write + steps: + - name: Collect Workflow Telemetry + uses: catchpoint/workflow-telemetry-action@v2 + + - name: Checkout Repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: "graalvm" + java-version: 25 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + allow-snapshot-wrappers: true + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Extract Project Version + id: get_version + run: | + VERSION=${'$'}(./gradlew properties --no-daemon \ + | grep '^version:' \ + | awk '{print ${'$'}2}') + + if [[ "${'$'}VERSION" == *SNAPSHOT* ]]; then + SNAPSHOT_FLAG=true + else + SNAPSHOT_FLAG=false + fi + + echo "VERSION=${'$'}VERSION" >> ${'$'}GITHUB_ENV + echo "SNAPSHOT_FLAG=${'$'}SNAPSHOT_FLAG" >> ${'$'}GITHUB_ENV + + - name: Log in to Docker Registry + uses: docker/login-action@v3 + with: + registry: $registry + username: ${'$'}{{ secrets.$username }} + password: ${'$'}{{ secrets.$password }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Determine image tags + run: | + CURRENT_BRANCH=${'$'}{GITHUB_REF#refs/heads/} + if [ "${'$'}{SNAPSHOT_FLAG}" = "true" ] || [ "${'$'}{CURRENT_BRANCH}" != "${'$'}{DEFAULT_BRANCH}" ]; then + echo "MAKE_LATEST=false" >> ${'$'}GITHUB_ENV + else + echo "MAKE_LATEST=true" >> ${'$'}GITHUB_ENV + fi + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: $registry/${'$'}{{ github.repository }} + tags: | + type=raw,value=${'$'}{{ env.VERSION }} + type=raw,value=latest,enable=${'$'}{{ env.MAKE_LATEST == 'true' }} + + - name: Build and Push Docker Image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${'$'}{{ steps.meta.outputs.tags }} + labels: ${'$'}{{ steps.meta.outputs.labels }} +""".trimStart() + + val outputPath = outputFile.get().asFile + outputPath.parentFile.mkdirs() + outputPath.writeText(workflow) + logger.lifecycle("Generated Docker workflow at ${outputPath.absolutePath}") + } +} diff --git a/surf-microservice-test/.github/workflows/build.yml b/surf-microservice-test/.github/workflows/build.yml new file mode 100644 index 0000000..e9623d9 --- /dev/null +++ b/surf-microservice-test/.github/workflows/build.yml @@ -0,0 +1,99 @@ +name: Build & Publish + +on: + push: + branches: + - version/** + workflow_dispatch: + +env: + SLNE_SNAPSHOTS_REPO_USERNAME: ${{ secrets.SLNE_SNAPSHOTS_REPO_USERNAME }} + SLNE_SNAPSHOTS_REPO_PASSWORD: ${{ secrets.SLNE_SNAPSHOTS_REPO_PASSWORD }} + SLNE_RELEASES_REPO_USERNAME: ${{ secrets.SLNE_RELEASES_REPO_USERNAME }} + SLNE_RELEASES_REPO_PASSWORD: ${{ secrets.SLNE_RELEASES_REPO_PASSWORD }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + +jobs: + build: + runs-on: ubuntu-latest + environment: production + permissions: + contents: write + packages: write + steps: + - name: Collect Workflow Telemetry + uses: catchpoint/workflow-telemetry-action@v2 + + - name: Checkout Repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: "graalvm" + java-version: 25 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + allow-snapshot-wrappers: true + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Check with Gradle + run: ./gradlew check + + - name: Publish to Maven + run: ./gradlew publish + + - name: Extract Project Version + id: get_version + run: | + VERSION=$(./gradlew properties --no-daemon \ + | grep '^version:' \ + | awk '{print $2}') + + if [[ "$VERSION" == *SNAPSHOT* ]]; then + SNAPSHOT_FLAG=true + else + SNAPSHOT_FLAG=false + fi + + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "SNAPSHOT_FLAG=$SNAPSHOT_FLAG" >> $GITHUB_ENV + + - name: Determine release flags + run: | + CURRENT_BRANCH=${GITHUB_REF#refs/heads/} + if [ "${SNAPSHOT_FLAG}" = "true" ]; then + echo "PRERELEASE=true" >> $GITHUB_ENV + else + echo "PRERELEASE=false" >> $GITHUB_ENV + fi + if [ "${SNAPSHOT_FLAG}" = "true" ] || [ "${CURRENT_BRANCH}" != "${DEFAULT_BRANCH}" ]; then + echo "MAKE_LATEST=false" >> $GITHUB_ENV + else + echo "MAKE_LATEST=true" >> $GITHUB_ENV + fi + + - name: Find JAR files + id: find_jars + run: | + echo "JAR_FILES<> $GITHUB_OUTPUT + find . -path "*/build/libs/*-all.jar" -type f | while read -r f; do + echo "$f" + done + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ env.VERSION }} + name: Release v${{ env.VERSION }} + prerelease: ${{ env.PRERELEASE }} + make_latest: ${{ env.MAKE_LATEST }} + generate_release_notes: true + files: ${{ steps.find_jars.outputs.JAR_FILES }} diff --git a/surf-microservice-test/.github/workflows/docker.yml b/surf-microservice-test/.github/workflows/docker.yml new file mode 100644 index 0000000..a1035bf --- /dev/null +++ b/surf-microservice-test/.github/workflows/docker.yml @@ -0,0 +1,92 @@ +name: Publish Docker Image + +on: + push: + branches: + - version/** + workflow_dispatch: + +env: + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + +jobs: + docker: + runs-on: ubuntu-latest + environment: production + permissions: + contents: read + packages: write + steps: + - name: Collect Workflow Telemetry + uses: catchpoint/workflow-telemetry-action@v2 + + - name: Checkout Repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: "graalvm" + java-version: 25 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v5 + with: + allow-snapshot-wrappers: true + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Extract Project Version + id: get_version + run: | + VERSION=$(./gradlew properties --no-daemon \ + | grep '^version:' \ + | awk '{print $2}') + + if [[ "$VERSION" == *SNAPSHOT* ]]; then + SNAPSHOT_FLAG=true + else + SNAPSHOT_FLAG=false + fi + + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "SNAPSHOT_FLAG=$SNAPSHOT_FLAG" >> $GITHUB_ENV + + - name: Log in to Docker Registry + uses: docker/login-action@v3 + with: + registry: repo.slne.dev/slne-docker-public + username: ${{ secrets.SLNE_DOCKER_REPO_USERNAME }} + password: ${{ secrets.SLNE_DOCKER_REPO_PASSWORD }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Determine image tags + run: | + CURRENT_BRANCH=${GITHUB_REF#refs/heads/} + if [ "${SNAPSHOT_FLAG}" = "true" ] || [ "${CURRENT_BRANCH}" != "${DEFAULT_BRANCH}" ]; then + echo "MAKE_LATEST=false" >> $GITHUB_ENV + else + echo "MAKE_LATEST=true" >> $GITHUB_ENV + fi + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: repo.slne.dev/slne-docker-public/${{ github.repository }} + tags: | + type=raw,value=${{ env.VERSION }} + type=raw,value=latest,enable=${{ env.MAKE_LATEST == 'true' }} + + - name: Build and Push Docker Image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/surf-microservice-test/build.gradle.kts b/surf-microservice-test/build.gradle.kts new file mode 100644 index 0000000..93070c8 --- /dev/null +++ b/surf-microservice-test/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("dev.slne.surf.microservice") version "+" +} + +surfMicroserviceDocker { + baseImage.set("ghcr.io/graalvm/jdk-community:25") + port.set(25565) + jvmArgs.set(listOf("-Xmx512m", "-Xms256m")) + repository.set(dev.slne.surf.microservice.gradle.plugin.docker.DockerRepository.PUBLIC) +} diff --git a/surf-microservice-test/gradle.properties b/surf-microservice-test/gradle.properties new file mode 100644 index 0000000..b84675a --- /dev/null +++ b/surf-microservice-test/gradle.properties @@ -0,0 +1,3 @@ +kotlin.code.style=official +mcVersion=1.21.11 +version=1.21.11-1.2.0 diff --git a/surf-microservice-test/settings.gradle.kts b/surf-microservice-test/settings.gradle.kts new file mode 100644 index 0000000..7fce24d --- /dev/null +++ b/surf-microservice-test/settings.gradle.kts @@ -0,0 +1,9 @@ +pluginManagement { + repositories { + gradlePluginPortal() + mavenLocal() + maven("https://repo.slne.dev/repository/maven-public/") { name = "maven-public" } + } +} + +rootProject.name = "surf-microservice-test"