From d5a1b58f0e20ddd3ad785e7adedee2f784678741 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Tue, 26 Sep 2023 18:09:22 +0300 Subject: [PATCH] Migration to new package in Maven Central (#1744) - copied CI scripts to build SNAPSHOT and RELEASE - removed workaround for mavenLocal --- .github/workflows/build_and_test.yml | 32 ++- .github/workflows/diktat_snapshot.yml | 22 +- .github/workflows/release.yml | 127 +++------ build.gradle.kts | 28 +- diktat-api/build.gradle.kts | 4 +- diktat-cli/build.gradle.kts | 25 +- diktat-common/build.gradle.kts | 2 +- diktat-gradle-plugin/build.gradle.kts | 27 +- diktat-ktlint-engine/build.gradle.kts | 4 +- diktat-rules/build.gradle.kts | 2 +- diktat-test-framework/build.gradle.kts | 1 + gradle/libs.versions.toml | 35 +-- gradle/plugins/build.gradle.kts | 16 +- .../buildutils/PublishingConfiguration.kt | 246 +++++++++++++----- .../code-quality-convention.gradle.kts | 5 +- ...detekt-convention-configuration.gradle.kts | 2 +- ...iktat-convention-configuration.gradle.kts} | 0 .../publishing-configuration.gradle.kts | 32 +-- ...ublishing-default-configuration.gradle.kts | 19 ++ ...g-signing-default-configuration.gradle.kts | 21 -- settings.gradle.kts | 12 + 21 files changed, 367 insertions(+), 295 deletions(-) rename gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/{diktat-convention-configuration.gradle.txt => diktat-convention-configuration.gradle.kts} (100%) create mode 100644 gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-default-configuration.gradle.kts delete mode 100644 gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-signing-default-configuration.gradle.kts diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 9964a49e0f..1c8f0a3d1e 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -14,6 +14,14 @@ concurrency: group: ${{ github.ref == 'refs/heads/master' && format('{0}-{1}', github.workflow, github.sha) || format('{0}-{1}', github.workflow, github.ref) }} cancel-in-progress: true +env: + GRADLE_OPTS: -Dorg.gradle.daemon=true -Dorg.gradle.parallel=true -Dorg.gradle.welcome=never + GPG_SEC: ${{ secrets.PGP_SEC }} + GPG_PASSWORD: ${{ secrets.PGP_PASSWORD }} + OSSRH_USERNAME: ${{ secrets.SONATYPE_USER }} + OSSRH_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + jobs: build_and_test_with_code_coverage: name: Build, test and upload code coverage @@ -233,6 +241,7 @@ jobs: contents: write pull-requests: write statuses: write + packages: write steps: - uses: actions/checkout@v4 @@ -305,6 +314,27 @@ jobs: fail_ci_if_error: false token: ${{ secrets.CODECOV_TOKEN }} + - name: 'Publish a snapshot to GitHub' + id: publish-github + if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && github.ref == 'refs/heads/master' }} + uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + arguments: | + -Preckon.stage=snapshot + publishAllPublicationsToGitHubRepository + + - name: 'Publish a snapshot to Maven Central' + id: publish-sonatype + if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && github.ref == 'refs/heads/master' }} + uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + arguments: | + -Preckon.stage=snapshot + publishToSonatype + closeAndReleaseSonatypeStagingRepository + report: name: Publish JUnit test results if: ${{ always() }} @@ -332,7 +362,6 @@ jobs: with: check_name: JUnit Tests (${{ runner.os }}, EnricoMi/publish-unit-test-result-action@v2) junit_files: | - **/target/*-reports/TEST-*.xml **/build/test-results/*/TEST-*.xml - name: JUnit Tests (EnricoMi/publish-unit-test-result-action@v2, Windows or Mac OS X) @@ -341,5 +370,4 @@ jobs: with: check_name: JUnit Tests (${{ runner.os }}, EnricoMi/publish-unit-test-result-action@v2) junit_files: | - **/target/*-reports/TEST-*.xml **/build/test-results/*/TEST-*.xml diff --git a/.github/workflows/diktat_snapshot.yml b/.github/workflows/diktat_snapshot.yml index b9cba9108b..e2143b0289 100644 --- a/.github/workflows/diktat_snapshot.yml +++ b/.github/workflows/diktat_snapshot.yml @@ -54,33 +54,13 @@ jobs: :generateLibsForDiktatSnapshot -x detekt -x test - # FixMe: return after 2.0.0 - # -x diktatCheck - - - name: 'Copy files and set flags' - run: | - echo "DIKTAT_SNAPSHOT=1" >> $GITHUB_ENV - mv gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/diktat-convention-configuration.gradle.txt gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/diktat-convention-configuration.gradle.kts + -x diktatCheck - name: 'Override ' run: | mv gradle/libs.versions.toml gradle/libs.versions.toml_current mv build/diktat-snapshot/libs.versions.toml_snapshot gradle/libs.versions.toml - # FixMe: remove after 2.0.0 - - name: 'Small hack to inject implementation and to run diktat properly from snapshot' - run: | - #!/bin/bash - file_path=gradle/plugins/build.gradle.kts - string_to_insert=' - dependencies { - implementation(libs.diktat.gradle.plugin) { - exclude("io.github.detekt.sarif4k", "sarif4k") - } - }' - - echo $string_to_insert >> $file_path - # copied from .github/workflows/diktat.yml - uses: gradle/gradle-build-action@v2 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 187d4d4bbe..7055d153db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,101 +5,60 @@ on: tags: - 'v*' +env: + GRADLE_OPTS: -Dorg.gradle.daemon=true -Dorg.gradle.parallel=true -Dorg.gradle.welcome=never + GPG_SEC: ${{ secrets.PGP_SEC }} + GPG_PASSWORD: ${{ secrets.PGP_PASSWORD }} + OSSRH_USERNAME: ${{ secrets.SONATYPE_USER }} + OSSRH_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + jobs: - build: - name: Build release + release: + name: 'Release' runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up JDK 11 + - uses: actions/checkout@v3 + with: + # Fetch Git tags, so that semantic version can be calculated. + # Alternatively, run `git fetch --prune --unshallow --tags` as the + # next step, see + # https://github.com/actions/checkout/issues/206#issuecomment-607496604. + fetch-depth: 0 + + - name: 'Set up Java' uses: actions/setup-java@v3 with: - distribution: zulu java-version: 11 - - name: Cache local Maven repository - uses: actions/cache@v3 + distribution: temurin + + - name: 'Publish a release to GitHub' + id: publish-github + uses: gradle/gradle-build-action@v2 with: - path: ~/.m2/repository - key: maven-build-${{ hashFiles('**/pom.xml') }} - restore-keys: | - maven-build- - - name: Setup environment - env: - DIKTAT_GPG_PUB: ${{ secrets.DIKTAT_PGP_PUB }} - DIKTAT_GPG_SEC: ${{ secrets.DIKTAT_PGP_SEC }} - # Note: maven-help-plugin requires non-interactive mode (do not add -B flag). - run: | - previous_version=$(printf 'VERSION=${diktat-check.version}\n0\n' | mvn help:evaluate | grep '^VERSION' | cut -d= -f2) - echo "PREVIOUS_VERSION=$previous_version" >> $GITHUB_ENV - echo "RELEASE_VERSION=${GITHUB_REF#'refs/tags/v'}" >> $GITHUB_ENV - echo "$DIKTAT_GPG_PUB" > ~/diktat.pubring.gpg - echo "$DIKTAT_GPG_SEC" > ~/diktat.secring.gpg - gpg --import ~/diktat.pubring.gpg - gpg --batch --import ~/diktat.secring.gpg # --batch suppresses intercatively asking passphrase - - name: Set version - run: mvn -B versions:set -DnewVersion=${{ env.RELEASE_VERSION }} versions:commit - - name: Create settings.xml - uses: whelk-io/maven-settings-xml-action@v21 + gradle-version: wrapper + arguments: | + publishAllPublicationsToGitHubRepository + + - name: 'Publish a release to Maven Central' + id: publish-sonatype + uses: gradle/gradle-build-action@v2 with: - servers: | - [ - { "id": "ossrh", "username": "${{ secrets.SONATYPE_USER }}", "password": "${{ secrets.SONATYPE_PASSWORD }}" }, - { "id": "gpg.passphrase", "passphrase": "${{ secrets.DIKTAT_GPG_PASS }}" }, - { "id": "kotlin-maven-plugin-tools", "username": "${{github.actor}}", "password": "${{ secrets.GITHUB_TOKEN }}" } - ] - - name: Deploy artifacts - run: mvn -B -Dstyle.color=always clean deploy -Prelease --projects '!diktat-ruleset' - - name: Build diktat.jar - run: mvn -B -Dstyle.color=always package --projects diktat-ruleset - - name: Create Github Release - id: create_release + gradle-version: wrapper + arguments: | + publishToSonatype + closeAndReleaseSonatypeStagingRepository + + github_release: + needs: release + name: 'Github Release' + runs-on: ubuntu-latest + steps: + - name: 'Github Release' uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} - release_name: Release ${{ env.RELEASE_VERSION }} + release_name: Release ${{ github.ref }} draft: false prerelease: false - - name: Upload assets to github releases - id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./diktat-ruleset/target/diktat-${{ env.RELEASE_VERSION }}.jar - asset_name: diktat-${{ env.RELEASE_VERSION }}.jar - asset_content_type: application/zip - - name: Update versions in pom.xml and documentation, update examples - id: update-versions - run: | - mvn -B versions:set -DnextSnapshot=true -DprocessAllModules=true versions:commit - mvn versions:set-property -Dproperty=diktat-check.version -DnewVersion=${{ env.RELEASE_VERSION }} - sed -i "s/$PREVIOUS_VERSION/$RELEASE_VERSION/g" README.md || echo "File README.md hasn't been updated!" - for file in examples/{maven/pom.xml,gradle-groovy-dsl/build.gradle,{gradle-kotlin-dsl,gradle-kotlin-dsl-multiproject}/build.gradle.kts} - do - sed -i "s/$PREVIOUS_VERSION/$RELEASE_VERSION/g" $file || echo "File $file hasn't been updated!" - cp diktat-rules/src/main/resources/diktat-analysis.yml $(dirname $file) - done - next_snapshot_version=$(printf 'VERSION=${project.version}\n0\n' | mvn help:evaluate | grep '^VERSION' | cut -d= -f2) - # Update the version in `examples/maven/pom.xml` - # (which is not a part of the multi-module project). - for file in examples/maven/pom.xml - do - sed -i "s|\(\)[[:digit:]]\(\.[[:digit:]]\)\+-SNAPSHOT\(\)|\1${next_snapshot_version}\3|g" "${file}" || echo "File ${file} hasn't been updated (2nd sed pass)" - done - echo "version=$next_snapshot_version" > info/buildSrc/gradle.properties - - name: Create pull request - uses: peter-evans/create-pull-request@v5 - with: - author: GitHub - commit-message: Prepare next development iteration after release ${{ env.RELEASE_VERSION }} - branch: infra/diktat-version-update-to-${{ env.RELEASE_VERSION }} - title: Update versions in pom.xml and documentation after ${{ env.RELEASE_VERSION }} release - body: | - * Versions are updated in pom.xml, README.md and in examples - * Current project version is incremented to the next snapshot - base: master diff --git a/build.gradle.kts b/build.gradle.kts index 4ea51e2334..afba69b985 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,3 @@ -import com.saveourtool.diktat.buildutils.configureSigning import org.jetbrains.kotlin.incremental.createDirectory import java.nio.file.Files @@ -26,10 +25,12 @@ talaiot { project.description = "diKTat kotlin formatter and fixer" -configureSigning() - tasks.create("generateLibsForDiktatSnapshot") { - val dir = rootProject.buildDir.resolve("diktat-snapshot") + val dir = rootProject.layout + .buildDirectory + .dir("diktat-snapshot") + .get() + .asFile val dependencies = setOf( rootProject.project(":diktat-common"), @@ -86,13 +87,15 @@ fun File.pathToMavenArtifact(project: Project): File = project.group.toString() /** * @return generated pom.xml for project dependency */ -fun Project.pomFile(): File = buildDir.resolve("publications") - .let { publicationsDir -> - publicationsDir.resolve("pluginMaven") - .takeIf { it.exists() } - ?: publicationsDir.resolve("maven") +fun Project.pomFile(): File = layout.buildDirectory + .dir("publications") + .map { publicationsDir -> + publicationsDir.dir("pluginMaven") + .takeIf { it.asFile.exists() } + ?: publicationsDir.dir("maven") } - .resolve("pom-default.xml") + .map { it.file("pom-default.xml").asFile } + .get() /** * @return file name of pom.xml for project @@ -102,7 +105,10 @@ fun Project.pomFileName(): String = "$name-$version.pom" /** * @return generated artifact for project dependency */ -fun Project.artifactFile(): File = buildDir.resolve("libs/${artifactFileName()}") +fun Project.artifactFile(): File = layout.buildDirectory + .dir("libs") + .map { it.file(artifactFileName()).asFile } + .get() /** * @return file name of artifact for project dependency diff --git a/diktat-api/build.gradle.kts b/diktat-api/build.gradle.kts index ed59aeca9e..9131b4b24b 100644 --- a/diktat-api/build.gradle.kts +++ b/diktat-api/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") id("com.saveourtool.diktat.buildutils.code-quality-convention") - id("com.saveourtool.diktat.buildutils.publishing-signing-default-configuration") + id("com.saveourtool.diktat.buildutils.publishing-default-configuration") alias(libs.plugins.kotlin.plugin.serialization) } @@ -13,7 +13,7 @@ dependencies { } val generateDiktatVersionFile by tasks.registering { - val outputDir = File("$buildDir/generated/src") + val outputDir = layout.buildDirectory.dir("generated/src").get().asFile val versionsFile = outputDir.resolve("generated/DiktatVersion.kt") val diktatVersion = version.toString() diff --git a/diktat-cli/build.gradle.kts b/diktat-cli/build.gradle.kts index f5e315c7cc..2dddb2340c 100644 --- a/diktat-cli/build.gradle.kts +++ b/diktat-cli/build.gradle.kts @@ -1,3 +1,4 @@ +import com.github.jengelman.gradle.plugins.shadow.ShadowExtension import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.jetbrains.kotlin.incremental.createDirectory @@ -5,7 +6,7 @@ import org.jetbrains.kotlin.incremental.createDirectory plugins { id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") id("com.saveourtool.diktat.buildutils.code-quality-convention") - id("com.saveourtool.diktat.buildutils.publishing-signing-default-configuration") + id("com.saveourtool.diktat.buildutils.publishing-configuration") alias(libs.plugins.kotlin.plugin.serialization) alias(libs.plugins.shadow) } @@ -27,9 +28,12 @@ dependencies { testImplementation(libs.mockito) } -val addLicenseTask = tasks.register("addLicense") { +val addLicenseTask: TaskProvider = tasks.register("addLicense") { val licenseFile = rootProject.file("LICENSE") - val outputDir = File("$buildDir/generated/src") + val outputDir = layout.buildDirectory + .dir("generated/src") + .get() + .asFile inputs.file(licenseFile) outputs.dir(outputDir) @@ -70,4 +74,19 @@ tasks { build { dependsOn(shadowJar) } + test { + dependsOn(shadowJar) + } +} + +publishing { + publications { + // it creates a publication for shadowJar + create("shadow") { + // https://github.com/johnrengelman/shadow/issues/417#issuecomment-830668442 + project.extensions.configure { + component(this@create) + } + } + } } diff --git a/diktat-common/build.gradle.kts b/diktat-common/build.gradle.kts index 1093b8fd21..fc1c57c0ed 100644 --- a/diktat-common/build.gradle.kts +++ b/diktat-common/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") id("com.saveourtool.diktat.buildutils.code-quality-convention") - id("com.saveourtool.diktat.buildutils.publishing-signing-default-configuration") + id("com.saveourtool.diktat.buildutils.publishing-default-configuration") alias(libs.plugins.kotlin.plugin.serialization) } diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index ea04b3c8fa..0d9ad03085 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -1,10 +1,10 @@ -import com.saveourtool.diktat.buildutils.configureSigning import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.getCurrentOperatingSystem import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") id("com.saveourtool.diktat.buildutils.code-quality-convention") + id("com.saveourtool.diktat.buildutils.publishing-default-configuration") id("pl.droidsonroids.jacoco.testkit") version "1.0.12" id("org.gradle.test-retry") version "1.5.5" id("com.gradle.plugin-publish") version "1.2.1" @@ -28,7 +28,7 @@ dependencies { tasks.withType { kotlinOptions { - // kotlin 1.4 api is latest support for kotlin 1.9 + // kotlin 1.4 api is the latest support version in kotlin 1.9 // min supported Gradle is 7.0 languageVersion = "1.4" apiVersion = "1.4" @@ -89,9 +89,14 @@ jacocoTestKit { tasks.jacocoTestReport { shouldRunAfter(tasks.withType()) executionData( - fileTree("$buildDir/jacoco").apply { - include("*.exec") - } + layout.buildDirectory + .dir("jacoco") + .map { jacocoDir -> + jacocoDir.asFileTree + .matching { + include("*.exec") + } + } ) reports { // xml report is used by codecov @@ -99,4 +104,14 @@ tasks.jacocoTestReport { } } -configureSigning() +afterEvaluate { + tasks.named("javadocJar") { + enabled = false + } + tasks.named("generateMetadataFileForPluginMavenPublication") { + dependsOn(tasks.named("dokkaJar")) + } + tasks.named("generateMetadataFileForMavenPublication") { + dependsOn(tasks.named("dokkaJar")) + } +} diff --git a/diktat-ktlint-engine/build.gradle.kts b/diktat-ktlint-engine/build.gradle.kts index 0e589a40e8..11869f5d05 100644 --- a/diktat-ktlint-engine/build.gradle.kts +++ b/diktat-ktlint-engine/build.gradle.kts @@ -3,7 +3,7 @@ import org.gradle.accessors.dm.LibrariesForLibs plugins { id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") id("com.saveourtool.diktat.buildutils.code-quality-convention") - id("com.saveourtool.diktat.buildutils.publishing-signing-default-configuration") + id("com.saveourtool.diktat.buildutils.publishing-default-configuration") } project.description = "This module builds diktat-api implementation using ktlint" @@ -34,7 +34,7 @@ val ktlintVersion: String = the() .get() val generateKtlintVersionFile by tasks.registering { - val outputDir = File("$buildDir/generated/src") + val outputDir = layout.buildDirectory.dir("generated/src").get().asFile val versionsFile = outputDir.resolve("generated/KtLintVersion.kt") inputs.property("ktlint version", ktlintVersion) diff --git a/diktat-rules/build.gradle.kts b/diktat-rules/build.gradle.kts index 02d3accc38..9e03d01bb3 100644 --- a/diktat-rules/build.gradle.kts +++ b/diktat-rules/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") id("com.saveourtool.diktat.buildutils.code-quality-convention") - id("com.saveourtool.diktat.buildutils.publishing-signing-default-configuration") + id("com.saveourtool.diktat.buildutils.publishing-default-configuration") alias(libs.plugins.kotlin.ksp) idea } diff --git a/diktat-test-framework/build.gradle.kts b/diktat-test-framework/build.gradle.kts index 0be75f8297..03a1157419 100644 --- a/diktat-test-framework/build.gradle.kts +++ b/diktat-test-framework/build.gradle.kts @@ -1,6 +1,7 @@ plugins { id("com.saveourtool.diktat.buildutils.kotlin-jvm-configuration") id("com.saveourtool.diktat.buildutils.code-quality-convention") + id("com.saveourtool.diktat.buildutils.publishing-default-configuration") } project.description = "Test framework for diktat" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ae1a1599bb..e48c5b3018 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,9 +8,9 @@ junit-platfrom = "1.10.0" guava = "32.1.2-jre" commons-cli = "1.5.0" commons-io = "2.13.0" -kotlinpoet = "1.12.0" detekt = "1.23.1" -dokka = "1.7.20" +dokka = "1.9.0" +gradle-nexus-publish-plugin = "1.3.0" jacoco = "0.8.8" # maven maven-api = "3.9.4" @@ -19,7 +19,6 @@ maven-plugin-testing-harness = "3.3.0" plexus = "2.0" jbool = "1.24" -# downgraded to be compliance with ktlint kotlin-logging = "5.1.0" log4j2 = "2.20.0" kaml = "0.55.0" @@ -35,26 +34,11 @@ gradle-shadow = "8.1.1" # copied from save-cloud jetbrains-annotations = "24.0.1" -save-cli = "0.3.9" -ktor = "2.2.4" -okio = "3.3.0" -kotlinx-datetime = "0.4.0" kotlinx-coroutines = "1.7.3" assertj = "3.24.2" -diktat = "2.0.0" -jgit = "6.5.0.202303070854-r" -mockito = "5.2.0" -mockito-kotlin = "4.1.0" -testcontainers = "1.17.6" -okhttp3 = "4.10.0" +diktat = "1.3.0-SNAPSHOT" reckon = "0.18.0" -commons-compress = "1.22" -zip4j = "2.11.5" -ktoml = "0.4.1" -springdoc = "1.6.15" spotless = "6.21.0" -arrow-kt = "1.1.5" -publish = "1.3.0" download = "5.5.0" [plugins] @@ -72,16 +56,9 @@ download = { id = "de.undercouch.download", version.ref = "download" } shadow = { id = "com.github.johnrengelman.shadow", version.ref = "gradle-shadow" } [libraries] -save-common = { module = "com.saveourtool.save:save-common", version.ref = "save-cli" } -save-common-jvm = { module = "com.saveourtool.save:save-common-jvm", version.ref = "save-cli" } -save-core = { module = "com.saveourtool.save:save-core", version.ref = "save-cli" } -save-core-jvm = { module = "com.saveourtool.save:save-core-jvm", version.ref = "save-cli" } -save-plugins-fix = { module = "com.saveourtool.save:fix-plugin", version.ref = "save-cli" } -save-plugins-fix-jvm = { module = "com.saveourtool.save:fix-plugin-jvm", version.ref = "save-cli" } -save-plugins-warn-jvm = { module = "com.saveourtool.save:warn-plugin-jvm", version.ref = "save-cli" } -save-plugins-fixAndWarn-jvm = { module = "com.saveourtool.save:fix-and-warn-plugin-jvm", version.ref = "save-cli" } -save-reporters = { module = "com.saveourtool.save:save-reporters", version.ref = "save-cli" } -publish-gradle-plugin = { module = "io.github.gradle-nexus:publish-plugin", version.ref = "publish"} +# plugins as dependency +dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } +gradle-nexus-publish-plugin = { module = "io.github.gradle-nexus:publish-plugin", version.ref = "gradle-nexus-publish-plugin"} download-plugin = { module = "de.undercouch:gradle-download-task", version.ref = "download" } # kotlin diff --git a/gradle/plugins/build.gradle.kts b/gradle/plugins/build.gradle.kts index 974faac77f..d85507ac24 100644 --- a/gradle/plugins/build.gradle.kts +++ b/gradle/plugins/build.gradle.kts @@ -12,6 +12,12 @@ repositories { url = this@run.toURI() } } + maven { + url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") + content { + includeGroup("com.saveourtool.diktat") + } + } mavenCentral() gradlePluginPortal() } @@ -32,13 +38,13 @@ run { implementation(libs.detekt.gradle.plugin) { exclude("io.github.detekt.sarif4k", "sarif4k") } - // FixMe: return after 2.0.0 - /* implementation(libs.diktat.gradle.plugin) { - exclude("io.github.detekt.sarif4k", "sarif4k") - }*/ + implementation(libs.diktat.gradle.plugin) { + exclude("io.github.detekt.sarif4k", "sarif4k") + } implementation(libs.sarif4k) implementation(libs.gradle.plugin.spotless) - implementation(libs.publish.gradle.plugin) + implementation(libs.dokka.gradle.plugin) + implementation(libs.gradle.nexus.publish.plugin) // extra dependencies implementation(libs.kotlin.stdlib) implementation(libs.kotlin.stdlib.common) diff --git a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/PublishingConfiguration.kt b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/PublishingConfiguration.kt index e032311b0b..321a8295de 100644 --- a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/PublishingConfiguration.kt +++ b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/PublishingConfiguration.kt @@ -10,89 +10,44 @@ package com.saveourtool.diktat.buildutils import io.github.gradlenexus.publishplugin.NexusPublishExtension +import io.github.gradlenexus.publishplugin.NexusPublishPlugin import org.gradle.api.Named import org.gradle.api.Project import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPom import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin +import org.gradle.api.publish.maven.tasks.PublishToMavenRepository import org.gradle.api.tasks.bundling.Jar import org.gradle.internal.logging.text.StyledTextOutput import org.gradle.internal.logging.text.StyledTextOutput.Style.Failure import org.gradle.internal.logging.text.StyledTextOutput.Style.Success import org.gradle.internal.logging.text.StyledTextOutputFactory +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.register import org.gradle.kotlin.dsl.support.serviceOf import org.gradle.kotlin.dsl.withType +import org.gradle.plugins.signing.Sign import org.gradle.plugins.signing.SigningExtension +import org.gradle.plugins.signing.SigningPlugin +import org.jetbrains.dokka.gradle.DokkaPlugin /** - * Enables signing of the artifacts if the `signingKey` project property is set. - * - * Should be explicitly called after each custom `publishing {}` section. + * Configures all aspects of the publishing process. */ -fun Project.configureSigning() { - if (hasProperty("signingKey")) { - /* - * GitHub Actions. - */ - configureSigningCommon { - useInMemoryPgpKeys(property("signingKey") as String?, findProperty("signingPassword") as String?) - } - } else if ( - hasProperties( - "signing.keyId", - "signing.password", - "signing.secretKeyRingFile", - ) - ) { - /*- - * Pure-Java signing mechanism via `org.bouncycastle.bcpg`. - * - * Requires an 8-digit (short form) PGP key id and a present `~/.gnupg/secring.gpg` - * (for gpg 2.1, run - * `gpg --keyring secring.gpg --export-secret-keys >~/.gnupg/secring.gpg` - * to generate one). - */ - configureSigningCommon() - } else if (hasProperty("signing.gnupg.keyName")) { - /*- - * Use an external `gpg` executable. - * - * On Windows, you may need to additionally specify the path to `gpg` via - * `signing.gnupg.executable`. - */ - configureSigningCommon { - useGpgCmd() - } +fun Project.configurePublishing() { + configurePublications() + apply() + if (this == rootProject) { + configureNexusPublishing() + configureGitHubPublishing() } -} -/** - * Updates pom.xml for publication - */ -@Suppress("TOO_LONG_FUNCTION") -fun Project.configurePublications() { - val dokkaJar: Jar = tasks.create("dokkaJar") { - group = "documentation" - archiveClassifier.set("javadoc") - from(tasks.findByName("dokkaHtml")) - } - configure { - repositories { - mavenLocal() - } - publications.withType().configureEach { - /* - * The content of this section will get executed only if - * a particular module has a `publishing {}` section. - */ - this.artifact(dokkaJar) - this.pom { - configurePom(project) - } - } + afterEvaluate { + configureSigning() } } @@ -101,14 +56,16 @@ fun Project.configurePublications() { * * @param project */ +@Suppress("TOO_LONG_FUNCTION") fun MavenPom.configurePom(project: Project) { name.set(project.name) description.set(project.description ?: project.name) - url.set("https://saveourtool.com") + url.set("https://github.com/saveourtool/diktat") licenses { license { name.set("MIT License") - url.set("http://www.opensource.org/licenses/mit-license.php") + url.set("https://opensource.org/license/MIT") + distribution.set("repo") } } developers { @@ -124,19 +81,56 @@ fun MavenPom.configurePom(project: Project) { email.set("peter.trifanov@gmail.com") url.set("https://github.com/petertrr") } + developer { + id.set("nulls") + name.set("Nariman Abdullin") + email.set("nulls.narik@gmail.com") + url.set("https://github.com/nulls") + } } scm { + url.set("https://github.com/saveourtool/diktat") connection.set("scm:git:git://github.com/saveourtool/diktat.git") - developerConnection.set("scm:git:ssh://github.com:saveourtool/diktat.git") - url.set("http://github.com/saveourtool/diktat/tree/master") + developerConnection.set("scm:git:git@github.com:saveourtool/diktat.git") } } -internal fun Project.configureNexusPublishing() { +/** + * Configures Maven Central as the publish destination. + */ +@Suppress("TOO_LONG_FUNCTION") +private fun Project.configureNexusPublishing() { + setPropertyFromEnv("OSSRH_USERNAME", "sonatypeUsername") + setPropertyFromEnv("OSSRH_PASSWORD", "sonatypePassword") + + if (!hasProperties("sonatypeUsername", "sonatypePassword")) { + styledOut(logCategory = "nexus") + .style(StyledTextOutput.Style.Info) + .text("Skipping Nexus publishing configuration as either ") + .style(StyledTextOutput.Style.Identifier) + .text("sonatypeUsername") + .style(StyledTextOutput.Style.Info) + .text(" or ") + .style(StyledTextOutput.Style.Identifier) + .text("sonatypePassword") + .style(StyledTextOutput.Style.Info) + .text(" are not set") + .println() + return + } + + apply() + configure { repositories { sonatype { + /* + * The default is https://oss.sonatype.org/service/local/. + */ nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) + /* + * The default is https://oss.sonatype.org/content/repositories/snapshots/. + */ snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) username.set(property("sonatypeUsername") as String) password.set(property("sonatypePassword") as String) @@ -145,6 +139,97 @@ internal fun Project.configureNexusPublishing() { } } +/** + * Configures GitHub Packages as the publish destination. + */ +private fun Project.configureGitHubPublishing() { + configure { + repositories { + maven { + name = "GitHub" + url = uri("https://maven.pkg.github.com/saveourtool/diktat") + credentials { + username = findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR") + password = findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN") + } + } + } + } +} + +/** + * Configures all publications. The publications must already exist. + */ +@Suppress("TOO_LONG_FUNCTION") +private fun Project.configurePublications() { + if (this == rootProject) { + return + } + apply() + @Suppress("GENERIC_VARIABLE_WRONG_DECLARATION") + val dokkaJarProvider = tasks.register("dokkaJar") { + group = "documentation" + archiveClassifier.set("javadoc") + from(tasks.named("dokkaHtml")) + } + configure { + repositories { + mavenLocal() + } + publications.withType().configureEach { + artifact(dokkaJarProvider) + pom { + configurePom(project) + } + } + } +} + +/** + * Enables signing of the artifacts if the `signingKey` project property is set. + * + * Should be explicitly called after each custom `publishing {}` section. + */ +private fun Project.configureSigning() { + setPropertyFromEnv("GPG_SEC", "signingKey") + setPropertyFromEnv("GPG_PASSWORD", "signingPassword") + + if (hasProperty("signingKey")) { + /* + * GitHub Actions. + */ + configureSigningCommon { + useInMemoryPgpKeys(property("signingKey") as String?, findProperty("signingPassword") as String?) + } + } else if ( + this.hasProperties( + "signing.keyId", + "signing.password", + "signing.secretKeyRingFile", + ) + ) { + /*- + * Pure-Java signing mechanism via `org.bouncycastle.bcpg`. + * + * Requires an 8-digit (short form) PGP key id and a present `~/.gnupg/secring.gpg` + * (for gpg 2.1, run + * `gpg --keyring secring.gpg --export-secret-keys >~/.gnupg/secring.gpg` + * to generate one). + */ + configureSigningCommon() + } else if (hasProperty("signing.gnupg.keyName")) { + /*- + * Use an external `gpg` executable. + * + * On Windows, you may need to additionally specify the path to `gpg` via + * `signing.gnupg.executable`. + */ + configureSigningCommon { + useGpgCmd() + } + } +} + /** * @param useKeys the block which configures the PGP keys. Use either * [SigningExtension.useInMemoryPgpKeys], [SigningExtension.useGpgCmd], or an @@ -153,6 +238,7 @@ internal fun Project.configureNexusPublishing() { * @see SigningExtension.useGpgCmd */ private fun Project.configureSigningCommon(useKeys: SigningExtension.() -> Unit = {}) { + apply() configure { useKeys() val publications = extensions.getByType().publications @@ -165,10 +251,21 @@ private fun Project.configureSigningCommon(useKeys: SigningExtension.() -> Unit styledOut(logCategory = "signing").style(style).println(message) sign(*publications.toTypedArray()) } + tasks.withType().configureEach { + // Workaround for the problem described at https://github.com/saveourtool/save-cli/pull/501#issuecomment-1439705340. + // We have a single Javadoc artifact shared by all platforms, hence all publications depend on signing of this artifact. + // This causes weird implicit dependencies, like `publishJsPublication...` depends on `signJvmPublication`. + dependsOn(tasks.withType()) + } } -private fun Project.styledOut(logCategory: String): StyledTextOutput = - serviceOf().create(logCategory) +/** + * Creates a styled text output. + * + * @param logCategory + * @return [StyledTextOutput] + */ +private fun Project.styledOut(logCategory: String): StyledTextOutput = serviceOf().create(logCategory) /** * Determines if this project has all the given properties. @@ -177,5 +274,10 @@ private fun Project.styledOut(logCategory: String): StyledTextOutput = * @return `true` if this project has all the given properties, `false` otherwise. * @see Project.hasProperty */ -private fun Project.hasProperties(vararg propertyNames: String): Boolean = - propertyNames.asSequence().all(this::hasProperty) +private fun Project.hasProperties(vararg propertyNames: String): Boolean = propertyNames.asSequence().all(this::hasProperty) + +private fun Project.setPropertyFromEnv(envName: String, propertyName: String) { + System.getenv(envName)?.let { + extra.set(propertyName, it) + } +} diff --git a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/code-quality-convention.gradle.kts b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/code-quality-convention.gradle.kts index cc4213df04..b64e22c86b 100644 --- a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/code-quality-convention.gradle.kts +++ b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/code-quality-convention.gradle.kts @@ -5,9 +5,6 @@ run { @Suppress("RUN_IN_SCRIPT", "AVOID_NULL_CHECKS") plugins { id("com.saveourtool.diktat.buildutils.detekt-convention-configuration") - // FixMe: remove after 2.0.0 - if (System.getenv("DIKTAT_SNAPSHOT") != null) { - id("com.saveourtool.diktat.buildutils.diktat-convention-configuration") - } + id("com.saveourtool.diktat.buildutils.diktat-convention-configuration") } } diff --git a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/detekt-convention-configuration.gradle.kts b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/detekt-convention-configuration.gradle.kts index 75fd92c9e2..b62eedc062 100644 --- a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/detekt-convention-configuration.gradle.kts +++ b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/detekt-convention-configuration.gradle.kts @@ -22,7 +22,7 @@ if (path == rootProject.path) { } tasks.register("mergeDetektReports", ReportMergeTask::class) { - output.set(buildDir.resolve("detekt-sarif-reports/detekt-merged.sarif")) + output.set(layout.buildDirectory.file("detekt-sarif-reports/detekt-merged.sarif").get().asFile) } } diff --git a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/diktat-convention-configuration.gradle.txt b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/diktat-convention-configuration.gradle.kts similarity index 100% rename from gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/diktat-convention-configuration.gradle.txt rename to gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/diktat-convention-configuration.gradle.kts diff --git a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-configuration.gradle.kts b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-configuration.gradle.kts index b4cca05387..73fffc4793 100644 --- a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-configuration.gradle.kts +++ b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-configuration.gradle.kts @@ -1,37 +1,9 @@ package com.saveourtool.diktat.buildutils -import io.github.gradlenexus.publishplugin.NexusPublishPlugin -import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.`maven-publish` plugins { `maven-publish` - signing } -run { - // If present, set properties from env variables. If any are absent, release will fail. - System.getenv("OSSRH_USERNAME")?.let { - extra.set("sonatypeUsername", it) - } - System.getenv("OSSRH_PASSWORD")?.let { - extra.set("sonatypePassword", it) - } - System.getenv("GPG_SEC")?.let { - extra.set("signingKey", it) - } - System.getenv("GPG_PASSWORD")?.let { - extra.set("signingPassword", it) - } - - if (project.path == rootProject.path) { - apply() - if (hasProperty("sonatypeUsername")) { - configureNexusPublishing() - } - } -} - -run { - configurePublications() -} +configurePublishing() diff --git a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-default-configuration.gradle.kts b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-default-configuration.gradle.kts new file mode 100644 index 0000000000..92952dc516 --- /dev/null +++ b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-default-configuration.gradle.kts @@ -0,0 +1,19 @@ +package com.saveourtool.diktat.buildutils + +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.get + +plugins { + `maven-publish` +} + +publishing { + publications { + create("maven") { + from(components["java"]) + } + } +} + +configurePublishing() diff --git a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-signing-default-configuration.gradle.kts b/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-signing-default-configuration.gradle.kts deleted file mode 100644 index b5d4c0f7b5..0000000000 --- a/gradle/plugins/src/main/kotlin/com/saveourtool/diktat/buildutils/publishing-signing-default-configuration.gradle.kts +++ /dev/null @@ -1,21 +0,0 @@ -package com.saveourtool.diktat.buildutils - -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.get - -plugins { - id("com.saveourtool.diktat.buildutils.publishing-configuration") -} - -run { - publishing { - publications { - create("maven") { - from(components["java"]) - } - } - } - - configureSigning() -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 8e061d34fa..150d50c91f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -9,6 +9,12 @@ dependencyResolutionManagement { url = this@run.toURI() } } + maven { + url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") + content { + includeGroup("com.saveourtool.diktat") + } + } mavenCentral() } } @@ -22,6 +28,12 @@ pluginManagement { url = this@run.toURI() } } + maven { + url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") + content { + includeGroup("com.saveourtool.diktat") + } + } mavenCentral() gradlePluginPortal() }