diff --git a/README.adoc b/README.adoc index 9304b99ac..13e93cb1d 100644 --- a/README.adoc +++ b/README.adoc @@ -9,7 +9,9 @@ Check link:https://github.com/jenkins-infra/documentation/blob/master/ci.adoc[th === buildPlugin -Applies the appropriate defaults for building a Maven- or Gradle-based plugin project on +WARNING: Gradle support in `buildPlugin()` is deprecated and will be eventually removed. Please use `buildPluginWithGradle()` + +Applies the appropriate defaults for building a Maven-based plugin project on Linux and Windows. You are advised to be using a link:https://github.com/jenkinsci/plugin-pom/blob/master/README.md[2.x parent POM]. @@ -83,6 +85,47 @@ Usage: buildPlugin(platforms: ['linux'], jdkVersions: [7, 8], findbugs: [archive: true, unstableTotalAll: '0'], checkstyle: [run: true, archive: true]) ---- +=== buildPluginWithGradle() + +Builds a Jenkins plugin using Gradle. +The implementation follows the standard build/test/archive pattern. +The method targets compatibility with link:https://github.com/jenkinsci/gradle-jpi-plugin[Gradle JPI Plugin], +and it may not work for other use-cases. + +==== Optional arguments + +* `repo` (default: `null` inherit from Multibranch) - custom Git repository to check out +* `failFast` (default: `true`) - instruct the build to fail fast when one of the configurations fail +* `platforms` (default: `['linux', 'windows']`) - Labels matching platforms to + execute the steps against in parallel +* `jdkVersions` (default: `[8]`) - JDK version numbers, must match a version + number jdk tool installed +* `configurations`: An alternative way to specify `platforms`, `jdkVersions` (that can not be combined + with any of them) +** Those options will run the build for all combinations of their values. While that is desirable in + many cases, `configurations` permit to provide a specific combinations of label and java/jenkins versions to use +** It is also possible to use a `buildPlugin.recommendedConfigurations()` method to get recommended configurations for testing. +Note that the recommended configuration may change over time, +and hence your CI may break if the new recommended configuration is not compatible +* `timeout`: (default: `60`) - the number of minutes for build timeout, cannot be bigger than 180, i.e. 3 hours. +[source,groovy] +---- +buildPluginWithGradle(/*...*/, configurations: [ + [ platform: "linux", jdk: "8" ], + [ platform: "windows", jdk: "8"], +]) +---- + +==== Limitations + +Not all features of `buildPlugin()` for Maven are supported in the gradle flow. +Examples of not supported features: + +* Deployment of incremental versions (link:https://github.com/jenkinsci/jep/tree/master/jep/305[JEP-305]) +* Publishing of static analysis and coverage reports (Checkstyle, SpotBugs, JaCoCo) +* Configuring `jenkinsVersion` and `javaLevel` for the build flow (as standalone arguments or as `configurations`) +* Usage of link:https://azure.microsoft.com/en-us/services/container-instances/[Azure Container Instances] as agents (only Maven agents are configured) + === infra.isTrusted() Determine whether the Pipeline is executing in an internal "trusted" Jenkins diff --git a/vars/buildPlugin.groovy b/vars/buildPlugin.groovy index 9acb013dd..955bfa4b2 100644 --- a/vars/buildPlugin.groovy +++ b/vars/buildPlugin.groovy @@ -111,6 +111,7 @@ def call(Map params = [:]) { } infra.runMaven(mavenOptions, jdk, null, null, addToolEnv) } else { + echo "WARNING: Gradle mode for buildPlugin() is deprecated, please use buildPluginWithGradle()" List gradleOptions = [ '--no-daemon', 'cleanTest', diff --git a/vars/buildPluginWithGradle.groovy b/vars/buildPluginWithGradle.groovy new file mode 100644 index 000000000..cfd7e634f --- /dev/null +++ b/vars/buildPluginWithGradle.groovy @@ -0,0 +1,84 @@ +#!/usr/bin/env groovy + +/** + * Simple wrapper step for building a plugin with Gradle. + */ +def call(Map params = [:]) { + // Faster build and reduces IO needs + properties([ + durabilityHint('PERFORMANCE_OPTIMIZED'), + buildDiscarder(logRotator(numToKeepStr: '5')), + ]) + + def repo = params.containsKey('repo') ? params.repo : null + def failFast = params.containsKey('failFast') ? params.failFast : true + def timeoutValue = params.containsKey('timeout') ? params.timeout : 60 + if (timeoutValue > 180) { + echo "Timeout value requested was $timeoutValue, lowering to 180 to avoid Jenkins project's resource abusive consumption" + timeoutValue = 180 + } + + boolean publishingIncrementals = false + boolean archivedArtifacts = false + Map tasks = [failFast: failFast] + buildPlugin.getConfigurations(params).each { config -> + String label = config.platform + String jdk = config.jdk + String jenkinsVersion = config.jenkins + String javaLevel = config.javaLevel + + String stageIdentifier = "${label}-${jdk}${jenkinsVersion ? '-' + jenkinsVersion : ''}" + + tasks[stageIdentifier] = { + node(label) { + timeout(timeoutValue) { + // Archive artifacts once with pom declared baseline + boolean doArchiveArtifacts = !jenkinsVersion && !archivedArtifacts + if (doArchiveArtifacts) { + archivedArtifacts = true + } + + stage("Checkout (${stageIdentifier})") { + infra.checkout(repo) + } + + stage("Build (${stageIdentifier})") { + if (javaLevel != null) { + echo "WARNING: 'javaLevel' parameter is not supported in buildPluginWithGradle(). It will be ignored" + } + //TODO(oleg-nenashev): Once supported by Gradle JPI Plugin, pass jenkinsVersion + if (jenkinsVersion != null) { + echo "WARNING: 'jenkinsVersion' parameter is not supported in buildPluginWithGradle(). It will be ignored" + } + List gradleOptions = [ + '--no-daemon', + 'cleanTest', + 'build', + ] + String command = "gradlew ${gradleOptions.join(' ')}" + if (isUnix()) { + command = "./" + command + } + infra.runWithJava(command, jdk) + } + + stage("Archive (${stageIdentifier})") { + junit testReports '**/build/test-results/**/*.xml' + + //TODO(oleg-nenashev): Add static analysis results publishing like in buildPlugin() for Maven + + // TODO do this in a finally-block so we capture all test results even if one branch aborts early + if (failFast && currentBuild.result == 'UNSTABLE') { + error 'There were test failures; halting early' + } + if (doArchiveArtifacts) { + archiveArtifacts artifacts: '**/build/libs/*.hpi,**/build/libs/*.jpi', fingerprint: true + } + } + } + } + } + } + + parallel(tasks) +} diff --git a/vars/buildPluginWithGradle.txt b/vars/buildPluginWithGradle.txt new file mode 100644 index 000000000..c0313eccf --- /dev/null +++ b/vars/buildPluginWithGradle.txt @@ -0,0 +1,18 @@ +

+ Builds a Jenkins plugin using Gradle. +

+

+ The implementation follows the standard build/test/archive pattern. + Note that the Gradle flow for Jenkins plugins offers less functionality than the Maven flow, + some key features are not supported: Incrementals - JEP-305, standard static analysis flows, etc. + The current version also does not allow configuring the jenkinsVersion. +

+ +

+ Usage. The method can be used in the same way as buildPlugin() for Maven projects. + See the documentation in the README of the Pipeline Library repository. +

+ +