Skip to content

Commit

Permalink
Add GitHub workflow to publish a release (#228)
Browse files Browse the repository at this point in the history
Part of #94

The workflow uses [nexus-actions](https://github.com/nexus-actions) to
manage the staging repository. The publication was updated to use the
new URL for deployment when a staging repository ID is available.
  • Loading branch information
OptimumCode authored Aug 21, 2024
1 parent 1f96bfc commit 3487c55
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 17 deletions.
15 changes: 10 additions & 5 deletions .github/workflows/build.main.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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",
)
}
}
}
27 changes: 18 additions & 9 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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'
134 changes: 134 additions & 0 deletions .github/workflows/release.main.kts
Original file line number Diff line number Diff line change
@@ -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 },
)
)
}
}
99 changes: 99 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -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 }}'
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> =
providers.gradleProperty("snake-kmp.signing.keyId")
Expand All @@ -33,11 +34,13 @@ val signingSecretKeyRingFile: Provider<String> =

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
Expand Down

0 comments on commit 3487c55

Please sign in to comment.