Skip to content

Commit ec026fc

Browse files
marko-bekhtasebersole
authored andcommitted
HHH-19341 Add JReleaser config for publishing to Maven Central (OSSRH)
and add a placeholder config for the future switch to Central
1 parent 138e2b5 commit ec026fc

File tree

11 files changed

+140
-125
lines changed

11 files changed

+140
-125
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ ObjectStore
5050
*.swo
5151

5252
# SDKman, used by some module maintainers
53-
.sdkmanrc
53+
.sdkmanrc

MAINTAINERS.md

+12
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ and the documentation to [docs.jboss.org](https://docs.jboss.org/hibernate/orm/)
106106

107107
After the job succeeds:
108108

109+
* Release the artifacts on the [OSSRH repository manager](https://oss.sonatype.org/#stagingRepositories).
110+
* Log into Nexus. The credentials can be found on Bitwarden; ask a teammate if you don't have access.
111+
* Click "staging repositories" to the left.
112+
* Examine your staging repository: check that all expected artifacts are there.
113+
* If necessary (that's very rare), test the release in the staging repository.
114+
You can drop the staging repo if there is a problem,
115+
but you'll need to revert the commits pushed during the release.
116+
* If everything is ok, select the staging repository and click the "Release" button.
117+
* For branches with automated releases (e.g. 6.6) the "release repository" will happen automatically.
118+
to enable/disable the automatic release of the staging repository update the [jreleaser.yml](jreleaser.yml) file,
119+
in particular change the `deploy.maven.nexus2.maven-central.releaseRepository` to `true`/`false`.
120+
109121
* Update [hibernate.org](https://github.com/hibernate/hibernate.org) if necessary:
110122
* If it is a new major or minor release, add a `_data/projects/orm/releases/series.yml` file
111123
and a `orm/releases/<version>/index.adoc` file.

build.gradle

-8
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,6 @@ tasks.register( 'releasePerform' ) {
5555
// See `:release:releasePerform` which does a lot of heavy lifting here
5656
}
5757

58-
59-
nexusPublishing {
60-
repositories {
61-
sonatype()
62-
}
63-
}
64-
65-
6658
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6759
// CI Build Task
6860

ci/release/Jenkinsfile

+13-5
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,11 @@ pipeline {
190190
// tags the version
191191
// changes the version to the provided development version
192192
withEnv([
193-
"BRANCH=${env.GIT_BRANCH}",
194193
"DISABLE_REMOTE_GRADLE_CACHE=true",
195194
// Increase the amount of memory for this part since asciidoctor doc rendering consumes a lot of metaspace
196195
"GRADLE_OPTS=-Dorg.gradle.jvmargs='-Dlog4j2.disableJmx -Xmx4g -XX:MaxMetaspaceSize=768m -XX:+HeapDumpOnOutOfMemoryError -Duser.language=en -Duser.country=US -Duser.timezone=UTC -Dfile.encoding=UTF-8'"
197196
]) {
198-
sh ".release/scripts/prepare-release.sh ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION}"
197+
sh ".release/scripts/prepare-release.sh -b ${env.GIT_BRANCH} -d ${env.DEVELOPMENT_VERSION} ${env.PROJECT} ${env.RELEASE_VERSION}"
199198
}
200199
}
201200
}
@@ -213,19 +212,28 @@ pipeline {
213212
]) {
214213
withCredentials([
215214
// https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh
216-
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'ORG_GRADLE_PROJECT_sonatypePassword', usernameVariable: 'ORG_GRADLE_PROJECT_sonatypeUsername'),
215+
// TODO: HHH-19309:
216+
// Once we switch to maven-central publishing (from nexus2) we need to add a new credentials
217+
// to use the following env variable names to set the user/password:
218+
// - JRELEASER_MAVENCENTRAL_USERNAME
219+
// - JRELEASER_MAVENCENTRAL_TOKEN
220+
// Also use the new `credentialsId` for Maven Central, e.g.:
221+
// usernamePassword(credentialsId: '???????', passwordVariable: 'JRELEASER_MAVENCENTRAL_TOKEN', usernameVariable: 'JRELEASER_MAVENCENTRAL_USERNAME'),
222+
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'JRELEASER_NEXUS2_PASSWORD', usernameVariable: 'JRELEASER_NEXUS2_USERNAME'),
217223
// https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#account_setup
218224
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'GRADLE_PUBLISH_SECRET', usernameVariable: 'GRADLE_PUBLISH_KEY'),
225+
gitUsernamePassword(credentialsId: 'username-and-token.Hibernate-CI.github.com', gitToolName: 'Default'),
219226
file(credentialsId: 'release.gpg.private-key', variable: 'SIGNING_GPG_PRIVATE_KEY_PATH'),
220-
string(credentialsId: 'release.gpg.passphrase', variable: 'SIGNING_GPG_PASSPHRASE'),
221-
gitUsernamePassword(credentialsId: 'username-and-token.Hibernate-CI.github.com', gitToolName: 'Default')
227+
string(credentialsId: 'release.gpg.passphrase', variable: 'JRELEASER_GPG_PASSPHRASE'),
228+
string(credentialsId: 'Hibernate-CI.github.com', variable: 'JRELEASER_GITHUB_TOKEN')
222229
]) {
223230
sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) {
224231
// performs documentation upload and Sonatype release
225232
// push to github
226233
withEnv([
227234
"DISABLE_REMOTE_GRADLE_CACHE=true"
228235
]) {
236+
env.RELEASE_GPG_HOMEDIR = env.WORKSPACE_TMP + '/.gpg'
229237
sh ".release/scripts/publish.sh ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION} ${env.GIT_BRANCH}"
230238
}
231239
}

ci/snapshot-publish.Jenkinsfile

+38-16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ if (currentBuild.getBuildCauses().toString().contains('BranchIndexingCause')) {
1010
return
1111
}
1212

13+
def checkoutReleaseScripts() {
14+
dir('.release/scripts') {
15+
checkout scmGit(branches: [[name: '*/main']], extensions: [],
16+
userRemoteConfigs: [[credentialsId: 'ed25519.Hibernate-CI.github.com',
17+
url: 'https://github.com/hibernate/hibernate-release-scripts.git']])
18+
}
19+
}
20+
1321
pipeline {
1422
agent {
1523
label 'Release'
@@ -30,21 +38,35 @@ pipeline {
3038
}
3139
stage('Publish') {
3240
steps {
33-
withCredentials([
34-
// https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh
35-
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'ORG_GRADLE_PROJECT_sonatypePassword', usernameVariable: 'ORG_GRADLE_PROJECT_sonatypeUsername'),
36-
// https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#account_setup
37-
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'GRADLE_PUBLISH_SECRET', usernameVariable: 'GRADLE_PUBLISH_KEY'),
38-
file(credentialsId: 'release.gpg.private-key', variable: 'SIGNING_GPG_PRIVATE_KEY_PATH'),
39-
string(credentialsId: 'release.gpg.passphrase', variable: 'SIGNING_GPG_PASSPHRASE'),
40-
gitUsernamePassword(credentialsId: 'username-and-token.Hibernate-CI.github.com', gitToolName: 'Default')
41-
]) {
42-
withEnv([
43-
"DISABLE_REMOTE_GRADLE_CACHE=true"
44-
]) {
45-
sh './gradlew clean publish -x test --no-scan --no-daemon --no-build-cache --stacktrace -PmavenMirror=nexus-load-balancer-c4cf05fd92f43ef8.elb.us-east-1.amazonaws.com'
46-
}
47-
}
41+
script {
42+
withCredentials([
43+
// https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh
44+
// TODO: HHH-19309:
45+
// Once we switch to maven-central publishing (from nexus2) we need to add a new credentials
46+
// to use the following env variable names to set the user/password:
47+
// - JRELEASER_MAVENCENTRAL_USERNAME
48+
// - JRELEASER_MAVENCENTRAL_TOKEN
49+
// Also use the new `credentialsId` for Maven Central, e.g.:
50+
// usernamePassword(credentialsId: '???????', passwordVariable: 'JRELEASER_MAVENCENTRAL_TOKEN', usernameVariable: 'JRELEASER_MAVENCENTRAL_USERNAME'),
51+
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'JRELEASER_NEXUS2_PASSWORD', usernameVariable: 'JRELEASER_NEXUS2_USERNAME'),
52+
string(credentialsId: 'Hibernate-CI.github.com', variable: 'JRELEASER_GITHUB_TOKEN'),
53+
// https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#account_setup
54+
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'GRADLE_PUBLISH_SECRET', usernameVariable: 'GRADLE_PUBLISH_KEY'),
55+
gitUsernamePassword(credentialsId: 'username-and-token.Hibernate-CI.github.com', gitToolName: 'Default')
56+
]) {
57+
withEnv([
58+
"DISABLE_REMOTE_GRADLE_CACHE=true"
59+
]) {
60+
checkoutReleaseScripts()
61+
def version = sh(
62+
script: ".release/scripts/determine-current-version.sh orm",
63+
returnStdout: true
64+
).trim()
65+
echo "Current version: '${version}'"
66+
sh "bash -xe .release/scripts/snapshot-deploy.sh orm ${version}"
67+
}
68+
}
69+
}
4870
}
4971
}
5072
}
@@ -55,4 +77,4 @@ pipeline {
5577
}
5678
}
5779
}
58-
}
80+
}

hibernate-platform/hibernate-platform.gradle

-8
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,3 @@ var publishingExtension = project.getExtensions().getByType(PublishingExtension)
6565
publishingExtension.publications.named("publishedArtifacts", MavenPublication) {
6666
from components.javaPlatform
6767
}
68-
69-
tasks.register("releasePerform") {
70-
group "release"
71-
description "See :release:releasePerform for details. Here we hook in publishing to Sonatype"
72-
73-
dependsOn tasks.publishToSonatype
74-
}
75-

jreleaser.yml

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
project:
2+
languages:
3+
java:
4+
groupId: org.hibernate.orm
5+
6+
release:
7+
github:
8+
skipTag: true
9+
skipRelease: true
10+
tagName: '{{projectVersion}}'
11+
12+
# File signing is always active
13+
signing:
14+
mode: COMMAND
15+
active: RELEASE
16+
armored: true
17+
18+
deploy:
19+
maven:
20+
# TODO: HHH-19309: Remove the entire nexus2 section:
21+
nexus2:
22+
maven-central:
23+
active: RELEASE
24+
url: https://oss.sonatype.org/service/local
25+
snapshotUrl: https://oss.sonatype.org/content/repositories/snapshots/
26+
closeRepository: true
27+
releaseRepository: false
28+
stagingRepositories:
29+
- target/staging-deploy/maven
30+
maven-central-snapshot:
31+
active: SNAPSHOT
32+
url: https://oss.sonatype.org/service/local
33+
snapshotUrl: https://oss.sonatype.org/content/repositories/snapshots/
34+
closeRepository: true
35+
releaseRepository: true
36+
javadocJar: false
37+
sign: false
38+
stagingRepositories:
39+
- target/staging-deploy/maven
40+
mavenCentral:
41+
maven-central:
42+
# TODO: HHH-19309: Change to RELEASE once switching to Maven-Central:
43+
# Note, this is an untested configuration, hence might need further adjustments
44+
active: NEVER
45+
url: https://central.sonatype.com/api/v1/publisher
46+
snapshotSupported: false
47+
applyMavenCentralRules: true
48+
stagingRepositories:
49+
- target/staging-deploy/maven
50+
# Deployment identifier used for publication.
51+
# deploymentId: dd9991b0-18a7-41e7-b1fe-37b8ea936f85
52+
maven-central-snapshot:
53+
# TODO: HHH-19309: Change to SNAPSHOT once switching to Maven-Central:
54+
active: NEVER
55+
url: https://central.sonatype.com/api/v1/publisher
56+
snapshotSupported: true
57+
applyMavenCentralRules: true
58+
javadocJar: false
59+
sign: false
60+
stagingRepositories:
61+
- target/staging-deploy/maven
62+
# Deployment identifier used for publication.
63+
# deploymentId: dd9991b0-18a7-41e7-b1fe-37b8ea936f85

local-build-plugins/src/main/groovy/local.publishing-java-module.gradle

-6
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,3 @@ tasks.register("preVerifyRelease") {
5353
dependsOn releasePrepareTask
5454
}
5555

56-
tasks.register( 'releasePerform' ) {
57-
group "release-perform"
58-
description "See :release:releasePerform for details. Here we hook in publishing to Sonatype"
59-
60-
dependsOn tasks.publishToSonatype
61-
}

local-build-plugins/src/main/groovy/local.publishing.gradle

+7-72
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
plugins {
77
id "maven-publish"
8-
id "signing"
98
}
109

1110
// Disable Gradle module metadata publishing until we know what we want.
@@ -63,6 +62,12 @@ publishingExtension.publications.configureEach {
6362
}
6463
}
6564

65+
publishingExtension.repositories {
66+
maven {
67+
url = rootProject.layout.buildDirectory.dir("staging-deploy${File.separator}maven")
68+
}
69+
}
70+
6671
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6772
// register the "main" publication named `publishedArtifacts`
6873
publishingExtension.publications.register("publishedArtifacts", MavenPublication) {
@@ -72,76 +77,6 @@ publishingExtension.publications.register("publishedArtifacts", MavenPublication
7277
}
7378
}
7479

75-
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76-
// Create a special local repository used for local testing of PublishToMavenRepository
77-
78-
if ( project.hasProperty("local_pub_repo") ) {
79-
// to use -
80-
// 1. run `gradlew -Plocal_pub_repo publishAllPublicationsToLocalRepoRepository`
81-
// 2. check ${rootProject}/target/maven-repo
82-
publishingExtension.repositories {
83-
maven {
84-
name = "localRepo"
85-
url = rootProject.layout.buildDirectory.dir("maven-repo").get().asFile.toURI()
86-
}
87-
}
88-
}
89-
90-
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91-
// Signing
92-
93-
def signingKey = resolveSigningKey()
94-
def signingPassphrase = resolveSigningPassphrase()
95-
96-
var signingExtension = project.getExtensions().getByType(SigningExtension) as SigningExtension
97-
signingExtension.sign publishingExtension.publications.publishedArtifacts
98-
signingExtension.useInMemoryPgpKeys(signingKey, signingPassphrase)
99-
100-
gradle.taskGraph.whenReady { TaskExecutionGraph graph ->
101-
// are we publishing to OSSRH?
102-
boolean wasPublishingRequested = false
103-
104-
graph.allTasks.each {task ->
105-
if ( task instanceof PublishToMavenRepository ) {
106-
if ( "sonatype" == task.repository.name ) {
107-
wasPublishingRequested = true
108-
}
109-
}
110-
}
111-
112-
if ( wasPublishingRequested ) {
113-
def ossrhUser = System.getenv().get( "ORG_GRADLE_PROJECT_sonatypeUsername" )
114-
def ossrhPass = System.getenv().get( "ORG_GRADLE_PROJECT_sonatypePassword" )
115-
if ( ossrhUser == null || ossrhPass == null ) {
116-
throw new RuntimeException( "Cannot perform publishing to OSSRH without credentials." )
117-
}
118-
logger.lifecycle "Publishing {} : {} : {}", project.group, project.name, project.version
119-
signingExtension.required = true
120-
}
121-
else if ( signingKey == null || signingPassphrase == null ) {
122-
tasks.withType( Sign ).each { t-> t.enabled = false }
123-
}
124-
}
125-
126-
static String resolveSigningKey() {
127-
var key = System.getenv().get( "SIGNING_GPG_PRIVATE_KEY" )
128-
if ( key != null ) {
129-
return key
130-
}
131-
132-
var keyFile = System.getenv().get( "SIGNING_GPG_PRIVATE_KEY_PATH" )
133-
if ( keyFile != null ) {
134-
return new File( keyFile ).text
135-
}
136-
137-
return null
138-
}
139-
140-
static String resolveSigningPassphrase() {
141-
return System.getenv().get( "SIGNING_GPG_PASSPHRASE" )
142-
}
143-
144-
14580
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14681
// Ancillary tasks
14782

@@ -176,4 +111,4 @@ tasks.withType(PublishToMavenRepository).configureEach {
176111
logger.lifecycle(" - artifact ({}) : {} ({})" , it.classifier, it.file, it.file.size())
177112
}
178113
}
179-
}
114+
}

release/README.adoc

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
= ORM Releases
22
:toc:
33

4-
This module performs the tasks needed as part of creating a release for Hibernate ORM. Releases are triggered as a Jenkins job.
4+
This module performs the tasks needed as part of creating a release for Hibernate ORM.
5+
Releases are triggered as a link:../ci/release/Jenkinsfile[Jenkins pipeline].
6+
7+
Hibernate ORM also publishes SNAPSHOT releases using an automated link:../ci/snapshot-publish.Jenkinsfile[Jenkins pipeline],
8+
which is triggered on a merge to the main branch. This job requires no user interactions.
59

610
== Preparation
711

@@ -38,7 +42,7 @@ If this is a new series, some additional steps are required to prepare the websi
3842
Start the appropriate Jenkins https://ci.hibernate.org/view/Release/job/hibernate-orm-release[job].
3943

4044
NOTE: When a release is started, the job coordinates with the unified Hibernate https://github.com/hibernate/hibernate-release-scripts[release scripts] in a number of stages and steps,
41-
calling tasks on this module's link:./release.gradle[Gradle script].
45+
calling tasks on this module's link:./release.gradle[Gradle script] and leveraging link:../jreleaser.yml[JReleaser configuration].
4246

4347
At a high-level, this process:
4448

tooling/hibernate-maven-plugin/hibernate-maven-plugin.gradle

-7
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@ tasks.register("preVerifyRelease") {
3737
dependsOn releasePrepareTask
3838
}
3939

40-
tasks.register( 'releasePerform' ) {
41-
group "release-perform"
42-
description "See :release:releasePerform for details. Here we hook in publishing to Sonatype"
43-
44-
dependsOn tasks.publishAllPublicationsToSonatypeRepository
45-
}
46-
4740
var publishingExtension = project.getExtensions().getByType(PublishingExtension) as PublishingExtension
4841
publishingExtension.publications.named("publishedArtifacts") {
4942
from components.java

0 commit comments

Comments
 (0)