Skip to content

Commit 73c9927

Browse files
committed
fix bug where maven publish tasks were not registered within release plugin lifecycle tasks
add test for multiproject setup improve actions gradle setup
1 parent 209dff2 commit 73c9927

File tree

7 files changed

+344
-99
lines changed

7 files changed

+344
-99
lines changed

.github/workflows/nebula.yml

Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,8 @@ on:
99
pull_request:
1010

1111
jobs:
12-
validation:
13-
name: "Gradle Wrapper Validation"
14-
runs-on: ubuntu-latest
15-
steps:
16-
- uses: actions/checkout@v2
17-
- uses: gradle/wrapper-validation-action@v1
1812
buildmultijdk:
1913
if: (!startsWith(github.ref, 'refs/tags/v'))
20-
needs: validation
2114
runs-on: ubuntu-latest
2215
strategy:
2316
matrix:
@@ -38,27 +31,16 @@ jobs:
3831
17
3932
${{ matrix.java }}
4033
java-package: jdk
41-
- uses: actions/cache@v4
42-
id: gradle-cache
43-
with:
44-
path: ~/.gradle/caches
45-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle/dependency-locks/*.lockfile') }}
46-
restore-keys: |
47-
- ${{ runner.os }}-gradle-
48-
- uses: actions/cache@v4
49-
id: gradle-wrapper-cache
34+
- name: Setup Gradle
35+
uses: gradle/actions/setup-gradle@v5
5036
with:
51-
path: ~/.gradle/wrapper
52-
key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }}
53-
restore-keys: |
54-
- ${{ runner.os }}-gradlewrapper-
37+
cache-overwrite-existing: true
5538
- name: Gradle build
5639
run: ./gradlew --info --stacktrace build
5740
env:
5841
JDK_VERSION_FOR_TESTS: ${{ matrix.java }}
5942
validatepluginpublication:
6043
if: startsWith(github.ref, 'refs/tags/v')
61-
needs: validation
6244
runs-on: ubuntu-latest
6345
name: Gradle Plugin Publication Validation
6446
env:
@@ -78,20 +60,10 @@ jobs:
7860
17
7961
21
8062
java-package: jdk
81-
- uses: actions/cache@v4
82-
id: gradle-cache
63+
- name: Setup Gradle
64+
uses: gradle/actions/setup-gradle@v5
8365
with:
84-
path: ~/.gradle/caches
85-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle/dependency-locks/*.lockfile') }}
86-
restore-keys: |
87-
- ${{ runner.os }}-gradle-
88-
- uses: actions/cache@v4
89-
id: gradle-wrapper-cache
90-
with:
91-
path: ~/.gradle/wrapper
92-
key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }}
93-
restore-keys: |
94-
- ${{ runner.os }}-gradlewrapper-
66+
cache-overwrite-existing: true
9567
- name: Verify plugin publication
9668
if: |
9769
startsWith(github.ref, 'refs/tags/v') &&
@@ -123,20 +95,10 @@ jobs:
12395
17
12496
21
12597
java-package: jdk
126-
- uses: actions/cache@v4
127-
id: gradle-cache
128-
with:
129-
path: ~/.gradle/caches
130-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle/dependency-locks/*.lockfile') }}
131-
restore-keys: |
132-
- ${{ runner.os }}-gradle-
133-
- uses: actions/cache@v4
134-
id: gradle-wrapper-cache
98+
- name: Setup Gradle
99+
uses: gradle/actions/setup-gradle@v5
135100
with:
136-
path: ~/.gradle/wrapper
137-
key: ${{ runner.os }}-gradlewrapper-${{ hashFiles('gradle/wrapper/*') }}
138-
restore-keys: |
139-
- ${{ runner.os }}-gradlewrapper-
101+
cache-overwrite-existing: true
140102
- name: Publish candidate
141103
if: |
142104
startsWith(github.ref, 'refs/tags/v') &&

build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ dependencies {
3939
implementation("org.apache.maven:maven-model:3.6.2")
4040
testImplementation("org.spockframework:spock-core:2.3-groovy-4.0")
4141
testImplementation("org.junit.vintage:junit-vintage-engine:5.14.0")
42+
testImplementation("org.ajoberstar.grgit:grgit-core:4.1.1") {
43+
exclude (group= "org.codehaus.groovy", module= "groovy")
44+
}
4245
}
4346

4447
gradlePlugin {

gradle.lockfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
# Manual edits can break the build and are not advised.
33
# This file is expected to be part of source control.
44
cglib:cglib-nodep:3.2.2=integTestRuntimeClasspath,testRuntimeClasspath
5-
com.netflix.nebula:nebula-test:11.5.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
5+
com.googlecode.javaewah:JavaEWAH:1.1.12=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
6+
com.netflix.nebula:nebula-test:11.6.3=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
67
io.github.gradle-nexus:publish-plugin:2.0.0=compileClasspath,integTestCompileClasspath,integTestRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
78
junit:junit:4.13.2=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
89
net.bytebuddy:byte-buddy:1.15.11=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
10+
org.ajoberstar.grgit:grgit-core:4.1.1=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
911
org.apache.groovy:groovy:4.0.4=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
1012
org.apache.maven:maven-model:3.6.2=compileClasspath,integTestCompileClasspath,integTestRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
1113
org.apiguardian:apiguardian-api:1.1.2=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
1214
org.assertj:assertj-core:3.27.3=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
1315
org.codehaus.plexus:plexus-utils:3.2.1=compileClasspath,integTestCompileClasspath,integTestRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
16+
org.eclipse.jgit:org.eclipse.jgit:5.13.0.202109080827-r=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
1417
org.hamcrest:hamcrest-core:1.3=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
1518
org.hamcrest:hamcrest:2.2=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
1619
org.jetbrains.kotlin:kotlin-reflect:2.2.0=compileClasspath,embeddedKotlin,integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -27,5 +30,6 @@ org.junit.platform:junit-platform-launcher:1.14.0=integTestCompileClasspath,inte
2730
org.junit.vintage:junit-vintage-engine:5.14.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
2831
org.objenesis:objenesis:2.4=integTestRuntimeClasspath,testRuntimeClasspath
2932
org.opentest4j:opentest4j:1.3.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
33+
org.slf4j:slf4j-api:1.7.30=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
3034
org.spockframework:spock-core:2.3-groovy-4.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
3135
empty=annotationProcessor,integTestAnnotationProcessor,testAnnotationProcessor

src/main/kotlin/nebula/plugin/publishing/MavenCentralPublishingPlugin.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ class MavenCentralPublishingPlugin @Inject constructor(private val providerFact
6666
throw GradleException("Could not find registered NexusPublishExtension")
6767
}
6868

69-
nexusPublishExtension.packageGroup.set(nebulaOssPublishingExtension.packageGroup.get())
69+
nexusPublishExtension.packageGroup.set(nebulaOssPublishingExtension.packageGroup)
7070
nexusPublishExtension.repositories.sonatype {
7171
nexusUrl.set(URI(sonatypeOssRepositoryUrl))
72-
username.set(nebulaOssPublishingExtension.sonatypeUsername.get())
73-
password.set(nebulaOssPublishingExtension.sonatypePassword.get())
72+
username.set(nebulaOssPublishingExtension.sonatypeUsername)
73+
password.set(nebulaOssPublishingExtension.sonatypePassword)
7474
stagingProfileId.set(getStagingProfileId(project))
7575
}
7676

src/main/kotlin/nebula/plugin/publishing/NebulaOssPublishingPlugin.kt

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ package nebula.plugin.publishing
1818
import org.gradle.api.Plugin
1919
import org.gradle.api.Project
2020
import org.gradle.api.provider.ProviderFactory
21+
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
2122
import org.gradle.kotlin.dsl.apply
23+
import org.gradle.kotlin.dsl.withType
2224
import javax.inject.Inject
2325

2426
/**
2527
* Configures artifact signing and publication to NetflixOSS and Maven Central
2628
*/
27-
open class NebulaOssPublishingPlugin @Inject constructor(private val providerFactory: ProviderFactory): Plugin<Project> {
29+
open class NebulaOssPublishingPlugin @Inject constructor(private val providerFactory: ProviderFactory) :
30+
Plugin<Project> {
2831
companion object {
2932
const val netflixOssDefaultRepositoryBaseUrl = "https://artifacts-oss.netflix.net/artifactory"
3033
const val netflixOssGradlePluginsRepository = "gradle-plugins"
@@ -43,6 +46,16 @@ open class NebulaOssPublishingPlugin @Inject constructor(private val providerFac
4346
project.pluginManager.apply(MavenCentralPublishingPlugin::class)
4447
project.pluginManager.apply(NebulaOssRepositoriesPlugin::class)
4548

49+
project.plugins.withId("com.netflix.nebula.release") {
50+
project.afterEvaluate {
51+
project.tasks.withType<PublishToMavenRepository> {
52+
mustRunAfter(project.rootProject.tasks.named("release"))
53+
}
54+
project.rootProject.tasks.named("postRelease") {
55+
dependsOn(project.tasks.withType<PublishToMavenRepository>())
56+
}
57+
}
58+
}
4659
}
4760

4861
private fun setExtensionDefaults(nebulaOssPublishingExtension: NebulaOssPublishingExtension, project: Project) {
@@ -64,7 +77,7 @@ open class NebulaOssPublishingPlugin @Inject constructor(private val providerFac
6477
"sonatypeStagingProfileId"
6578
) ?: netflixDefaultStagingProfile
6679

67-
if(!stagingProfileId.isNotBlank()) {
80+
if (!stagingProfileId.isNotBlank()) {
6881
extension.stagingProfileId.convention(stagingProfileId)
6982
}
7083
}
@@ -77,14 +90,14 @@ open class NebulaOssPublishingPlugin @Inject constructor(private val providerFac
7790
"sonatypePackageGroup"
7891
) ?: project.group.toString().split(".").take(2).joinToString(".")
7992

80-
if(packageGroup.isNotBlank()) {
93+
if (packageGroup.isNotBlank()) {
8194
extension.packageGroup.convention(packageGroup)
8295
}
8396
}
8497

8598
private fun setSigningKey(extension: NebulaOssPublishingExtension, project: Project) {
8699
val signingKeyFile = project.rootProject.file(signingKeyFileLocation)
87-
if(signingKeyFile.exists()) {
100+
if (signingKeyFile.exists()) {
88101
extension.signingKey.convention(signingKeyFile.readText())
89102
} else {
90103
val signingKey = findPropertyValue(
@@ -93,54 +106,64 @@ open class NebulaOssPublishingPlugin @Inject constructor(private val providerFac
93106
"sonatype.signingKey",
94107
"netflixOssSigningKey"
95108
)
96-
if(!signingKey.isNullOrBlank()) {
109+
if (!signingKey.isNullOrBlank()) {
97110
extension.signingKey.convention(signingKey)
98111
}
99112
}
100113
}
101114

102115
private fun setSigningPassword(extension: NebulaOssPublishingExtension, project: Project) {
103-
val signingPassword = findPropertyValue(project,
116+
val signingPassword = findPropertyValue(
117+
project,
104118
"NETFLIX_OSS_SIGNING_PASSWORD",
105119
"sonatype.signingPassword",
106-
"netflixOssSigningPassword")
107-
if(!signingPassword.isNullOrBlank()) {
120+
"netflixOssSigningPassword"
121+
)
122+
if (!signingPassword.isNullOrBlank()) {
108123
extension.signingPassword.convention(signingPassword)
109124
}
110125
}
111126

112127
private fun setNetflixOssCredentials(extension: NebulaOssPublishingExtension, project: Project) {
113-
val netflixOssUsername = findPropertyValue(project,
128+
val netflixOssUsername = findPropertyValue(
129+
project,
114130
"NETFLIX_OSS_REPO_USERNAME",
115131
"netflixOss.username",
116-
"netflixOssUsername")
117-
if(!netflixOssUsername.isNullOrBlank()) {
132+
"netflixOssUsername"
133+
)
134+
if (!netflixOssUsername.isNullOrBlank()) {
118135
extension.netflixOssUsername.convention(netflixOssUsername)
119136
}
120137

121-
val netflixOssPassword = findPropertyValue(project,
138+
val netflixOssPassword = findPropertyValue(
139+
project,
122140
"NETFLIX_OSS_REPO_PASSWORD",
123141
"netflixOss.password",
124-
"netflixOssPassword")
125-
if(!netflixOssPassword.isNullOrBlank()) {
142+
"netflixOssPassword"
143+
)
144+
if (!netflixOssPassword.isNullOrBlank()) {
126145
extension.netflixOssPassword.convention(netflixOssPassword)
127146
}
128147
}
129148

130149
private fun setMavenCentralCredentials(extension: NebulaOssPublishingExtension, project: Project) {
131-
val sonatypeUsername = findPropertyValue(project,
150+
val sonatypeUsername = findPropertyValue(
151+
project,
132152
"NETFLIX_OSS_SONATYPE_USERNAME",
133153
"sonatype.username",
134-
"sonatypeUsername")
135-
if(!sonatypeUsername.isNullOrBlank()) {
154+
"sonatypeUsername"
155+
)
156+
if (!sonatypeUsername.isNullOrBlank()) {
136157
extension.sonatypeUsername.convention(sonatypeUsername)
137158
}
138159

139-
val sonatypePassword = findPropertyValue(project,
160+
val sonatypePassword = findPropertyValue(
161+
project,
140162
"NETFLIX_OSS_SONATYPE_PASSWORD",
141163
"sonatype.password",
142-
"sonatypePassword")
143-
if(!sonatypePassword.isNullOrBlank()) {
164+
"sonatypePassword"
165+
)
166+
if (!sonatypePassword.isNullOrBlank()) {
144167
extension.sonatypePassword.convention(sonatypePassword)
145168
}
146169
}
@@ -152,7 +175,7 @@ open class NebulaOssPublishingPlugin @Inject constructor(private val providerFac
152175
"netflixOss.repositoryBaseUrl",
153176
"netflixOssRepositoryBaseUrl"
154177
)
155-
if(!repositoryBaseUrl.isNullOrBlank()) {
178+
if (!repositoryBaseUrl.isNullOrBlank()) {
156179
extension.netflixOssRepositoryBaseUrl.convention(repositoryBaseUrl)
157180
} else {
158181
extension.netflixOssRepositoryBaseUrl.convention(netflixOssDefaultRepositoryBaseUrl)
@@ -195,32 +218,38 @@ open class NebulaOssPublishingPlugin @Inject constructor(private val providerFac
195218
}
196219

197220
private fun projectExecutionHasTask(project: Project, task: String): Boolean {
198-
return project.gradle.startParameter.taskNames.contains(task) || project.gradle.startParameter.taskNames.contains(":${task}")
221+
return project.gradle.startParameter.taskNames.contains(task) || project.gradle.startParameter.taskNames.contains(
222+
":${task}"
223+
)
199224
}
200225

201-
private fun findPropertyValue(project: Project,
202-
envVariableName: String,
203-
namespacedPropertyName: String,
204-
propertyName: String
205-
) : String? {
226+
private fun findPropertyValue(
227+
project: Project,
228+
envVariableName: String,
229+
namespacedPropertyName: String,
230+
propertyName: String
231+
): String? {
206232
val propertyValueFromEnv = readEnvVariable(envVariableName)
207233
return when {
208234
propertyValueFromEnv != null -> {
209235
propertyValueFromEnv
210236
}
237+
211238
project.hasProperty(propertyName) -> {
212239
project.prop(propertyName)
213240
}
241+
214242
project.hasProperty(namespacedPropertyName) -> {
215243
project.prop(namespacedPropertyName)
216244
}
245+
217246
else -> null
218247
}
219248
}
220249

221-
private fun readEnvVariable(envVariableName: String) : String? {
250+
private fun readEnvVariable(envVariableName: String): String? {
222251
val envVariable = providerFactory.environmentVariable(envVariableName)
223-
return if(envVariable.isPresent) envVariable.get() else null
252+
return if (envVariable.isPresent) envVariable.get() else null
224253
}
225254

226255
private fun Project.prop(s: String): String? = project.findProperty(s) as String?
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package nebula.plugin.publishing
2+
3+
import nebula.test.dsl.TestProjectRunner
4+
import org.ajoberstar.grgit.Grgit
5+
import java.io.File
6+
7+
fun withGitTag(
8+
projectDir: File,
9+
remoteGitDir: File,
10+
tag: String,
11+
block: () -> TestProjectRunner
12+
): TestProjectRunner {
13+
Grgit.init {
14+
dir = remoteGitDir
15+
}
16+
val localCopy = Grgit.clone {
17+
dir = projectDir
18+
uri = remoteGitDir.toURI().toString()
19+
}
20+
projectDir.resolve(".gitignore").writeText(
21+
"""
22+
.gradle/
23+
"""
24+
)
25+
val runner = block()
26+
localCopy.add {
27+
this.patterns = setOf(".")
28+
}
29+
localCopy.commit {
30+
message = "Initial"
31+
}
32+
localCopy.tag.add {
33+
name = tag
34+
}
35+
return runner
36+
}

0 commit comments

Comments
 (0)