Skip to content

Commit f4be30e

Browse files
authored
Merge pull request #25 from rundeck-plugins/grails7-upgrade
Grails 7 Migration - Rundeck 6.0 Compatibility
2 parents ba6426f + ef93360 commit f4be30e

10 files changed

Lines changed: 400 additions & 240 deletions

File tree

.github/workflows/gradle.yml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,28 @@ jobs:
88
runs-on: ubuntu-latest
99

1010
steps:
11-
- uses: actions/checkout@v2
11+
- uses: actions/checkout@v4
1212
with:
1313
fetch-depth: 0
1414
- name: Get Fetch Tags
1515
run: git -c protocol.version=2 fetch --tags --progress --no-recurse-submodules origin
1616
if: "!contains(github.ref, 'refs/tags')"
17-
- name: Set up JDK 1.8
18-
uses: actions/setup-java@v1
17+
- name: Set up JDK 17
18+
uses: actions/setup-java@v4
1919
with:
20-
java-version: 11
20+
java-version: '17'
21+
distribution: 'zulu'
2122
- name: Grant execute permission for gradlew
2223
run: chmod +x gradlew
2324
- name: Build with Gradle
2425
run: ./gradlew build
2526
- name: Get Release Version
2627
id: get_version
27-
run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo ::set-output name=VERSION::$VERSION
28+
run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
2829
- name: Upload plugin jar
29-
uses: actions/upload-artifact@v4.4.1
30+
uses: actions/upload-artifact@v4
3031
with:
3132
# Artifact name
3233
name: Grails-Plugin-${{ steps.get_version.outputs.VERSION }}
3334
# Directory containing files to upload
34-
path: build/libs/http-notification-plugin-${{ steps.get_version.outputs.VERSION }}.jar
35+
path: build/libs/http-notification-${{ steps.get_version.outputs.VERSION }}.jar

.github/workflows/release.yml

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,42 @@
11
on:
22
push:
3-
# Sequence of patterns matched against refs/tags
43
tags:
5-
- '*' # Push events to matching v*, i.e. v1.0, v20.15.10
4+
- '*.*.*'
65

7-
name: Upload Release Asset
6+
name: Publish Release
87

98
jobs:
109
build:
11-
name: Upload Release Asset
10+
name: Publish Release
1211
runs-on: ubuntu-latest
1312
steps:
1413
- name: Checkout code
15-
uses: actions/checkout@v2
14+
uses: actions/checkout@v4
1615
with:
1716
fetch-depth: 0
18-
- name: set up JDK 1.8
19-
uses: actions/setup-java@v1
17+
- name: Set up JDK 17
18+
uses: actions/setup-java@v4
2019
with:
21-
java-version: 11
20+
java-version: '17'
21+
distribution: 'zulu'
2222
- name: Build with Gradle
2323
run: ./gradlew build
2424
- name: Get Release Version
2525
id: get_version
26-
run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo ::set-output name=VERSION::$VERSION
26+
run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
2727
- name: Create Release
28-
id: create_release
29-
uses: actions/create-release@v1.0.0
28+
run: |
29+
gh release create \
30+
--generate-notes \
31+
--title 'Release ${{ steps.get_version.outputs.VERSION }}' \
32+
${{ github.ref_name }} \
33+
build/libs/http-notification-${{ steps.get_version.outputs.VERSION }}.jar
3034
env:
3135
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32-
with:
33-
tag_name: ${{ github.ref }}
34-
release_name: Release ${{ steps.get_version.outputs.VERSION }}
35-
draft: false
36-
prerelease: false
37-
- name: Upload Release Asset (jar)
38-
id: upload-release-asset
39-
uses: actions/upload-release-asset@v1
36+
- name: Publish to Maven Central
37+
run: ./gradlew -PsigningKey=${SIGNING_KEY_B64} -PsigningPassword=${SIGNING_PASSWORD} -PsonatypeUsername=${SONATYPE_USERNAME} -PsonatypePassword=${SONATYPE_PASSWORD} publishToSonatype closeAndReleaseSonatypeStagingRepository
4038
env:
41-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42-
with:
43-
upload_url: ${{ steps.create_release.outputs.upload_url }}
44-
asset_path: build/libs/http-notification-plugin-${{ steps.get_version.outputs.VERSION }}.jar
45-
asset_name: http-notification-plugin-${{ steps.get_version.outputs.VERSION }}.jar
46-
asset_content_type: application/octet-stream
39+
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
40+
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
41+
SIGNING_KEY_B64: ${{ secrets.SIGNING_KEY_B64 }}
42+
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}

build.gradle

Lines changed: 83 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,38 @@
1-
2-
buildscript {
3-
repositories {
4-
mavenCentral()
5-
maven { url "https://oss.sonatype.org/content/groups/public"}
6-
}
7-
}
8-
91
plugins {
10-
id 'pl.allegro.tech.build.axion-release' version '1.13.4'
2+
id 'pl.allegro.tech.build.axion-release' version '1.17.2'
3+
id 'groovy'
4+
id 'java'
5+
id 'io.github.gradle-nexus.publish-plugin' version '2.0.0'
116
}
127

13-
group 'com.rundeck.plugin'
14-
15-
apply plugin: 'pl.allegro.tech.build.axion-release'
16-
apply plugin: 'groovy'
17-
apply plugin: 'java'
18-
19-
sourceCompatibility = 11
20-
ext.rundeckPluginVersion = '1.2'
21-
ext.pluginClassNames='com.rundeck.plugin.HttpNotificationPlugin'
22-
ext.pluginName = 'Http Notification'
23-
ext.pluginDescription = 'A notification plugin that makes HTTP requests'
8+
group 'org.rundeck.plugins'
249

10+
ext.publishName = "Http Notification ${project.version}"
11+
ext.githubSlug = 'rundeck-plugins/http-notification'
12+
ext.developers = [
13+
[id: 'gschueler', name: 'Greg Schueler', email: 'greg@rundeck.com']
14+
]
2515

2616
scmVersion {
27-
ignoreUncommittedChanges = true
17+
ignoreUncommittedChanges = false
2818
tag {
29-
prefix = ''
19+
prefix = '' // NO "v" prefix - see PLUGIN_TAGGING_ARCHITECTURE.md
3020
versionSeparator = ''
31-
def origDeserialize=deserialize
32-
//apend .0 to satisfy semver if the tag version is only X.Y
33-
deserialize = { config, position, tagName ->
34-
def orig = origDeserialize(config, position, tagName)
35-
if (orig.split('\\.').length < 3) {
36-
orig += ".0"
37-
}
38-
orig
39-
}
4021
}
4122
}
42-
project.version = scmVersion.version
23+
24+
version = scmVersion.version // Dynamic version from git tag
25+
26+
java {
27+
sourceCompatibility = JavaVersion.VERSION_17
28+
targetCompatibility = JavaVersion.VERSION_17
29+
withSourcesJar()
30+
withJavadocJar()
31+
}
32+
ext.rundeckPluginVersion = '1.2'
33+
ext.pluginClassNames='com.rundeck.plugin.HttpNotificationPlugin'
34+
ext.pluginName = 'Http Notification'
35+
ext.pluginDescription = 'A notification plugin that makes HTTP requests'
4336

4437
configurations{
4538
//declare custom pluginLibs configuration to include only libs for this plugin
@@ -52,54 +45,55 @@ configurations{
5245
}
5346

5447
repositories {
55-
mavenCentral()
5648
mavenLocal()
57-
maven { url 'https://jitpack.io' }
58-
59-
}
60-
61-
dependencies {
62-
implementation 'org.rundeck:rundeck-core:5.14.0-rc1-20250722'
63-
64-
pluginLibs ('com.github.rundeck-plugins:http-step:1.1.6'){
65-
exclude group: 'org.rundeck', module: 'rundeck-core'
49+
maven {
50+
name = 'Central Portal Snapshots'
51+
url = 'https://central.sonatype.com/repository/maven-snapshots/'
52+
content {
53+
includeGroup('org.rundeck')
54+
}
6655
}
67-
68-
implementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.14'
69-
implementation 'org.codehaus.groovy:groovy-all:3.0.9'
70-
71-
// Add secure commons-lang3 to provide alternative to vulnerable commons-lang 2.6
72-
implementation 'org.apache.commons:commons-lang3:3.18.0'
73-
74-
testImplementation group: 'junit', name: 'junit', version: '4.13.1'
75-
76-
testImplementation "org.codehaus.groovy:groovy-all:3.0.17"
77-
testImplementation "org.spockframework:spock-core:2.0-groovy-3.0"
78-
testImplementation "cglib:cglib-nodep:2.2.2"
79-
testImplementation 'org.objenesis:objenesis:1.4'
80-
81-
}
82-
83-
configurations.all {
84-
resolutionStrategy {
85-
// Replace vulnerable commons-lang with secure commons-lang3
86-
dependencySubstitution {
87-
substitute module('commons-lang:commons-lang') using module('org.apache.commons:commons-lang3:3.18.0')
56+
maven {
57+
name = "PackageCloudTest"
58+
url = uri("https://packagecloud.io/pagerduty/rundeckpro-test/maven2")
59+
content {
60+
includeGroup('org.rundeck.plugins')
8861
}
8962
}
63+
mavenCentral()
9064
}
9165

66+
dependencies {
67+
implementation 'org.apache.groovy:groovy-all:4.0.29'
68+
compileOnly 'org.rundeck:rundeck-core:6.0.0-alpha1-20260407'
69+
testImplementation 'org.rundeck:rundeck-core:6.0.0-alpha1-20260407'
70+
71+
// Apache HTTP client dependencies for compilation (http-step bundles these but doesn't expose them transitively)
72+
implementation 'org.apache.httpcomponents:httpclient:4.5.14'
73+
// Version 3.18.0 fixes CVE-2025-48924 (StackOverflowError in ClassUtils)
74+
implementation 'org.apache.commons:commons-lang3:3.20.0'
75+
76+
// Bundle http-step plugin in lib/ directory for runtime
77+
// Use transitive=false to avoid duplicating dependencies already bundled in http-step JAR
78+
pluginLibs ('org.rundeck.plugins:http-step:1.1.20-grails7') {
79+
transitive = false
80+
}
9281

93-
// task to copy plugin libs to output/lib dir
94-
task copyToLib(type: Copy) {
95-
into "$buildDir/output/lib"
96-
from configurations.pluginLibs
82+
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
83+
testImplementation "org.apache.groovy:groovy-all:4.0.29"
84+
testImplementation "org.spockframework:spock-core:2.4-groovy-4.0"
85+
testImplementation "net.bytebuddy:byte-buddy:1.14.11"
86+
testImplementation 'org.objenesis:objenesis:3.4'
9787
}
9888

9989

10090

10191
jar {
102-
from "$buildDir/output"
92+
// Include plugin dependencies in lib/ directory
93+
into('lib') {
94+
from configurations.pluginLibs
95+
}
96+
10397
manifest {
10498
def libList = configurations.pluginLibs.collect{'lib/' + it.name}.join(' ')
10599
attributes 'Rundeck-Plugin-Name' : pluginName
@@ -115,13 +109,28 @@ jar {
115109
attributes 'Rundeck-Plugin-Archive': 'true'
116110
attributes 'Rundeck-Plugin-Libs': "${libList}"
117111
}
118-
dependsOn(copyToLib)
119112
}
120113

114+
test {
115+
useJUnit()
116+
117+
// Java 17+ module access for reflection/mocking
118+
jvmArgs = [
119+
'--add-opens=java.base/java.lang=ALL-UNNAMED',
120+
'--add-opens=java.base/java.util=ALL-UNNAMED',
121+
'--add-opens=java.base/java.lang.reflect=ALL-UNNAMED',
122+
'--add-opens=java.base/java.net=ALL-UNNAMED'
123+
]
124+
}
121125

122-
//set jar task to depend on copyToLib
123-
jar.dependsOn(copyToLib)
126+
nexusPublishing {
127+
packageGroup = 'org.rundeck.plugins'
128+
repositories {
129+
sonatype {
130+
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
131+
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
132+
}
133+
}
134+
}
124135

125-
tasks.withType(Test) {
126-
useJUnitPlatform()
127-
}
136+
apply from: "${rootDir}/gradle/publishing.gradle"

gradle/publishing.gradle

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Define project extension values in the project gradle file before including this file:
3+
*
4+
* publishName = 'Name of Package'
5+
* publishDescription = 'description' (optional)
6+
* githubSlug = Github slug e.g. 'rundeck/rundeck-cli'
7+
* developers = [ [id:'id', name:'name', email: 'email' ] ] list of developers
8+
*
9+
* Define project properties to sign and publish when invoking publish task:
10+
*
11+
* ./gradlew \
12+
* -PsigningKey="base64 encoded gpg key" \
13+
* -PsigningPassword="password for key" \
14+
* -PsonatypeUsername="sonatype token user" \
15+
* -PsonatypePassword="sonatype token password" \
16+
* publishToSonatype closeAndReleaseSonatypeStagingRepository
17+
*/
18+
apply plugin: 'maven-publish'
19+
apply plugin: 'signing'
20+
21+
publishing {
22+
publications {
23+
"${project.name}"(MavenPublication) { publication ->
24+
from components.java
25+
26+
pom {
27+
name = publishName
28+
description = project.ext.hasProperty('publishDescription') ? project.ext.publishDescription :
29+
project.description ?: publishName
30+
url = "https://github.com/${githubSlug}"
31+
licenses {
32+
license {
33+
name = 'The Apache Software License, Version 2.0'
34+
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
35+
distribution = 'repo'
36+
}
37+
}
38+
scm {
39+
url = "https://github.com/${githubSlug}"
40+
connection = "scm:git:git@github.com/${githubSlug}.git"
41+
developerConnection = "scm:git:git@github.com:${githubSlug}.git"
42+
}
43+
if (project.ext.developers) {
44+
developers {
45+
project.ext.developers.each { dev ->
46+
developer {
47+
id = dev.id
48+
name = dev.name
49+
email = dev.email
50+
}
51+
}
52+
}
53+
}
54+
}
55+
56+
}
57+
}
58+
repositories {
59+
def pkgcldWriteToken = System.getenv("PKGCLD_WRITE_TOKEN") ?: project.findProperty("pkgcldWriteToken")
60+
if (pkgcldWriteToken) {
61+
maven {
62+
name = "PackageCloudTest"
63+
url = uri("https://packagecloud.io/pagerduty/rundeckpro-test/maven2")
64+
authentication {
65+
header(HttpHeaderAuthentication)
66+
}
67+
credentials(HttpHeaderCredentials) {
68+
name = "Authorization"
69+
value = "Bearer " + pkgcldWriteToken
70+
}
71+
}
72+
}
73+
}
74+
}
75+
def base64Decode = { String prop ->
76+
project.findProperty(prop) ?
77+
new String(Base64.getDecoder().decode(project.findProperty(prop).toString())).trim() :
78+
null
79+
}
80+
81+
if (project.hasProperty('signingKey') && project.hasProperty('signingPassword')) {
82+
signing {
83+
useInMemoryPgpKeys(base64Decode("signingKey"), project.signingPassword)
84+
sign(publishing.publications)
85+
}
86+
}

gradle/wrapper/gradle-wrapper.jar

5.48 KB
Binary file not shown.

0 commit comments

Comments
 (0)