diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..425e7d2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,150 @@ +name: Build and Deploy + +on: + push: + branches: + - develop # For snapshot builds + - main # For release builds + paths-ignore: + - '**.md' + - '.gitignore' + - 'LICENSE' + workflow_dispatch: + inputs: + channel: + description: 'Release Channel' + required: true + default: 'snapshot' + type: choice + options: + - snapshot + - rc + - release + version: + description: 'Version (only for release channel)' + required: false + type: string + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Set up JDK 21 + uses: actions/setup-java@v4.7.0 + with: + distribution: 'temurin' + java-version: '21' + cache: 'gradle' + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + with: + build-scan-publish: true + build-scan-terms-of-use-url: 'https://gradle.com/help/legal-terms-of-use' + build-scan-terms-of-use-agree: 'yes' + + - name: Make Gradle Wrapper Executable + run: chmod +x ./gradlew + + - name: Determine Version and Channel + id: version + run: | + # If triggered manually, use workflow input; otherwise, decide based on branch name + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + CHANNEL="${{ github.event.inputs.channel }}" + if [[ "$CHANNEL" == "release" && -n "${{ github.event.inputs.version }}" ]]; then + VERSION="${{ github.event.inputs.version }}" + fi + elif [[ "${{ github.ref }}" == "refs/heads/main" ]]; then + CHANNEL="release" + else + CHANNEL="snapshot" + fi + + # Get the commit hash (short version) + COMMIT_HASH=$(git rev-parse --short HEAD) + echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_ENV + + # Read the base version from gradle.properties + BASE_VERSION=$(grep '^baseVersion=' gradle.properties | cut -d'=' -f2) + if [ "$CHANNEL" == "release" ]; then + FINAL_VERSION="$BASE_VERSION" + elif [ "$CHANNEL" == "rc" ]; then + FINAL_VERSION="${BASE_VERSION}-rc.${COMMIT_HASH}" + else + FINAL_VERSION="${BASE_VERSION}-SNAPSHOT.${COMMIT_HASH}" + fi + echo "Determined version: $FINAL_VERSION" + + # Set outputs for later steps + echo "CHANNEL=$CHANNEL" >> $GITHUB_OUTPUT + echo "VERSION=$FINAL_VERSION" >> $GITHUB_OUTPUT + + - name: Build with Gradle + run: | + ./gradlew --parallel --build-cache clean build shadowJar \ + -PreleaseType=${{ steps.version.outputs.CHANNEL }} \ + -Pversion=${{ steps.version.outputs.VERSION }} + env: + COMMIT_HASH: ${{ env.COMMIT_HASH }} + + - name: Publish to SimpleCloud Repository + run: | + if [[ "${{ steps.version.outputs.CHANNEL }}" == "release" ]]; then + export GPG_TTY=$(tty) + export GRADLE_OPTS="-Dorg.gradle.daemon=false" + ./gradlew --no-daemon --parallel --build-cache publishMavenJavaPublicationToSimplecloudRepository \ + -PreleaseType=${{ steps.version.outputs.CHANNEL }} \ + -Pversion=${{ steps.version.outputs.VERSION }} \ + -Psigning.gnupg.keyName="${{ secrets.GPG_PRIVATE_KEY }}" \ + -Psigning.gnupg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + else + ./gradlew --parallel --build-cache publishMavenJavaPublicationToSimplecloudRepository \ + -PreleaseType=${{ steps.version.outputs.CHANNEL }} \ + -Pversion=${{ steps.version.outputs.VERSION }} + fi + env: + COMMIT_HASH: ${{ env.COMMIT_HASH }} + SIMPLECLOUD_USERNAME: ${{ secrets.SIMPLECLOUD_USERNAME }} + SIMPLECLOUD_PASSWORD: ${{ secrets.SIMPLECLOUD_PASSWORD }} + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }} + ORG_GRADLE_PROJECT_signingPassphrase: ${{ secrets.GPG_PASSPHRASE }} + + - name: Prepare Artifacts + run: | + mkdir -p release-artifacts + find . -type f -name "*.jar" -path "*/build/libs/*.jar" -not -path "./build/libs/*" \ + -not -name "*${{ steps.version.outputs.VERSION }}*" \ + -exec cp {} release-artifacts/ \; + + - name: Update Channel Tag + run: | + git config user.name "GitHub Actions" + git config user.email "actions@github.com" + # Delete any existing channel tag locally and remotely + git tag -d ${{ steps.version.outputs.CHANNEL }} || true + git push origin :refs/tags/${{ steps.version.outputs.CHANNEL }} || true + # Create a new tag at the current commit + git tag -a ${{ steps.version.outputs.CHANNEL }} -m "Latest ${{ steps.version.outputs.CHANNEL }} build (v${{ steps.version.outputs.VERSION }})" + git push origin ${{ steps.version.outputs.CHANNEL }} --force + + - name: Create Channel Release + uses: softprops/action-gh-release@v2 + with: + name: "${{ steps.version.outputs.CHANNEL }} channel" + tag_name: ${{ steps.version.outputs.CHANNEL }} + body: | + Latest build in the ${{ steps.version.outputs.CHANNEL }} channel. + Version: ${{ steps.version.outputs.VERSION }} + Commit: ${{ github.sha }} + prerelease: ${{ steps.version.outputs.CHANNEL != 'release' }} + files: release-artifacts/*.jar + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 486ecae..a02c384 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.kotlin) @@ -7,13 +8,9 @@ plugins { `maven-publish` } -val baseVersion = "0.0.30" -val commitHash = System.getenv("COMMIT_HASH") -val snapshotversion = "${baseVersion}-dev.$commitHash" - allprojects { group = "app.simplecloud.controller" - version = if (commitHash != null) snapshotversion else baseVersion + version = determineVersion() repositories { mavenCentral() @@ -33,51 +30,35 @@ subprojects { implementation(rootProject.libs.kotlin.jvm) } - publishing { - repositories { - maven { - name = "simplecloud" - url = uri("https://repo.simplecloud.app/snapshots/") - credentials { - username = System.getenv("SIMPLECLOUD_USERNAME")?: (project.findProperty("simplecloudUsername") as? String) - password = System.getenv("SIMPLECLOUD_PASSWORD")?: (project.findProperty("simplecloudPassword") as? String) - } - authentication { - create("basic") - } - } - } - - publications { - // Not publish controller-runtime - if (project.name == "controller-runtime") { - return@publications - } - - create("mavenJava") { - from(components["java"]) - } - } - } - java { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } kotlin { jvmToolchain(21) + compilerOptions { + languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) + jvmTarget.set(JvmTarget.JVM_21) } } - tasks.named("shadowJar", ShadowJar::class) { - mergeServiceFiles() - archiveFileName.set("${project.name}.jar") - } + tasks { + withType { + options.isFork = true + options.isIncremental = true + } + + named("shadowJar", ShadowJar::class) { + mergeServiceFiles() - tasks.test { - useJUnitPlatform() + archiveFileName.set("${project.name}.jar") + } + + test { + useJUnitPlatform() + } } centralPortal { @@ -89,7 +70,7 @@ subprojects { pom { name.set("SimpleCloud controller") description.set("The heart of SimpleCloud v3") - url.set("https://github.com/theSimpleCloud/simplecloud-controller") + url.set("https://github.com/simplecloudapp/simplecloud-controller") developers { developer { @@ -108,18 +89,72 @@ subprojects { } } scm { - url.set("https://github.com/theSimpleCloud/simplecloud-controller.git") - connection.set("git:git@github.com:theSimpleCloud/simplecloud-controller.git") + url.set("https://github.com/simplecloudapp/simplecloud-controller.git") + connection.set("git:git@github.com:simplecloudapp/simplecloud-controller.git") + } + } + } + + publishing { + repositories { + maven { + name = "simplecloud" + url = uri(determineRepositoryUrl()) + credentials { + username = System.getenv("SIMPLECLOUD_USERNAME") + ?: (project.findProperty("simplecloudUsername") as? String) + password = System.getenv("SIMPLECLOUD_PASSWORD") + ?: (project.findProperty("simplecloudPassword") as? String) + } + authentication { + create("basic") + } + } + } + + publications { + create("mavenJava") { + from(components["java"]) } } } signing { - if (commitHash != null) { + val releaseType = project.findProperty("releaseType")?.toString() ?: "snapshot" + if (releaseType != "release") { return@signing } + if (hasProperty("signingPassphrase")) { + val signingKey: String? by project + val signingPassphrase: String? by project + useInMemoryPgpKeys(signingKey, signingPassphrase) + } else { + useGpgCmd() + } + sign(publishing.publications) - useGpgCmd() + } +} + +fun determineVersion(): String { + val baseVersion = project.findProperty("baseVersion")?.toString() ?: "0.0.0" + val releaseType = project.findProperty("releaseType")?.toString() ?: "snapshot" + val commitHash = System.getenv("COMMIT_HASH") ?: "local" + + return when (releaseType) { + "release" -> baseVersion + "rc" -> "$baseVersion-rc.$commitHash" + "snapshot" -> "$baseVersion-SNAPSHOT.$commitHash" + else -> "$baseVersion-SNAPSHOT.local" + } +} + +fun determineRepositoryUrl(): String { + val baseUrl = "https://repo.simplecloud.app/" + return when (project.findProperty("releaseType")?.toString() ?: "snapshot") { + "release" -> "$baseUrl/releases" + "rc" -> "$baseUrl/rc" + else -> "$baseUrl/snapshots" } } \ No newline at end of file diff --git a/controller-api/build.gradle.kts b/controller-api/build.gradle.kts index ecc433b..eaa4321 100644 --- a/controller-api/build.gradle.kts +++ b/controller-api/build.gradle.kts @@ -6,6 +6,7 @@ dependencies { tasks.named("shadowJar", ShadowJar::class) { mergeServiceFiles() + relocate("com", "app.simplecloud.external.com") relocate("google", "app.simplecloud.external.google") relocate("io", "app.simplecloud.external.io") @@ -13,5 +14,6 @@ tasks.named("shadowJar", ShadowJar::class) { relocate("javax", "app.simplecloud.external.javax") relocate("android", "app.simplecloud.external.android") relocate("build.buf.gen.simplecloud", "app.simplecloud.buf") + archiveFileName.set("${project.name}.jar") } \ No newline at end of file diff --git a/controller-runtime/build.gradle.kts b/controller-runtime/build.gradle.kts index d44a354..e23d62d 100644 --- a/controller-runtime/build.gradle.kts +++ b/controller-runtime/build.gradle.kts @@ -8,13 +8,15 @@ dependencies { api(project(":controller-shared")) api(libs.bundles.jooq) api(libs.sqlite.jdbc) - jooqCodegen(libs.jooq.meta.extensions) + implementation(libs.simplecloud.metrics) implementation(libs.bundles.log4j) implementation(libs.clikt) implementation(libs.spring.crypto) implementation(libs.spotify.completablefutures) implementation(libs.envoy.controlplane) + + jooqCodegen(libs.jooq.meta.extensions) } application { diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..a434d49 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,10 @@ +baseVersion=0.0.30 +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true +org.gradle.daemon=true +org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError +kotlin.incremental=true +kotlin.incremental.js=true +kotlin.caching.enabled=true +kotlin.parallel.tasks.in.project=true \ No newline at end of file