Skip to content

Commit 93e917f

Browse files
committed
1 parent 4bf2ea6 commit 93e917f

File tree

3 files changed

+119
-165
lines changed

3 files changed

+119
-165
lines changed

ci/release/Jenkinsfile

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ def checkoutReleaseScripts() {
5353
}
5454
}
5555

56-
File findReleaseNotes() {
57-
}
5856

5957
// --------------------------------------------
6058
// Pipeline
@@ -95,6 +93,10 @@ pipeline {
9593
stage('Release check') {
9694
steps {
9795
script {
96+
print "INFO: params.RELEASE_VERSION = ${params.RELEASE_VERSION}"
97+
print "INFO: params.DEVELOPMENT_VERSION = ${params.DEVELOPMENT_VERSION}"
98+
print "INFO: params.RELEASE_DRY_RUN? = ${params.RELEASE_DRY_RUN}"
99+
98100
checkoutReleaseScripts()
99101

100102
def currentVersion = Version.parseDevelopmentVersion( sh(
@@ -152,7 +154,7 @@ pipeline {
152154
env.DEVELOPMENT_VERSION = developmentVersion.toString()
153155

154156
if ( params.RELEASE_DRY_RUN ) {
155-
env.SCRIPT_OPTIONS += " -d"
157+
env.SCRIPT_OPTIONS += "-d"
156158
}
157159

158160
// Determine version id to check if Jira version exists
@@ -169,27 +171,20 @@ pipeline {
169171
configFile(fileId: 'release.config.ssh', targetLocation: "${env.HOME}/.ssh/config"),
170172
configFile(fileId: 'release.config.ssh.knownhosts', targetLocation: "${env.HOME}/.ssh/known_hosts")
171173
]) {
172-
withCredentials([
173-
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USER'),
174-
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'PLUGIN_PORTAL_PASSWORD', usernameVariable: 'PLUGIN_PORTAL_USERNAME'),
175-
file(credentialsId: 'release.gpg.private-key', variable: 'RELEASE_GPG_PRIVATE_KEY_PATH'),
176-
string(credentialsId: 'release.gpg.passphrase', variable: 'RELEASE_GPG_PASSPHRASE')
177-
]) {
178-
sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) {
179-
// set release version
180-
// update changelog from JIRA
181-
// tags the version
182-
// changes the version to the provided development version
183-
withEnv([
184-
"BRANCH=${env.GIT_BRANCH}",
185-
"DISABLE_REMOTE_GRADLE_CACHE=true",
186-
// Increase the amount of memory for this part since asciidoctor doc rendering consumes a lot of metaspace
187-
"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'"
188-
]) {
189-
sh ".release/scripts/prepare-release.sh ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION}"
190-
}
191-
}
192-
}
174+
sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) {
175+
// set release version
176+
// update changelog from JIRA
177+
// tags the version
178+
// changes the version to the provided development version
179+
withEnv([
180+
"BRANCH=${env.GIT_BRANCH}",
181+
"DISABLE_REMOTE_GRADLE_CACHE=true",
182+
// Increase the amount of memory for this part since asciidoctor doc rendering consumes a lot of metaspace
183+
"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'"
184+
]) {
185+
sh ".release/scripts/prepare-release.sh ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION}"
186+
}
187+
}
193188
}
194189
}
195190
}
@@ -204,10 +199,12 @@ pipeline {
204199
configFile(fileId: 'release.config.ssh.knownhosts', targetLocation: "${env.HOME}/.ssh/known_hosts")
205200
]) {
206201
withCredentials([
207-
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USER'),
208-
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'PLUGIN_PORTAL_PASSWORD', usernameVariable: 'PLUGIN_PORTAL_USERNAME'),
209-
file(credentialsId: 'release.gpg.private-key', variable: 'RELEASE_GPG_PRIVATE_KEY_PATH'),
210-
string(credentialsId: 'release.gpg.passphrase', variable: 'RELEASE_GPG_PASSPHRASE'),
202+
// https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh
203+
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'ORG_GRADLE_PROJECT_sonatypePassword', usernameVariable: 'ORG_GRADLE_PROJECT_sonatypeUsername'),
204+
// https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#account_setup
205+
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'GRADLE_PUBLISH_SECRET', usernameVariable: 'GRADLE_PUBLISH_KEY'),
206+
file(credentialsId: 'release.gpg.private-key', variable: 'SIGNING_GPG_PRIVATE_KEY_PATH'),
207+
string(credentialsId: 'release.gpg.passphrase', variable: 'SIGNING_GPG_PASSPHRASE')
211208
gitUsernamePassword(credentialsId: 'username-and-token.Hibernate-CI.github.com', gitToolName: 'Default')
212209
]) {
213210
sshagent(['ed25519.Hibernate-CI.github.com', 'hibernate.filemgmt.jboss.org', 'hibernate-ci.frs.sourceforge.net']) {
@@ -216,7 +213,7 @@ pipeline {
216213
withEnv([
217214
"DISABLE_REMOTE_GRADLE_CACHE=true"
218215
]) {
219-
sh ".release/scripts/publish.sh ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION} ${env.GIT_BRANCH} ${env.SCRIPT_OPTIONS}"
216+
sh ".release/scripts/publish.sh ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION} ${env.GIT_BRANCH}"
220217
}
221218
}
222219
}
@@ -243,7 +240,7 @@ pipeline {
243240
extensions: [],
244241
userRemoteConfigs: [[credentialsId: 'ed25519.Hibernate-CI.github.com', url: 'https://github.com/hibernate/hibernate.org.git']]
245242
)
246-
sh "../scripts/website-release.sh ${env.PROJECT} ${env.RELEASE_VERSION} ${env.SCRIPT_OPTIONS} "
243+
sh "../scripts/website-release.sh ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION}"
247244
}
248245
}
249246
}

gradle/published-java-module.gradle

Lines changed: 70 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -24,155 +24,107 @@ dependencies {
2424
javadocSources sourceSets.main.allJava
2525
}
2626

27+
java {
28+
// Configure the Java "software component" to include javadoc and sources jars in addition to the classes jar.
29+
// Ultimately, this component is what makes up the publication for this project.
30+
withJavadocJar()
31+
withSourcesJar()
32+
}
33+
2734

2835
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2936
// Publishing
3037

31-
publishing {
32-
publications {
33-
// main publication
34-
publishedArtifacts {
35-
// Add the Java component to the main publication
36-
from components.java
37-
}
38+
var publishingExtension = project.getExtensions().getByType(PublishingExtension) as PublishingExtension
39+
publishingExtension.publications {
40+
// main publication
41+
publishedArtifacts {
42+
// Add the Java component to the main publication
43+
from components.java
3844
}
3945
}
4046

41-
java {
42-
// include javadoc and sources jar in the Java component
43-
// - classes jar included by default
44-
withJavadocJar()
45-
withSourcesJar()
46-
}
4747

48-
var signingKey = resolveSigningKey()
49-
var signingPassword = findSigningProperty( "RELEASE_GPG_PASSPHRASE" )
48+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49+
// Signing
5050

51-
signing {
52-
useInMemoryPgpKeys( signingKey, signingPassword )
51+
def signPublicationsTask = tasks.register('signPublications') {
52+
description "Grouping task which executes all Sign tasks"
5353

54-
sign publishing.publications.publishedArtifacts
54+
dependsOn tasks.withType( Sign )
5555
}
5656

57-
String resolveSigningKey() {
58-
var key = findSigningProperty( "RELEASE_GPG_PRIVATE_KEY" )
59-
if ( key != null ) {
60-
return key
61-
}
62-
63-
var keyFile = findSigningProperty( "RELEASE_GPG_PRIVATE_KEY_PATH" )
64-
if ( keyFile != null ) {
65-
return new File( keyFile ).text
66-
}
57+
tasks.named( "publishPublishedArtifactsPublicationToSonatypeRepository" ) {
58+
// publishing depends on signing
59+
dependsOn signPublicationsTask
60+
}
6761

68-
return null
62+
tasks.register('sign') {
63+
description "Pseudonym for :signPublications"
64+
dependsOn signPublicationsTask
6965
}
7066

71-
String findSigningProperty(String propName) {
72-
def sysProp = System.getProperty(propName)
73-
if ( sysProp != null ) {
74-
logger.debug "Found `{}` as a system property", propName
75-
return sysProp
76-
}
67+
var signingExtension = project.getExtensions().getByType(SigningExtension) as SigningExtension
7768

78-
def envVar = System.getenv().get(propName)
79-
if ( envVar != null ) {
80-
logger.debug "Found `{}` as an env-var property", propName
81-
return envVar
82-
}
69+
gradle.taskGraph.whenReady { TaskExecutionGraph graph ->
70+
boolean wasSigningRequested = false
71+
boolean wasPublishingRequested = false
8372

84-
def projectProp = project.hasProperty(propName)
85-
if (projectProp) {
86-
logger.debug "Found `{}` as a project property", propName
87-
return projectProp
73+
graph.allTasks.each {task ->
74+
if ( task instanceof Sign ) {
75+
wasSigningRequested = true
76+
}
77+
else if ( task instanceof PublishToMavenRepository ) {
78+
wasPublishingRequested = true
79+
}
8880
}
8981

90-
logger.debug "Did not find `{}`", propName
91-
return null
92-
}
93-
94-
95-
var signingTask = project.tasks.getByName( "signPublishedArtifactsPublication" ) as Sign
96-
var signingExtension = project.getExtensions().getByType(SigningExtension) as SigningExtension
82+
if ( wasPublishingRequested ) {
83+
def ossrhUser = System.getenv().get( "ORG_GRADLE_PROJECT_sonatypeUsername" )
84+
def ossrhPass = System.getenv().get( "ORG_GRADLE_PROJECT_sonatypePassword" )
85+
if ( ossrhUser == null || ossrhPass == null ) {
86+
throw new RuntimeException( "Cannot perform publishing to OSSRH without credentials." )
87+
}
88+
logger.lifecycle "Publishing groupId: '" + project.group + "', version: '" + project.version + "'"
89+
}
9790

98-
task sign {
99-
dependsOn "signPublications"
100-
}
91+
if ( wasSigningRequested || wasPublishingRequested ) {
92+
// signing was explicitly requested and/or we are publishing to Sonatype OSSRH
93+
// - we need the signing to happen
94+
signingExtension.required = true
10195

102-
task signPublications { t ->
103-
tasks.withType( Sign ).all { s ->
104-
t.dependsOn s
96+
var signingKey = resolveSigningKey()
97+
var signingPassword = resolveSigningPassphrase()
98+
signingExtension.useInMemoryPgpKeys( signingKey, signingPassword )
99+
signingExtension.sign publishing.publications.publishedArtifacts
105100
}
106-
}
107-
108-
signingTask.doFirst {
109-
if ( signingKey == null || signingPassword == null ) {
110-
throw new GradleException(
111-
"Cannot perform signing without GPG details. Please set the `signingKey` and `signingKeyFile` properties"
112-
)
101+
else {
102+
// signing was not explicitly requested and we are not publishing to OSSRH,
103+
// - disable all Sign tasks
104+
tasks.withType( Sign ).each { enabled = false }
113105
}
114106
}
115107

116-
117-
boolean wasSigningExplicitlyRequested() {
118-
// check whether signing task was explicitly requested when running the build
119-
//
120-
// NOTE: due to https://discuss.gradle.org/t/how-to-tell-if-a-task-was-explicitly-asked-for-on-the-command-line/42853/3
121-
// we cannot definitively know whether the task was requested. Gradle really just does not expose this information.
122-
// so we make a convention - we check the "start parameters" object to see which task-names were requested;
123-
// the problem is that these are the raw names directly from the command line. e.g. it is perfectly legal to
124-
// say `gradlew signPubArtPub` in place of `gradlew signPublishedArtifactsPublication` - Gradle will simply
125-
// "expand" the name it finds. However, it does not make that available.
126-
//
127-
// so the convention is that we will check for the following task names
128-
//
129-
// for each of:
130-
// 1. `sign`
131-
// 2. `signPublications`
132-
// 3. `signPublishedArtifactsPublication`
133-
//
134-
// and we check both forms:
135-
// 1. "${taskName}"
136-
// 2. project.path + ":${taskName}"
137-
//
138-
// we need to check both again because of the "start parameters" discussion
139-
140-
def signingTaskNames = ["sign", "signPublications", "signPublishedArtifactsPublication"]
141-
142-
for ( String taskName : signingTaskNames ) {
143-
if ( gradle.startParameter.taskNames.contains( taskName )
144-
|| gradle.startParameter.taskNames.contains( "${project.path}:${taskName}" ) ) {
145-
return true
146-
}
108+
static String resolveSigningKey() {
109+
var key = System.getenv().get( "SIGNING_GPG_PRIVATE_KEY" )
110+
if ( key != null ) {
111+
return key
147112
}
148113

149-
return false
150-
}
114+
var keyFile = System.getenv().get( "SIGNING_GPG_PRIVATE_KEY_PATH" )
115+
if ( keyFile != null ) {
116+
return new File( keyFile ).text
117+
}
151118

152-
if ( wasSigningExplicitlyRequested() ) {
153-
// signing was explicitly requested
154-
signingExtension.required = true
119+
throw new RuntimeException( "Cannot perform signing without GPG details." )
155120
}
156-
else {
157-
gradle.taskGraph.whenReady { graph ->
158-
if ( graph.hasTask( signingTask ) ) {
159-
// signing is scheduled to happen.
160-
//
161-
// we know, from above if-check, that it was not explicitly requested -
162-
// so it is triggered via task dependency. make sure we want it to happen
163-
var publishingTask = project.tasks.getByName( "publishPublishedArtifactsPublicationToSonatypeRepository" ) as PublishToMavenRepository
164-
if ( graph.hasTask( publishingTask ) ) {
165-
// we are publishing to Sonatype OSSRH - we need the signing to happen
166-
signingExtension.required = true
167-
}
168-
else {
169-
// signing was not explicitly requested and we are not publishing to OSSRH,
170-
// so do not sign.
171-
signingTask.enabled = false
172-
}
173-
}
174121

122+
static String resolveSigningPassphrase() {
123+
var passphrase = System.getenv().get( "SIGNING_GPG_PASSPHRASE" )
124+
if ( passphrase == null ) {
125+
throw new RuntimeException( "Cannot perform signing without GPG details." )
175126
}
127+
return passphrase
176128
}
177129

178130

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

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ tasks.withType(AbstractArchiveTask).configureEach {
6363
test {
6464
useJUnitPlatform()
6565
if ( project.hasProperty( 'excludeTests' ) ) {
66-
exclude project.property( 'excludeTests' )
66+
exclude project.property( 'excludeTests' ) as String
6767
}
6868
}
6969

@@ -107,14 +107,14 @@ processResources {
107107
filter( ReplaceTokens, tokens: [ 'hibernateVersion': getVersion() ] )
108108
}
109109

110-
tasks.withType( JavaCompile ) {
110+
tasks.withType(JavaCompile).configureEach {
111111
options.encoding = 'UTF-8'
112112
}
113113

114114
if ( !jdkVersions.explicit ) {
115-
tasks.withType( GroovyCompile ) {
116-
sourceCompatibility = JavaVersion.toVersion( jdkVersions.baseline )
117-
targetCompatibility = JavaVersion.toVersion( jdkVersions.baseline )
115+
tasks.withType(GroovyCompile).configureEach {
116+
sourceCompatibility = JavaVersion.toVersion(jdkVersions.baseline)
117+
targetCompatibility = JavaVersion.toVersion(jdkVersions.baseline)
118118
}
119119
}
120120
else {
@@ -133,20 +133,25 @@ tasks.publish.enabled !project.ormVersion.isSnapshot
133133
tasks.publishPlugins.enabled !project.ormVersion.isSnapshot
134134

135135
gradle.taskGraph.whenReady { tg ->
136-
if ( tg.hasTask( project.tasks.publishPlugins ) && project.tasks.publishPlugins.enabled ) {
137-
// look for sys-prop or env-var overrides of the tokens used for publishing
138-
if ( project.properties.containsKey( 'gradle.publish.key' )
139-
|| project.properties.containsKey( 'gradle.publish.secret' ) ) {
140-
// nothing to do - already explicitly set
141-
}
142-
else {
143-
// use the values from the credentials provider, if any
144-
if ( project.property( 'gradle.publish.key' ) == null ) {
145-
throw new RuntimeException( "`-Pgradle.publish.key=...` not found" )
136+
// verify credentials for publishing the plugin up front to avoid any work (only if we are publishing)
137+
if ( tg.hasTask( ":publishPlugins" ) && project.tasks.publishPlugins.enabled ) {
138+
// we are publishing the plugin - make sure there is a credentials pair
139+
//
140+
// first, check the `GRADLE_PUBLISH_KEY` / `GRADLE_PUBLISH_SECRET` combo (env vars)
141+
// and then the `gradle.publish.key` / `gradle.publish.secret` combo (project prop)
142+
// - see https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#account_setup
143+
if ( System.getenv().get("GRADLE_PUBLISH_KEY") != null ) {
144+
if ( System.getenv().get("GRADLE_PUBLISH_SECRET") != null ) {
145+
throw new RuntimeException( "`GRADLE_PUBLISH_KEY` specified, but not `GRADLE_PUBLISH_SECRET` for publishing Gradle plugin" )
146146
}
147-
if ( project.property( 'gradle.publish.secret' ) == null ) {
148-
throw new RuntimeException( "`-Pgradle.publish.secret=...` not found" )
147+
}
148+
else if ( project.findProperty( 'gradle.publish.key' ) != null ) {
149+
if ( project.findProperty( 'gradle.publish.secret' ) != null ) {
150+
throw new RuntimeException( "`gradle.publish.key` specified, but not `gradle.publish.secret` for publishing Gradle plugin" )
149151
}
150152
}
153+
else {
154+
throw new RuntimeException( "No credentials specified for publishing Gradle plugin" )
155+
}
151156
}
152157
}

0 commit comments

Comments
 (0)