diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index b892415..85a66b7 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -8,27 +8,28 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get Fetch Tags run: git -c protocol.version=2 fetch --tags --progress --no-recurse-submodules origin if: "!contains(github.ref, 'refs/tags')" - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + - name: Set up JDK 11 + uses: actions/setup-java@v4 with: - java-version: 1.8 + java-version: '11' + distribution: 'zulu' - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle run: ./gradlew build - name: Get Release Version id: get_version - run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo ::set-output name=VERSION::$VERSION - - name: Upload plugin jar - uses: actions/upload-artifact@v1.0.0 + run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + - name: Upload artifact jar + uses: actions/upload-artifact@v4 with: # Artifact name - name: Grails-Plugin-${{ steps.get_version.outputs.VERSION }} + name: S3-Resource-Plugin-${{ steps.get_version.outputs.VERSION }} # Directory containing files to upload - path: build/libs/aws-s3-model-source-${{ steps.get_version.outputs.VERSION }}.jar \ No newline at end of file + path: build/libs/*-${{ steps.get_version.outputs.VERSION }}.jar \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4a6f9c..e94ed88 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,45 +2,43 @@ on: push: # Sequence of patterns matched against refs/tags tags: - - '*' # Push events to matching v*, i.e. v1.0, v20.15.10 + - 'v[0-9]+.[0-9]+.[0-9]+' # Push events to matching v*, i.e. v1.0, v20.15.10 -name: Upload Release Asset +name: Publish Release jobs: build: - name: Upload Release Asset + name: Publish Release runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 - - name: set up JDK 1.8 - uses: actions/setup-java@v1 + - name: Set up JDK 11 + uses: actions/setup-java@v4 with: - java-version: 1.8 + java-version: '11' + distribution: 'zulu' - name: Build with Gradle run: ./gradlew build - name: Get Release Version id: get_version - run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo ::set-output name=VERSION::$VERSION + run: VERSION=$(./gradlew currentVersion -q -Prelease.quiet) && echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Create Release id: create_release - uses: actions/create-release@v1.0.0 + run: | + gh release create \ + --generate-notes \ + --title 'Release ${{ steps.get_version.outputs.VERSION }}' \ + ${{ github.ref_name }} \ + build/libs/aws-s3-model-source-${{ steps.get_version.outputs.VERSION }}.jar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ steps.get_version.outputs.VERSION }} - draft: false - prerelease: false - - name: Upload Release Asset (jar) - id: upload-release-asset - uses: actions/upload-release-asset@v1 + - name: Publish to Maven Central + run: ./gradlew -PsigningKey=${SIGNING_KEY_B64} -PsigningPassword=${SIGNING_PASSWORD} -PsonatypeUsername=${SONATYPE_USERNAME} -PsonatypePassword=${SONATYPE_PASSWORD} publishToSonatype closeAndReleaseSonatypeStagingRepository env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: build/libs/aws-s3-model-source-${{ steps.get_version.outputs.VERSION }}.jar - asset_name: aws-s3-model-source-${{ steps.get_version.outputs.VERSION }}.jar - asset_content_type: application/octet-stream \ No newline at end of file + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SIGNING_KEY_B64: ${{ secrets.SIGNING_KEY_B64 }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1434f8a..80a46bb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,49 +1,36 @@ -import org.gradle.api.tasks.testing.Test - -/* - * Copyright 2017 Rundeck, Inc. (http://rundeck.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -plugins{ - id 'pl.allegro.tech.build.axion-release' version '1.13.4' +plugins { + id 'java' + id 'groovy' + id 'idea' + alias(libs.plugins.axionRelease) + alias(libs.plugins.nexusPublish) } - -ext.rundeckPluginVersion = '1.2' -ext.pluginClassNames= - 'com.rundeck.plugins.aws.S3ResourceModelSource' +group = 'org.rundeck.plugins' +ext.pluginClassNames='com.rundeck.plugins.aws.S3ResourceModelSource' ext.pluginName = 'S3 resource Model Source' ext.pluginDescription = 'Use Amazon S3 to store resources model file.' +ext.publishName = "S3 Resource Model Source ${project.version}" +ext.githubSlug = 'rundeck-plugins/aws-s3-model-source' +ext.developers = [ + [id: 'gschueler', name: 'Greg Schueler', email: 'greg@rundeck.com'] +] -apply plugin: 'java' -apply plugin: 'groovy' - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -repositories { - mavenCentral() - mavenLocal() -} +ext.rundeckPluginVersion = '1.2' scmVersion { tag { prefix = 'v' versionSeparator = '' } + ignoreUncommittedChanges = true } -version scmVersion.version + +allprojects { + project.version = scmVersion.version + apply from: "${rootDir}/gradle/java.gradle" +} + configurations { pluginLibs @@ -52,22 +39,27 @@ configurations { } } +repositories { + mavenCentral() + mavenLocal() +} + dependencies { - implementation group: 'org.rundeck', name: 'rundeck-core', version: '4.13.0-20230515' - implementation "org.slf4j:slf4j-api:1.7.30" - pluginLibs ('com.amazonaws:aws-java-sdk-s3:1.12.708') { + implementation(libs.rundeckCore) { + exclude group: "com.google.guava" + } + implementation libs.slf4jApi + + pluginLibs(libs.awsSdkS3) { exclude group: "com.fasterxml.jackson.core" exclude group: "com.fasterxml.jackson.dataformat" } - pluginLibs ('com.amazonaws:aws-java-sdk-sts:1.11.743') { + pluginLibs(libs.awsSdkSts) { exclude group: "com.fasterxml.jackson.core" exclude group: "com.fasterxml.jackson.dataformat" } - testImplementation "org.codehaus.groovy:groovy-all:3.0.9" - testImplementation "org.spockframework:spock-core:2.0-groovy-3.0" - testImplementation "cglib:cglib-nodep:2.2.2" - testImplementation 'org.objenesis:objenesis:1.4' + testImplementation libs.bundles.testLibs } task copyToLib(type: Copy) { @@ -88,14 +80,28 @@ jar { attributes 'Rundeck-Plugin-Target-Host-Compatibility': 'all' attributes 'Rundeck-Plugin-Author': 'Rundeck, Inc.' attributes 'Rundeck-Plugin-Classnames': pluginClassNames - attributes 'Rundeck-Plugin-File-Version': version + attributes 'Rundeck-Plugin-File-Version': project.version attributes 'Rundeck-Plugin-Version': rundeckPluginVersion attributes 'Rundeck-Plugin-Archive': 'true' attributes 'Rundeck-Plugin-Libs': "${libList}" } - dependsOn(copyToLib) } -tasks.withType(Test) { +//set jar task to depend on copyToLib +jar.dependsOn(copyToLib) + +test { useJUnitPlatform() -} \ No newline at end of file +} + +nexusPublishing { + packageGroup = 'org.rundeck.plugins' + repositories { + sonatype { + nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/")) + snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/")) + } + } +} + +apply from: "${rootDir}/gradle/publishing.gradle" diff --git a/gradle/java.gradle b/gradle/java.gradle new file mode 100644 index 0000000..a7f905f --- /dev/null +++ b/gradle/java.gradle @@ -0,0 +1,13 @@ +java { + sourceCompatibility = JavaVersion.VERSION_11 + withJavadocJar() + withSourcesJar() +} + +allprojects { + gradle.projectsEvaluated { + tasks.withType(JavaCompile).configureEach { + options.compilerArgs.add("-Xlint:deprecation") + } + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..8cc8140 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,29 @@ +[versions] +axionRelease = "1.18.18" +groovy = "3.0.24" +rundeckCore = "5.10.0-20250312" +nexusPublish = "2.0.0" +spock = "2.3-groovy-3.0" +awsSdk = "1.12.708" +cglib = "2.2.2" +byteBuddy = "1.14.12" +objenesis = "1.4" +slf4j = "1.7.30" + +[libraries] +rundeckCore = { group = "org.rundeck", name = "rundeck-core", version.ref = "rundeckCore" } +groovyAll = { group = "org.codehaus.groovy", name = "groovy-all", version.ref = "groovy" } +spockCore = { group = "org.spockframework", name = "spock-core", version.ref = "spock" } +awsSdkS3 = { group = "com.amazonaws", name = "aws-java-sdk-s3", version.ref = "awsSdk" } +awsSdkSts = { group = "com.amazonaws", name = "aws-java-sdk-sts", version.ref = "awsSdk" } +cglibNodep = { group = "cglib", name = "cglib-nodep", version.ref = "cglib" } +objenesis = { group = "org.objenesis", name = "objenesis", version.ref = "objenesis" } +byteBuddy = { group = "net.bytebuddy", name = "byte-buddy", version.ref = "byteBuddy" } +slf4jApi = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" } + +[bundles] +testLibs = ["groovyAll", "spockCore", "cglibNodep", "objenesis", "byteBuddy"] + +[plugins] +axionRelease = { id = "pl.allegro.tech.build.axion-release", version.ref = "axionRelease" } +nexusPublish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexusPublish" } \ No newline at end of file diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle new file mode 100644 index 0000000..8dd1f0f --- /dev/null +++ b/gradle/publishing.gradle @@ -0,0 +1,70 @@ +/** + * Define project extension values in the project gradle file before including this file: + * + * publishName = 'Name of Package' + * publishDescription = 'description' (optional) + * githubSlug = Github slug e.g. 'rundeck/rundeck-cli' + * developers = [ [id:'id', name:'name', email: 'email' ] ] list of developers + * + * Define project properties to sign and publish when invoking publish task: + * + * ./gradlew \ + * -PsigningKey="base64 encoded gpg key" \ + * -PsigningPassword="password for key" \ + * -PsonatypeUsername="sonatype token user" \ + * -PsonatypePassword="sonatype token password" \ + * publishToSonatype closeAndReleaseSonatypeStagingRepository + */ +apply plugin: 'maven-publish' +apply plugin: 'signing' + +publishing { + publications { + "${project.name}"(MavenPublication) { publication -> + from components.java + + pom { + name = publishName + description = project.ext.hasProperty('pluginDescription') ? project.ext.pluginDescription : + project.description ?: publishName + url = "https://github.com/${githubSlug}" + licenses { + license { + name = 'The Apache Software License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + distribution = 'repo' + } + } + scm { + url = "https://github.com/${githubSlug}" + connection = "scm:git:git@github.com/${githubSlug}.git" + developerConnection = "scm:git:git@github.com:${githubSlug}.git" + } + if (project.ext.developers) { + developers { + project.ext.developers.each { dev -> + developer { + id = dev.id + name = dev.name + email = dev.email + } + } + } + } + } + + } + } +} +def base64Decode = { String prop -> + project.findProperty(prop) ? + new String(Base64.getDecoder().decode(project.findProperty(prop).toString())).trim() : + null +} + +if (project.hasProperty('signingKey') && project.hasProperty('signingPassword')) { + signing { + useInMemoryPgpKeys(base64Decode("signingKey"), project.signingPassword) + sign(publishing.publications) + } +} \ No newline at end of file diff --git a/src/main/java/com/rundeck/plugins/aws/S3Base.java b/src/main/java/com/rundeck/plugins/aws/S3Base.java index 1db3302..d9651c7 100644 --- a/src/main/java/com/rundeck/plugins/aws/S3Base.java +++ b/src/main/java/com/rundeck/plugins/aws/S3Base.java @@ -35,7 +35,7 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.S3ClientOptions; import com.amazonaws.services.s3.model.S3Object; -import com.dtolabs.rundeck.core.common.Framework; +import com.dtolabs.rundeck.core.common.IFramework; import com.dtolabs.rundeck.core.common.INodeSet; import com.dtolabs.rundeck.core.resources.ResourceModelSource; import com.dtolabs.rundeck.core.resources.ResourceModelSourceException; @@ -74,7 +74,7 @@ public class S3Base implements AWSCredentials,ResourceModelSource, WriteableMode private boolean writable=false; - private Framework framework; + private IFramework framework; private AmazonS3 amazonS3; @@ -83,7 +83,7 @@ public void setAmazonS3(AmazonS3 amazonS3){ } public S3Base(String bucket, String filePath, - String extension, Framework framework){ + String extension, IFramework framework){ this.bucket=bucket; this.filePath=filePath; this.extension=extension; diff --git a/src/main/java/com/rundeck/plugins/aws/S3ResourceModelSource.java b/src/main/java/com/rundeck/plugins/aws/S3ResourceModelSource.java index ce5cd84..72cd9b8 100644 --- a/src/main/java/com/rundeck/plugins/aws/S3ResourceModelSource.java +++ b/src/main/java/com/rundeck/plugins/aws/S3ResourceModelSource.java @@ -27,7 +27,7 @@ import com.amazonaws.SDKGlobalConfiguration; import com.amazonaws.auth.PropertiesCredentials; import com.amazonaws.services.s3.S3ClientOptions; -import com.dtolabs.rundeck.core.common.Framework; +import com.dtolabs.rundeck.core.common.IFramework; import com.dtolabs.rundeck.core.plugins.Plugin; import com.dtolabs.rundeck.core.plugins.configuration.ConfigurationException; import com.dtolabs.rundeck.core.plugins.configuration.Describable; @@ -43,7 +43,7 @@ public class S3ResourceModelSource implements ResourceModelSourceFactory,Describable { public static final String PROVIDER_NAME = "aws-s3-source"; - private Framework framework; + private IFramework framework; public static final String KEY = "key"; @@ -151,7 +151,7 @@ public Description getDescription() { return DESC; } - public S3ResourceModelSource(final Framework framework) { + public S3ResourceModelSource(final IFramework framework) { this.framework = framework; } diff --git a/src/test/groovy/com/rundeck/plugins/aws/S3BaseSpec.groovy b/src/test/groovy/com/rundeck/plugins/aws/S3BaseSpec.groovy index 5d9c27f..48613e9 100644 --- a/src/test/groovy/com/rundeck/plugins/aws/S3BaseSpec.groovy +++ b/src/test/groovy/com/rundeck/plugins/aws/S3BaseSpec.groovy @@ -4,7 +4,7 @@ import com.amazonaws.AmazonClientException import com.amazonaws.services.s3.AmazonS3 import com.amazonaws.services.s3.model.ObjectMetadata import com.amazonaws.services.s3.model.S3Object -import com.dtolabs.rundeck.core.common.Framework +import com.dtolabs.rundeck.core.common.IFramework import com.dtolabs.rundeck.core.common.INodeSet import com.dtolabs.rundeck.core.resources.ResourceModelSourceException import com.dtolabs.rundeck.core.resources.format.ResourceFormatParser @@ -172,18 +172,15 @@ class S3BaseSpec extends Specification{ } + private IFramework getFramework(INodeSet nodeSet) { + return Mock(IFramework) { + _ * getResourceFormatParserService() >> Mock(ResourceFormatParserService) { + _ * getParserForMIMEType(_) >> Mock(ResourceFormatParser) { + _ * parseDocument(_) >> nodeSet - private Framework getFramework(INodeSet nodeSet){ - def resourceFormatParser = Mock(ResourceFormatParser){ - parseDocument(_) >> nodeSet + } + } } - def resourceFormatParserService = Mock(ResourceFormatParserService){ - getParserForMIMEType(_) >> resourceFormatParser - } - def framework = Mock(Framework){ - getResourceFormatParserService()>> resourceFormatParserService - } - return framework } }