diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..15e7cd3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,150 @@ +name: Build and Deploy + +on: + push: + branches: + - develop + - main + 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_KEY_ID }}" \ + -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 945f334..8c328f3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,17 +1,14 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.kotlin) alias(libs.plugins.sonatype.central.portal.publisher) `maven-publish` } -val baseVersion = "0.0.1" -val commitHash = System.getenv("COMMIT_HASH") -val timestamp = System.currentTimeMillis() // Temporary to be able to build and publish directly out of fix branch with same commit hash -val snapshotVersion = "${baseVersion}-dev.${timestamp}-${commitHash}" - allprojects { group = "app.simplecloud.plugin" - version = if (commitHash != null) snapshotVersion else baseVersion + version = determineVersion() repositories { mavenCentral() @@ -35,19 +32,32 @@ subprojects { compileOnly(rootProject.libs.bundles.adventure) } + 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) + } } publishing { repositories { maven { name = "simplecloud" - url = uri("https://repo.simplecloud.app/snapshots/") + url = uri(determineRepositoryUrl()) credentials { - username = System.getenv("SIMPLECLOUD_USERNAME")?: (project.findProperty("simplecloudUsername") as? String) - password = System.getenv("SIMPLECLOUD_PASSWORD")?: (project.findProperty("simplecloudPassword") as? String) + username = System.getenv("SIMPLECLOUD_USERNAME") + ?: (project.findProperty("simplecloudUsername") as? String) + password = System.getenv("SIMPLECLOUD_PASSWORD") + ?: (project.findProperty("simplecloudPassword") as? String) } + authentication { create("basic") } @@ -62,11 +72,41 @@ subprojects { } 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/gradle.properties b/gradle.properties new file mode 100644 index 0000000..0529379 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,10 @@ +baseVersion=0.0.1 +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