diff --git a/.github/workflows/build.main.kts b/.github/workflows/build.main.kts index b5379f5d1..5e0a696c3 100755 --- a/.github/workflows/build.main.kts +++ b/.github/workflows/build.main.kts @@ -6,12 +6,13 @@ @file:DependsOn("actions:checkout:v4") @file:DependsOn("actions:cache:v4") @file:DependsOn("actions:setup-java:v4") -@file:DependsOn("gradle:gradle-build-action:v3") +@file:DependsOn("gradle:actions__setup-gradle:v4") + import io.github.typesafegithub.workflows.actions.actions.Cache import io.github.typesafegithub.workflows.actions.actions.Checkout import io.github.typesafegithub.workflows.actions.actions.SetupJava -import io.github.typesafegithub.workflows.actions.gradle.GradleBuildAction +import io.github.typesafegithub.workflows.actions.gradle.ActionsSetupGradle import io.github.typesafegithub.workflows.domain.Concurrency import io.github.typesafegithub.workflows.domain.RunnerType.* import io.github.typesafegithub.workflows.domain.triggers.PullRequest @@ -59,11 +60,15 @@ workflow( ), ) uses( - name = "Build", - action = GradleBuildAction( - arguments = "build", + name = "Set up Gradle", + action = ActionsSetupGradle( + gradleVersion = "wrapper", ), ) + run( + name = "Build", + command = "./gradlew build --stacktrace", + ) } } } diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 016689227..f1e8871b6 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -46,10 +46,13 @@ jobs: path: '~/.konan/**/*' key: 'kotlin-konan-${{ runner.os }}' - id: 'step-3' - name: 'Build' - uses: 'gradle/gradle-build-action@v3' + name: 'Set up Gradle' + uses: 'gradle/actions/setup-gradle@v4' with: - arguments: 'build' + gradle-version: 'wrapper' + - id: 'step-4' + name: 'Build' + run: './gradlew build --stacktrace' build-on-MacOSLatest: runs-on: 'macos-latest' needs: @@ -71,10 +74,13 @@ jobs: path: '~/.konan/**/*' key: 'kotlin-konan-${{ runner.os }}' - id: 'step-3' - name: 'Build' - uses: 'gradle/gradle-build-action@v3' + name: 'Set up Gradle' + uses: 'gradle/actions/setup-gradle@v4' with: - arguments: 'build' + gradle-version: 'wrapper' + - id: 'step-4' + name: 'Build' + run: './gradlew build --stacktrace' build-on-WindowsLatest: runs-on: 'windows-latest' needs: @@ -96,7 +102,10 @@ jobs: path: '~/.konan/**/*' key: 'kotlin-konan-${{ runner.os }}' - id: 'step-3' - name: 'Build' - uses: 'gradle/gradle-build-action@v3' + name: 'Set up Gradle' + uses: 'gradle/actions/setup-gradle@v4' with: - arguments: 'build' + gradle-version: 'wrapper' + - id: 'step-4' + name: 'Build' + run: './gradlew build --stacktrace' diff --git a/.github/workflows/release.main.kts b/.github/workflows/release.main.kts new file mode 100755 index 000000000..cd996cad1 --- /dev/null +++ b/.github/workflows/release.main.kts @@ -0,0 +1,134 @@ +#!/usr/bin/env kotlin +@file:Repository("https://repo1.maven.org/maven2/") +@file:DependsOn("io.github.typesafegithub:github-workflows-kt:2.3.0") + +@file:Repository("https://bindings.krzeminski.it/") +@file:DependsOn("actions:checkout:v4") +@file:DependsOn("actions:cache:v4") +@file:DependsOn("actions:setup-java:v4") +@file:DependsOn("gradle:actions__setup-gradle:v4") +@file:DependsOn("nexus-actions:create-nexus-staging-repo:v1") +@file:DependsOn("nexus-actions:release-nexus-staging-repo:v1") +@file:DependsOn("nexus-actions:drop-nexus-staging-repo:v1") + +import io.github.typesafegithub.workflows.actions.actions.Cache +import io.github.typesafegithub.workflows.actions.actions.Checkout +import io.github.typesafegithub.workflows.actions.actions.SetupJava +import io.github.typesafegithub.workflows.actions.gradle.ActionsSetupGradle +import io.github.typesafegithub.workflows.actions.nexusactions.CreateNexusStagingRepo +import io.github.typesafegithub.workflows.actions.nexusactions.DropNexusStagingRepo +import io.github.typesafegithub.workflows.actions.nexusactions.ReleaseNexusStagingRepo +import io.github.typesafegithub.workflows.domain.AbstractResult +import io.github.typesafegithub.workflows.domain.JobOutputs +import io.github.typesafegithub.workflows.domain.RunnerType +import io.github.typesafegithub.workflows.domain.triggers.WorkflowDispatch +import io.github.typesafegithub.workflows.dsl.expressions.Contexts +import io.github.typesafegithub.workflows.dsl.expressions.expr +import io.github.typesafegithub.workflows.dsl.workflow + +val SONATYPE_USERNAME by Contexts.secrets +val SONATYPE_PASSWORD by Contexts.secrets +val SONATYPE_STAGING_PROFILE_ID by Contexts.secrets +val SIGNING_KEY_ID by Contexts.secrets +val SIGNING_KEY by Contexts.secrets +val SIGNING_PASSWORD by Contexts.secrets + +workflow( + name = "Publish release to Maven Central", + on = listOf( + WorkflowDispatch() + ), + sourceFile = __FILE__, +) { + val stagingRepoJob = + job( + id = "create-staging-repo", + name = "Create staging repository", + runsOn = RunnerType.UbuntuLatest, + outputs = object : JobOutputs() { + var repositoryId: String by output() + } + ) { + val createRepo = uses( + action = CreateNexusStagingRepo( + username = expr { SONATYPE_USERNAME }, + password = expr { SONATYPE_PASSWORD }, + stagingProfileId = expr { SONATYPE_STAGING_PROFILE_ID }, + ) + ) + jobOutputs.repositoryId = createRepo.outputs.repositoryId + } + val publishJob = + job( + id = "publish-artifacts", + runsOn = RunnerType.MacOSLatest, + needs = listOf(stagingRepoJob), + ) { + uses(action = Checkout()) + uses( + name = "Set up JDK", + action = SetupJava( + javaVersion = "11", + distribution = SetupJava.Distribution.Zulu, + cache = SetupJava.BuildPlatform.Gradle, + ), + ) + uses( + name = "Cache Kotlin Konan", + action = Cache( + path = listOf( + "~/.konan/**/*", + ), + key = "kotlin-konan-${expr { runner.os }}", + ), + ) + uses( + name = "Set up Gradle", + action = ActionsSetupGradle( + gradleVersion = "wrapper", + ), + ) + run( + name = "Publish", + command = "./gradlew publishAllPublicationsToSonatypeReleaseRepository --stacktrace", + env = + mapOf( + "ORG_GRADLE_PROJECT_snake-kmp.ossrhUsername" to expr { SONATYPE_USERNAME }, + "ORG_GRADLE_PROJECT_snake-kmp.ossrhPassword" to expr { SONATYPE_PASSWORD }, + "ORG_GRADLE_PROJECT_snake-kmp.ossrhStagingRepositoryId" to expr { stagingRepoJob.outputs.repositoryId }, + "ORG_GRADLE_PROJECT_snake-kmp.signing.keyId" to expr { SIGNING_KEY_ID }, + "ORG_GRADLE_PROJECT_snake-kmp.signing.key" to expr { SIGNING_KEY }, + "ORG_GRADLE_PROJECT_snake-kmp.signing.password" to expr { SIGNING_PASSWORD }, + ) + ) + } + + job( + id = "close-staging-repo", + runsOn = RunnerType.UbuntuLatest, + condition = expr { publishJob.result.eq(AbstractResult.Status.Success) }, + needs = listOf(stagingRepoJob, publishJob), + ) { + uses( + action = ReleaseNexusStagingRepo( + username = expr { SONATYPE_USERNAME }, + password = expr { SONATYPE_PASSWORD }, + stagingRepositoryId = expr { stagingRepoJob.outputs.repositoryId }, + ) + ) + } + job( + id = "drop-staging-repo", + runsOn = RunnerType.UbuntuLatest, + condition = expr { publishJob.result.neq(AbstractResult.Status.Success) }, + needs = listOf(stagingRepoJob, publishJob), + ) { + uses( + action = DropNexusStagingRepo( + username = expr { SONATYPE_USERNAME }, + password = expr { SONATYPE_PASSWORD }, + stagingRepositoryId = expr { stagingRepoJob.outputs.repositoryId }, + ) + ) + } +} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 000000000..c56272b76 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,99 @@ +# This file was generated using Kotlin DSL (.github/workflows/release.main.kts). +# If you want to modify the workflow, please change the Kotlin file and regenerate this YAML file. +# Generated with https://github.com/typesafegithub/github-workflows-kt + +name: 'Publish release to Maven Central' +on: + workflow_dispatch: {} +jobs: + check_yaml_consistency: + name: 'Check YAML consistency' + runs-on: 'ubuntu-latest' + steps: + - id: 'step-0' + name: 'Check out' + uses: 'actions/checkout@v4' + - id: 'step-1' + name: 'Execute script' + run: 'rm ''.github/workflows/release.yaml'' && ''.github/workflows/release.main.kts''' + - id: 'step-2' + name: 'Consistency check' + run: 'git diff --exit-code ''.github/workflows/release.yaml''' + create-staging-repo: + name: 'Create staging repository' + runs-on: 'ubuntu-latest' + needs: + - 'check_yaml_consistency' + outputs: + repositoryId: '${{ steps.step-0.outputs.repository_id }}' + steps: + - id: 'step-0' + uses: 'nexus-actions/create-nexus-staging-repo@v1' + with: + username: '${{ secrets.SONATYPE_USERNAME }}' + password: '${{ secrets.SONATYPE_PASSWORD }}' + staging_profile_id: '${{ secrets.SONATYPE_STAGING_PROFILE_ID }}' + publish-artifacts: + runs-on: 'macos-latest' + needs: + - 'create-staging-repo' + - 'check_yaml_consistency' + steps: + - id: 'step-0' + uses: 'actions/checkout@v4' + - id: 'step-1' + name: 'Set up JDK' + uses: 'actions/setup-java@v4' + with: + java-version: '11' + distribution: 'zulu' + cache: 'gradle' + - id: 'step-2' + name: 'Cache Kotlin Konan' + uses: 'actions/cache@v4' + with: + path: '~/.konan/**/*' + key: 'kotlin-konan-${{ runner.os }}' + - id: 'step-3' + name: 'Set up Gradle' + uses: 'gradle/actions/setup-gradle@v4' + with: + gradle-version: 'wrapper' + - id: 'step-4' + name: 'Publish' + env: + ORG_GRADLE_PROJECT_snake-kmp.ossrhUsername: '${{ secrets.SONATYPE_USERNAME }}' + ORG_GRADLE_PROJECT_snake-kmp.ossrhPassword: '${{ secrets.SONATYPE_PASSWORD }}' + ORG_GRADLE_PROJECT_snake-kmp.ossrhStagingRepositoryId: '${{ needs.create-staging-repo.outputs.repositoryId }}' + ORG_GRADLE_PROJECT_snake-kmp.signing.keyId: '${{ secrets.SIGNING_KEY_ID }}' + ORG_GRADLE_PROJECT_snake-kmp.signing.key: '${{ secrets.SIGNING_KEY }}' + ORG_GRADLE_PROJECT_snake-kmp.signing.password: '${{ secrets.SIGNING_PASSWORD }}' + run: './gradlew publishAllPublicationsToSonatypeReleaseRepository --stacktrace' + close-staging-repo: + runs-on: 'ubuntu-latest' + needs: + - 'create-staging-repo' + - 'publish-artifacts' + - 'check_yaml_consistency' + if: '${{ needs.publish-artifacts.result == ''success'' }}' + steps: + - id: 'step-0' + uses: 'nexus-actions/release-nexus-staging-repo@v1' + with: + username: '${{ secrets.SONATYPE_USERNAME }}' + password: '${{ secrets.SONATYPE_PASSWORD }}' + staging_repository_id: '${{ needs.create-staging-repo.outputs.repositoryId }}' + drop-staging-repo: + runs-on: 'ubuntu-latest' + needs: + - 'create-staging-repo' + - 'publish-artifacts' + - 'check_yaml_consistency' + if: '${{ needs.publish-artifacts.result != ''success'' }}' + steps: + - id: 'step-0' + uses: 'nexus-actions/drop-nexus-staging-repo@v1' + with: + username: '${{ secrets.SONATYPE_USERNAME }}' + password: '${{ secrets.SONATYPE_PASSWORD }}' + staging_repository_id: '${{ needs.create-staging-repo.outputs.repositoryId }}' diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts index af7de56fb..c99292d2c 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts @@ -21,6 +21,7 @@ plugins { // can be set in gradle.properties or environment variables, e.g. ORG_GRADLE_PROJECT_snake-kmp.ossrhUsername val ossrhUsername = providers.gradleProperty("snake-kmp.ossrhUsername") val ossrhPassword = providers.gradleProperty("snake-kmp.ossrhPassword") +val ossrhStagingRepositoryID = providers.gradleProperty("snake-kmp.ossrhStagingRepositoryId") val signingKeyId: Provider = providers.gradleProperty("snake-kmp.signing.keyId") @@ -33,11 +34,13 @@ val signingSecretKeyRingFile: Provider = val isReleaseVersion = provider { !version.toString().endsWith("-SNAPSHOT") } -val sonatypeReleaseUrl = isReleaseVersion.map { isRelease -> +val sonatypeReleaseUrl = isReleaseVersion.flatMap { isRelease -> if (isRelease) { - "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + ossrhStagingRepositoryID.map { repositoryId -> + "https://oss.sonatype.org/service/local/staging/deployByRepositoryId/${repositoryId}/" + }.orElse("https://oss.sonatype.org/service/local/staging/deploy/maven2/") } else { - "https://oss.sonatype.org/content/repositories/snapshots/" + provider { "https://oss.sonatype.org/content/repositories/snapshots/" } } } //endregion