Skip to content

Commit

Permalink
Switch publication on Maven Central to JReleaser
Browse files Browse the repository at this point in the history
  • Loading branch information
ascheman committed Aug 8, 2024
1 parent bddc767 commit 9e02e46
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 56 deletions.
58 changes: 46 additions & 12 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ plugins {

alias(libs.plugins.gradle.versions)
alias(libs.plugins.sonar)

alias(libs.plugins.jreleaser)
}

allprojects {
Expand Down Expand Up @@ -54,22 +56,54 @@ File baseBuildDir = file("${project.rootDir}/build")
File mavenBuildRepo = new File(baseBuildDir, "maven-repo")
// end::mavenBuildRepo[]

// tag::artifactsZip[]
String artifactsZip = 'publish-to-maven-central.zip'
// end::artifactsZip[]

task zipArtifacts(type: Zip) {
from mavenBuildRepo
exclude '**/maven-metadata.xml*'
archiveFileName.set(artifactsZip)
destinationDirectory.set(baseBuildDir)
task signAll() {
doLast {
logger.quiet("Signed all artifacts for upload with JReleaser")
}
}
zipArtifacts.dependsOn(
signAll.dependsOn(
':htmlSanityCheck-core:signMavenJavaPublication',
':htmlSanityCheck-gradle-plugin:signHtmlSanityCheckPluginMarkerMavenPublication',
':htmlSanityCheck-gradle-plugin:signPluginMavenPublication'
)

jreleaserDeploy.dependsOn(
'signAll',
':htmlSanityCheck-core:publishAllPublicationsToMyLocalRepositoryForFullIntegrationTestsRepository',
':htmlSanityCheck-gradle-plugin:publishAllPublicationsToMyLocalRepositoryForFullIntegrationTestsRepository'
)
zipArtifacts.doFirst {
project.ext.set('enableSigning', 'true')

jreleaser {
project {
license = 'Apache-2.0'
links {
homepage = urls.website
}
inceptionYear = '2014'
copyright = '2024'
}

release {
github {
repoOwner = 'aim42'
overwrite = true
}
}

deploy {
active = 'NEVER'

maven {
mavenCentral {
app {
active = 'ALWAYS'
sign = false
url = 'https://central.sonatype.com/api/v1/publisher'
stagingRepository(mavenBuildRepo.toString())
}
}
}
}
}

configure(subprojects) {
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ spock = 'org.spockframework:spock-bom:2.3-groovy-3.0'
[plugins]
gradle-versions = { id= 'com.github.ben-manes.versions', version = '0.51.0' }
sonar = { id = 'org.sonarqube', version = '5.0.0.4638' }
jreleaser = { id = 'org.jreleaser', version = '1.13.1'}
gitProperties = { id = 'com.gorylenko.gradle-git-properties', version = '2.4.1' }

# Copyright Gerd Aschemann and aim42 contributors.
Expand Down
92 changes: 48 additions & 44 deletions src/docs/development/publishing.adoc
Original file line number Diff line number Diff line change
@@ -1,77 +1,81 @@
:filename: development/publishing.adoc
=== Publishing kbd:htmlSC Releases

==== Background
kbd:htmlSC (Core and Gradle plugin) can be published to https://central.sonatype.com/search?q=org.aim42.htmlSanityCheck[Maven Central] (MC) for retrieval by its consumers.

Our Gradle build stores all artifacts and their meta-data (POM + module files,
as well as their respective hashes and signatures) in a local Maven repository.
They are subject to integration tests.
Finally, they can be uploaded to Maven Central (as ZIP file).
Traditional usage as Gradle plugin from https://plugins.gradle.org[Gradle Plugin repository] is still possible,
as they are redirecting plugin downloads automatically to Maven Central.

[[item:local-repository]]
* The build stores these files to the root build directory.
+
[source,groovy]
.Local Maven repository for integration testing and publication
----
include::../../../build.gradle[tag=mavenBuildRepo]
----
WARNING: Only note that newer versions (>= 2.0.0) currently do not show up in the https://plugins.gradle.org/search?term=org.aim42.htmlSanityCheck[web interface].

[[item:zip-file]]
* And it stores the ZIP file there as well
+
[source,groovy]
.Generated ZIP file for publication
----
include::../../../build.gradle[tag=artifactsZip]
----
==== Prerequisites

===== Maven Central (Sonatype) account

Make yourself familiar with https://central.sonatype.org/publish-ea/publish-ea-guide/[the publishing process].

[IMPORTANT]
.Setup GnuPG signing
[CAUTION]
.Credentials needed
====
To successfully sign the artifacts
you need to set up GnuPG in your local `+${HOME}/.gradle/gradle.properties+`,
You need respective credentials to upload files to Maven Central for the `org.aim42.htmlSanityCheck` namespace.
Talk to Gernot Starke to get these permissions.
====

You will need to https://central.sonatype.org/register/central-portal/#create-an-account[sign up for Maven Central]
(or, to be more precise, to its provider, Sonatype).
Additionally, you need to create https://central.sonatype.org/publish/generate-portal-token/[a portal token].

[[sec:artifact-signing]]
===== Artifact signing

To successfully upload artifacts and other files (POM etc.), a valid PGP signature is required.
Therefore, you need to set up GnuPG in your local `+${HOME}/.gradle/gradle.properties+`,
according to the https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials[Gradle Signatory documentation].

Add the following entries:

[source,properties]
----
signing.keyId=24875D73
signing.password=secret # <1>
signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg <2>
signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg <1>
signing.password=<SECRET> # <2>
----
<1> Instead of provisioning the clear text password, you could also provide it on the command line when calling Gradle:
<1> Note that you need to specify the literal path to your home directory; it is not possible to refer to system properties like `+${user.home}+` here.
<2> Instead of putting the clear text password into the file, you should provide it on the command line when calling Gradle
+
[source,shell]
----
./gradlew -Psigning.password=... <task>
----
<2> Note that you need to specify the literal path to your home directory; it is not possible to refer to system properties like `+${user.home}+` here.
====

==== Publishing actions

Adjust version number::
Set the version number in xref:../../../gradle.properties[] to the next value.

Build / publish local / sign::
Generate artifacts and publish them to the local Maven repository for integration tests
Build / Test::
Clean, check (test), and perform integration tests:
+
[source,bash,subs="callouts+"]
----
./gradlew clean integrationTest zipArtifacts # <1> <2>
./gradlew clean check integrationTest
----
<1> The `integrationTest` task will implicitly call the task `publishAllPublicationsToMyLocalRepositoryForFullIntegrationTestsRepository` which pushes all required files for publication to the <<item:local-repository,repository>>.
<2> The `zipArtifacts` task will generate the <<item:zip-file,ZIP file>> for publication.

Upload ZIP to Maven Central::
Finally, upload the resulting ZIP file (manually) to Maven Central,
i.e., https://central.sonatype.com/publishing[Sonatype Central].
Sign / Upload to Maven Central::
Sign artifacts and load them up to Maven Central via https://jreleaser.org[JReleaser].
+
[CAUTION]
.Credentials needed
====
You need respective credentials to upload files to Maven Central for the `org.aim42.htmlSanityCheck` namespace.
Talk to Gernot Starke to get these permissions.
====
[source,bash,subs="callouts+"]
----
./gradlew jreleaserDeploy -PenableSigning=true -Psigning.password=... # <1> <2>
----
<1> Checkout <<sec:artifact-signing>> for more information.
<2> The `enableSigning` flag is necessary to enforce signing (which is not necessary for local installations,
integration testing, etc.)

The `jreleaserDeploy` task will implicitly call the task `signAll` which signs
and pushes all required files for publication to a local repository.
JReleaser picks them up from there and loads them up to the Maven Central staging area as a new version.

Publish on Maven Central::
Finally, publish the staged version on Maven Central,
i.e., https://central.sonatype.com/publishing[Sonatype Central].

0 comments on commit 9e02e46

Please sign in to comment.