From 8f982acbb297c74576ccfcf013671016157eac4f Mon Sep 17 00:00:00 2001 From: Vasily Vasilkov Date: Thu, 13 Jul 2023 22:25:35 +0400 Subject: [PATCH 1/4] Update build and workflow files --- .github/workflows/pull-request.yml | 31 ++++++ .github/workflows/push-to-master.yml | 39 +++---- build.gradle.kts | 155 ++++++++++++++++++--------- 3 files changed, 152 insertions(+), 73 deletions(-) create mode 100644 .github/workflows/pull-request.yml diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..1ebd969 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,31 @@ +name: On pull request + +on: [ pull_request ] + +concurrency: on-pull-request + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'corretto' + cache: 'gradle' + + - name: Build + run: ./gradlew devSnapshot printDevSnapshotReleaseNote + env: + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_PASSWORD: ${{ secrets.GPG_SIGNING_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.OSSRH_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + GITHUB_HEAD_REF: ${{ github.head_ref }} diff --git a/.github/workflows/push-to-master.yml b/.github/workflows/push-to-master.yml index 5f81d48..92ca5af 100644 --- a/.github/workflows/push-to-master.yml +++ b/.github/workflows/push-to-master.yml @@ -1,43 +1,36 @@ name: On push to master on: - release: - types: [published] + push: + branches: + - master + +concurrency: on-push-to-master jobs: build: - runs-on: ubuntu-latest steps: - - - name: Checkout full repository history - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Set up JDK 11 - uses: actions/setup-java@v2 + - name: Setup JDK 11 + uses: actions/setup-java@v3 with: java-version: '11' - distribution: 'adopt' - server-id: github - - - name: Enqueue concurrent workflows runs - uses: softprops/turnstyle@v1 - with: - abort-after-seconds: 1800 - poll-interval-seconds: 30 - same-branch-only: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + distribution: 'corretto' + cache: 'gradle' - - name: Build, upload release version to Maven Central and create git release tag with Gradle - run: ./gradlew final closeAndReleaseRepository printFinalReleaseNode + - name: Build + run: ./gradlew final closeAndReleaseStagingRepository printFinalReleaseNote env: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} GPG_SIGNING_PASSWORD: ${{ secrets.GPG_SIGNING_PASSWORD }} - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.OSSRH_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + GITHUB_HEAD_REF: ${{ github.head_ref }} GRGIT_USER: ${{ secrets.GRGIT_USER }} GRGIT_PASS: ${{ secrets.GRGIT_PASS }} diff --git a/build.gradle.kts b/build.gradle.kts index 9b02562..090de25 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,11 +4,11 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { java - signing kotlin("jvm") version "1.6.10" - id("io.codearte.nexus-staging") version "0.22.0" - id("nebula.release") version "15.2.0" - id("maven-publish") + signing + `maven-publish` + id("com.netflix.nebula.release") version "17.2.2" + id("io.github.gradle-nexus.publish-plugin") version "1.3.0" } repositories { @@ -33,22 +33,15 @@ dependencies { testImplementation("org.slf4j:slf4j-simple:1.7.36") } -configure { - sourceCompatibility = JavaVersion.VERSION_11 -} - -java { - withSourcesJar() - withJavadocJar() -} // Kotlin settings -val compileKotlin: KotlinCompile by tasks -compileKotlin.kotlinOptions.jvmTarget = "11" - -val compileTestKotlin: KotlinCompile by tasks -compileTestKotlin.kotlinOptions.jvmTarget = "11" +tasks.withType { + kotlinOptions.jvmTarget = "11" + kotlinOptions.apiVersion = "1.7" + kotlinOptions.languageVersion = "1.7" +} +// Unit tests settings tasks.withType { enableAssertions = true useJUnitPlatform() @@ -59,6 +52,11 @@ tasks.withType { } } +java { + withSourcesJar() + withJavadocJar() +} + val settingsProvider = SettingsProvider() @@ -70,33 +68,51 @@ tasks { } } - // Publish artifacts to Maven Central before pushing new git tag to repo - named("release").get().apply { - dependsOn(named("publish").get()) + afterEvaluate { + // Publish artifacts to Maven Central before pushing new git tag to repo + named("release").get().apply { + dependsOn(named("publishToSonatype").get()) + } + + named("closeAndReleaseStagingRepository").get().apply { + dependsOn(named("final").get()) + } } } - tasks.withType { doFirst { settingsProvider.validateGPGSecrets() } + dependsOn(tasks.getByName("build")) } tasks.withType { doFirst { - settingsProvider.validateOssrhCredentials() + settingsProvider.validateSonatypeCredentials() + } +} + +tasks.register("printFinalReleaseNote") { + doLast { + printFinalReleaseNote( + groupId = PublicationSettings.GROUP_ID, + artifactId = PublicationSettings.ARTIFACT_ID, + sanitizedVersion = project.sanitizeVersion() + ) } + dependsOn(tasks.getByName("final")) } -tasks.register("printFinalReleaseNode") { +tasks.register("printDevSnapshotReleaseNote") { doLast { - printFinalReleaseNode( + printDevSnapshotReleaseNote( groupId = PublicationSettings.GROUP_ID, artifactId = PublicationSettings.ARTIFACT_ID, sanitizedVersion = project.sanitizeVersion() ) } + dependsOn(tasks.getByName("devSnapshot")) } publishing { @@ -139,15 +155,6 @@ publishing { } } } - repositories { - maven { - credentials { - username = settingsProvider.ossrhUsername - password = settingsProvider.ossrhPassword - } - url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") - } - } } signing { @@ -155,17 +162,46 @@ signing { sign(publishing.publications["mavenJava"]) } -nexusStaging { - packageGroup = PublicationSettings.STAGING_PACKAGE_GROUP - username = settingsProvider.ossrhUsername - password = settingsProvider.ossrhPassword +nexusPublishing { + repositories { + sonatype { + useStaging.set(!project.isSnapshotVersion()) + packageGroup.set(PublicationSettings.GROUP_ID) + username.set(settingsProvider.sonatypeUsername) + password.set(settingsProvider.sonatypePassword) +// nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) +// snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) + } + } } +// We want to change SNAPSHOT versions format from: +// ..-dev.#+. (local branch) +// ..-dev.#+ (github pull request) +// to: +// ..-dev+-SNAPSHOT fun Project.sanitizeVersion(): String { - return version.toString() + val version = version.toString() + return if (project.isSnapshotVersion()) { + val githubHeadRef = settingsProvider.githubHeadRef + if (githubHeadRef != null) { + // github pull request + version + .replace(Regex("-dev\\.\\d+\\+[a-f0-9]+$"), "-dev+$githubHeadRef-SNAPSHOT") + } else { + // local branch + version + .replace(Regex("-dev\\.\\d+\\+"), "-dev+") + .replace(Regex("\\.[a-f0-9]+$"), "-SNAPSHOT") + } + } else { + version + } } -fun printFinalReleaseNode(groupId: String, artifactId: String, sanitizedVersion: String) { +fun Project.isSnapshotVersion() = version.toString().contains("-dev.") + +fun printFinalReleaseNote(groupId: String, artifactId: String, sanitizedVersion: String) { println() println("========================================================") println() @@ -187,6 +223,25 @@ fun printFinalReleaseNode(groupId: String, artifactId: String, sanitizedVersion: println() } +fun printDevSnapshotReleaseNote(groupId: String, artifactId: String, sanitizedVersion: String) { + println() + println("========================================================") + println() + println("New developer SNAPSHOT artifact version were published:") + println(" groupId: $groupId") + println(" artifactId: $artifactId") + println(" version: $sanitizedVersion") + println() + println("Discover on Maven Central:") + println(" https://s01.oss.sonatype.org/content/repositories/snapshots/${groupId.replace('.', '/')}/$artifactId/") + println() + println("Edit or delete artifacts on OSS Nexus Repository Manager:") + println(" https://s01.oss.sonatype.org/#nexus-search;gav~$groupId~~~~") + println() + println("========================================================") + println() +} + class SettingsProvider { val gpgSigningKey: String? @@ -195,11 +250,11 @@ class SettingsProvider { val gpgSigningPassword: String? get() = System.getenv(GPG_SIGNING_PASSWORD_PROPERTY) - val ossrhUsername: String? - get() = System.getenv(OSSRH_USERNAME_PROPERTY) + val sonatypeUsername: String? + get() = System.getenv(SONATYPE_USERNAME_PROPERTY) - val ossrhPassword: String? - get() = System.getenv(OSSRH_PASSWORD_PROPERTY) + val sonatypePassword: String? + get() = System.getenv(SONATYPE_PASSWORD_PROPERTY) val githubHeadRef: String? get() = System.getenv(GITHUB_HEAD_REF_PROPERTY) @@ -209,16 +264,16 @@ class SettingsProvider { lazyMessage = { "Both $GPG_SIGNING_KEY_PROPERTY and $GPG_SIGNING_PASSWORD_PROPERTY environment variables must not be empty" } ) - fun validateOssrhCredentials() = require( - value = !ossrhUsername.isNullOrBlank() && !ossrhPassword.isNullOrBlank(), - lazyMessage = { "Both $OSSRH_USERNAME_PROPERTY and $OSSRH_PASSWORD_PROPERTY environment variables must not be empty" } + fun validateSonatypeCredentials() = require( + value = !sonatypeUsername.isNullOrBlank() && !sonatypePassword.isNullOrBlank(), + lazyMessage = { "Both $SONATYPE_USERNAME_PROPERTY and $SONATYPE_PASSWORD_PROPERTY environment variables must not be empty" } ) - companion object { + private companion object { private const val GPG_SIGNING_KEY_PROPERTY = "GPG_SIGNING_KEY" private const val GPG_SIGNING_PASSWORD_PROPERTY = "GPG_SIGNING_PASSWORD" - private const val OSSRH_USERNAME_PROPERTY = "OSSRH_USERNAME" - private const val OSSRH_PASSWORD_PROPERTY = "OSSRH_PASSWORD" + private const val SONATYPE_USERNAME_PROPERTY = "SONATYPE_USERNAME" + private const val SONATYPE_PASSWORD_PROPERTY = "SONATYPE_PASSWORD" private const val GITHUB_HEAD_REF_PROPERTY = "GITHUB_HEAD_REF" } } @@ -234,7 +289,7 @@ object PublicationSettings { const val DEVELOPER_ID = "vgv" const val DEVELOPER_NAME = "Vasily Vasilkov" - const val DEVELOPER_EMAIL = "vgv@ecwid.com" + const val DEVELOPER_EMAIL = "vasily.vasilkov@lightspeedhq.com" const val LICENSE_NAME = "The Apache License, Version 2.0" const val LICENSE_URL = "https://www.apache.org/licenses/LICENSE-2.0.txt" From 2424028a4db6e64973b874eae14796b02c33cc5e Mon Sep 17 00:00:00 2001 From: Vasily Vasilkov Date: Thu, 13 Jul 2023 22:26:45 +0400 Subject: [PATCH 2/4] Fix mistype --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 1ebd969..0c7f3ee 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -14,7 +14,7 @@ jobs: with: fetch-depth: 0 - - name: Setup JDK 17 + - name: Setup JDK 11 uses: actions/setup-java@v3 with: java-version: '11' From 3c7202c197a299d7e7e745be235be8c815dda558 Mon Sep 17 00:00:00 2001 From: Vasily Vasilkov Date: Thu, 13 Jul 2023 22:28:42 +0400 Subject: [PATCH 3/4] Fix sonatype path --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 090de25..3e62cc9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -233,10 +233,10 @@ fun printDevSnapshotReleaseNote(groupId: String, artifactId: String, sanitizedVe println(" version: $sanitizedVersion") println() println("Discover on Maven Central:") - println(" https://s01.oss.sonatype.org/content/repositories/snapshots/${groupId.replace('.', '/')}/$artifactId/") + println(" https://oss.sonatype.org/content/repositories/snapshots/${groupId.replace('.', '/')}/$artifactId/") println() println("Edit or delete artifacts on OSS Nexus Repository Manager:") - println(" https://s01.oss.sonatype.org/#nexus-search;gav~$groupId~~~~") + println(" https://oss.sonatype.org/#nexus-search;gav~$groupId~~~~") println() println("========================================================") println() From 197627e29f6bffc6365cda6dcf70a7c4487704d8 Mon Sep 17 00:00:00 2001 From: Vasily Vasilkov Date: Thu, 13 Jul 2023 22:32:48 +0400 Subject: [PATCH 4/4] Release on any master change, but README.md --- .github/workflows/push-to-master.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/push-to-master.yml b/.github/workflows/push-to-master.yml index 92ca5af..ed6d46a 100644 --- a/.github/workflows/push-to-master.yml +++ b/.github/workflows/push-to-master.yml @@ -4,6 +4,8 @@ on: push: branches: - master + paths-ignore: + - README.md concurrency: on-push-to-master