From 35d323e93ab5dbde632b0b47098be40ad8dd3d5f Mon Sep 17 00:00:00 2001 From: James Verbus Date: Wed, 7 Apr 2021 23:27:18 -0700 Subject: [PATCH] Move off of JCenter / TravisCI to Maven Central / GitHub Actions. (#26) --- .github/workflows/ci.yml | 116 +++++++++++++++++++++++ .travis.yml | 55 ----------- README.md | 5 + build.gradle | 21 +++- gradle/java-publication.gradle | 93 ++++++++++++++++++ gradle/release.gradle | 39 ++++++++ gradle/shipkit.gradle | 44 --------- gradle/wrapper/gradle-wrapper.properties | 2 +- isolation-forest/build.gradle | 2 + version.properties | 7 +- 10 files changed, 279 insertions(+), 105 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml create mode 100644 gradle/java-publication.gradle create mode 100644 gradle/release.gradle delete mode 100644 gradle/shipkit.gradle diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8eccec5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,116 @@ +# +# CI build that assembles artifacts and runs tests. +# If validation is successful this workflow releases from the main dev branch. +# +# - skipping CI: add [skip ci] to the commit message +# - skipping release: add [skip release] to the commit message +# +name: CI + +on: + push: + branches: ['master'] + tags-ignore: [v*] # release tags are autogenerated after a successful CI, no need to run CI against them + paths-ignore: + - 'docs/**' + - '**.md' + pull_request: + branches: ['**'] + +jobs: + + build: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - scala-version: 2.11.8 + spark-version: 2.3.0 + - scala-version: 2.11.8 + spark-version: 2.4.3 + - scala-version: 2.12.11 + spark-version: 2.4.3 + - scala-version: 2.12.11 + spark-version: 3.0.0 + if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')" + steps: + - name: Check out code + uses: actions/checkout@v2 # https://github.com/actions/checkout + with: + fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci + - name: Set up Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Perform build + env: + SCALA_VERSION: ${{ matrix.scala-version }} + SPARK_VERSION: ${{ matrix.spark-version }} + run: ./gradlew build publishToMavenLocal -s -PscalaVersion=$SCALA_VERSION -PsparkVersion=$SPARK_VERSION + + github-release: + runs-on: ubuntu-latest + needs: build + # Release job, only for pushes to the main development branch + if: github.event_name == 'push' + && github.ref == 'refs/heads/main' + && github.repository == 'linkedin/isolation-forest' + && !contains(toJSON(github.event.commits.*.message), '[skip release]') + steps: + - name: Check out code + # https://github.com/actions/checkout + uses: actions/checkout@v2 + with: + # Needed to get all tags. Refer https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci + fetch-depth: '0' + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Release + run: ./gradlew githubRelease -s + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +# release: +# runs-on: ubuntu-latest +# strategy: +# matrix: +# include: +# - scala-version: 2.11.8 +# spark-version: 2.3.0 +# - scala-version: 2.11.8 +# spark-version: 2.4.3 +# - scala-version: 2.12.11 +# spark-version: 2.4.3 +# - scala-version: 2.12.11 +# spark-version: 3.0.0 +# if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')" +# steps: +# - name: Check out code +# uses: actions/checkout@v2 # https://github.com/actions/checkout +# with: +# fetch-depth: '0' # https://github.com/shipkit/shipkit-changelog#fetch-depth-on-ci +# - name: Set up Java +# uses: actions/setup-java@v1 +# with: +# java-version: 1.8 +# - name: Perform build +# env: +# SCALA_VERSION: ${{ matrix.scala-version }} +# SPARK_VERSION: ${{ matrix.spark-version }} +# run: ./gradlew build publishToMavenLocal -s -PscalaVersion=$SCALA_VERSION -PsparkVersion=$SPARK_VERSION +# - name: Perform release +# # Release job, only for pushes to the main development branch +# if: github.event_name == 'push' +# && github.ref == 'refs/heads/master' +# && github.repository == 'linkedin/isolation-forest' +# && !contains(toJSON(github.event.commits.*.message), '[skip release]') +# run: ./gradlew publishToSonatype closeAndReleaseStagingRepository -s -PscalaVersion=$SCALA_VERSION -PsparkVersion=$SPARK_VERSION +# env: +# SCALA_VERSION: ${{ matrix.scala-version }} +# SPARK_VERSION: ${{ matrix.spark-version }} +# SONATYPE_USER: ${{ secrets.SONATYPE_USER }} +# SONATYPE_PWD: ${{ secrets.SONATYPE_PWD }} +# PGP_KEY: ${{ secrets.PGP_KEY }} +# PGP_PWD: ${{ secrets.PGP_PWD }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e040d73..0000000 --- a/.travis.yml +++ /dev/null @@ -1,55 +0,0 @@ -# More details on how to configure the Travis build -# https://docs.travis-ci.com/user/customizing-the-build/ - -dist: trusty - -language: scala - -jdk: - - oraclejdk8 - -script: ./gradlew build -s -PscalaVersion=$TRAVIS_SCALA_VERSION -PsparkVersion=$SPARK_VERSION; - -jobs: - include: - - scala: 2.11.8 - env: SPARK_VERSION=2.3.0 - - scala: 2.11.8 - env: SPARK_VERSION=2.4.3 - - scala: 2.12.11 - env: SPARK_VERSION=2.4.3 - - scala: 2.12.11 - env: SPARK_VERSION=3.0.0 - # The upload stage is an inelegant way to automatically publish all artifact variants until the following Shipkit - # issue is resolved: https://github.com/mockito/shipkit/issues/858 - # The baseline (Spark 2.3.0 and Scala 2.11.8) version is uploaded by the subsequent release stage. - - stage: upload - scala: 2.11.8 - env: SPARK_VERSION=2.4.3 - script: ./gradlew releaseNeeded | grep "Releasing" - && ./gradlew bintrayUpload -PscalaVersion=$TRAVIS_SCALA_VERSION -PsparkVersion=$SPARK_VERSION -x :bintrayPublish -x :bintrayUpload - || echo "No release needed."; - - scala: 2.12.11 - env: SPARK_VERSION=2.4.3 - script: ./gradlew releaseNeeded | grep "Releasing" - && ./gradlew bintrayUpload -PscalaVersion=$TRAVIS_SCALA_VERSION -PsparkVersion=$SPARK_VERSION -x :bintrayPublish -x :bintrayUpload - || echo "No release needed."; - - scala: 2.12.11 - env: SPARK_VERSION=3.0.0 - script: ./gradlew releaseNeeded | grep "Releasing" - && ./gradlew bintrayUpload -PscalaVersion=$TRAVIS_SCALA_VERSION -PsparkVersion=$SPARK_VERSION -x :bintrayPublish -x :bintrayUpload - || echo "No release needed."; - - stage: release - scala: 2.11.8 - env: SPARK_VERSION=2.3.0 - script: ./gradlew build -s -PscalaVersion=$TRAVIS_SCALA_VERSION -PsparkVersion=$SPARK_VERSION && ./gradlew ciPerformRelease; - -# Skipping install step to avoid having Travis run arbitrary './gradlew assemble' task -# https://docs.travis-ci.com/user/customizing-the-build/#Skipping-the-Installation-Step -install: - - true - -# Don't build tags -branches: - except: - - /^v\d/ diff --git a/README.md b/README.md index 1ae6c5e..3aa0cf2 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,11 @@ You can also build an artifact with Spark 2.4 (or 3.0) and Scala 2.12. ./gradlew build -PsparkVersion=3.0.0 -PscalaVersion=2.12.11 ``` +To force a rebuild of the library, you can use: +```bash +./gradlew clean build --no-build-cache +``` + ### Add an isolation-forest dependency to your project Please check [Bintray](https://bintray.com/beta/#/linkedin/maven/isolation-forest) for the latest diff --git a/build.gradle b/build.gradle index f50fb41..d127227 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,22 @@ +buildscript { + repositories { + jcenter() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "io.github.gradle-nexus:publish-plugin:1.+" + classpath "org.shipkit:shipkit-auto-version:1.+" + classpath "org.shipkit:shipkit-changelog:1.+" + } +} + plugins { - id "org.shipkit.java" version "2.3.0" } +apply from: "gradle/release.gradle" + allprojects { apply plugin: "eclipse" apply plugin: "idea" @@ -13,3 +28,7 @@ allprojects { mavenCentral() } } + +task clean(type: Delete) { + delete "build" +} diff --git a/gradle/java-publication.gradle b/gradle/java-publication.gradle new file mode 100644 index 0000000..b189b1e --- /dev/null +++ b/gradle/java-publication.gradle @@ -0,0 +1,93 @@ +apply plugin: "java" + +def licenseSpec = copySpec { + from project.rootDir + include "LICENSE" + include "NOTICE" +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier 'sources' + from sourceSets.main.allSource + with licenseSpec +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier 'javadoc' + from tasks.javadoc + with licenseSpec +} + +jar { + with licenseSpec +} + +artifacts { + archives sourcesJar + archives javadocJar +} + +apply plugin: "maven-publish" // https://docs.gradle.org/current/userguide/publishing_maven.html +publishing { + publications { + isolationForestJar(MavenPublication) { + from components.java + artifact sourcesJar + artifact javadocJar + + artifactId = project.archivesBaseName + + pom { + name = artifactId + description = "A Spark/Scala implementation of the isolation forest unsupervised outlier detection algorithm." + + url = "https://github.com/linkedin/isolation-forest" + licenses { + license { + name = 'BSD 2-CLAUSE' + url = 'https://github.com/linkedin/isolation-forest/blob/master/LICENSE' + distribution = 'repo' + } + } + developers { + [ + 'jverbus:James Verbus' + ].each { devData -> + developer { + def devInfo = devData.split(':') + id = devInfo[0] + name = devInfo[1] + url = 'https://github.com/' + devInfo[0] + roles = ["Core developer"] + } + } + } + scm { + url = 'https://github.com/linkedin/isolation-forest.git' + } + issueManagement { + url = 'https://github.com/linkedin/isolation-forest/issues' + system = 'GitHub issues' + } + ciManagement { + url = 'https://travis-ci.com/linkedin/isolation-forest' + system = 'Travis CI' + } + } + } + } + + // Useful for testing - running "publish" will create artifacts/pom in a local dir. + repositories { maven { url = "$rootProject.buildDir/repo" } } +} + +// Fleshes out problems with Maven pom generation when building. +tasks.build.dependsOn("publishIsolationForestJarPublicationToMavenLocal") + +apply plugin: 'signing' // https://docs.gradle.org/current/userguide/signing_plugin.html +signing { + if (System.getenv("PGP_KEY")) { + useInMemoryPgpKeys(System.getenv("PGP_KEY"), System.getenv("PGP_PWD")) + sign publishing.publications.isolationForestJar + } +} diff --git a/gradle/release.gradle b/gradle/release.gradle new file mode 100644 index 0000000..d5690c5 --- /dev/null +++ b/gradle/release.gradle @@ -0,0 +1,39 @@ +// +// Shipkit tasks +// + +// Plugin jars are added to the buildscript classpath in the root build.gradle file. +apply plugin: "org.shipkit.shipkit-auto-version" // https://github.com/shipkit/shipkit-auto-version + +apply plugin: "org.shipkit.shipkit-changelog" // https://github.com/shipkit/shipkit-changelog +tasks.named("generateChangelog") { + previousRevision = project.ext.'shipkit-auto-version.previous-tag' + githubToken = System.getenv("GITHUB_TOKEN") + repository = "linkedin/isolation-forest" +} + +apply plugin: "org.shipkit.shipkit-github-release" // https://github.com/shipkit/shipkit-changelog +tasks.named("githubRelease") { + def genTask = tasks.named("generateChangelog").get() + dependsOn genTask + repository = genTask.repository + changelog = genTask.outputFile + githubToken = System.getenv("GITHUB_TOKEN") + newTagRevision = System.getenv("GITHUB_SHA") +} + +// +// Maven Central configuration +// + +apply plugin: "io.github.gradle-nexus.publish-plugin" // https://github.com/gradle-nexus/publish-plugin/ +nexusPublishing { + repositories { + if (System.getenv("SONATYPE_PWD")) { + sonatype { + username = System.getenv("SONATYPE_USER") + password = System.getenv("SONATYPE_PWD") + } + } + } +} diff --git a/gradle/shipkit.gradle b/gradle/shipkit.gradle deleted file mode 100644 index 3e64b5b..0000000 --- a/gradle/shipkit.gradle +++ /dev/null @@ -1,44 +0,0 @@ -shipkit { - gitHub.repository = "linkedin/isolation-forest" - gitHub.readOnlyAuthToken = "c2a615888e1b91ac44a80b7cbe450f234a14214f" - gitHub.writeAuthToken = System.getenv("GH_WRITE_TOKEN") - - team.developers = ['jverbus:James Verbus'] -} - -allprojects { - plugins.withId("org.shipkit.bintray") { - - //Bintray configuration is handled by JFrog Bintray Gradle Plugin - //For reference see the official documentation: https://github.com/bintray/gradle-bintray-plugin - bintray { - - key = System.getenv("BINTRAY_API_KEY") - - pkg { - repo = 'maven' - user = 'jverbus' - userOrg = 'linkedin' - name = 'isolation-forest' - licenses = ['BSD 2-CLAUSE'] - labels = ['spark', 'unsupervised learning', 'outlier detection'] - description = 'A Spark/Scala implementation of the isolation forest unsupervised outlier detection algorithm.' - } - } - } - - plugins.withId("org.shipkit.java-publish") { - publishing.publications.javaLibrary.pom.withXml { - //refer to Groovy xml Node reference for more info how to manipulate xml - asNode().licenses.replaceNode { - licenses { - license { - name "BSD 2-CLAUSE" - url "https://github.com/linkedin/isolation-forest/blob/master/LICENSE" - distribution "repo" - } - } - } - } - } -} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ea13fdf..442d913 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/isolation-forest/build.gradle b/isolation-forest/build.gradle index 6e7c588..9d35dd5 100644 --- a/isolation-forest/build.gradle +++ b/isolation-forest/build.gradle @@ -32,3 +32,5 @@ test { } archivesBaseName = "${project.name}_${sparkVersion}_${scalaVersionShort}" + +apply from: "$rootDir/gradle/java-publication.gradle" diff --git a/version.properties b/version.properties index e1e7ad6..fdb7ee5 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,3 @@ -#Version of the produced binaries. This file is intended to be checked-in. -#It will be automatically bumped by release automation. -version=1.0.2 -previousVersion=1.0.1 +# Version of the produced binaries. +# The version is inferred by shipkit-auto-version Gradle plugin (https://github.com/shipkit/shipkit-auto-version). +version=1.0.*