Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(buildPluginWithGradle) Add quality checks #652

Merged
merged 3 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ buildPluginWithGradle(/*...*/, configurations: [

* `tests`: (default: `null`) - a map of parameters to run tests during the build
** `skip` - If `true`, skip all the tests.
* `jacoco`: (default: `null`) - a map of parameters to change the default configuration of the `recordCoverage` step of the https://github.com/jenkinsci/code-coverage-api-plugin[Code Coverage Plugin]. This step is called after a plugin build to record the code coverage results of JaCoCo. See https://www.jenkins.io/doc/pipeline/steps/code-coverage-api/#recordcoverage-record-code-coverage-results[recordCoverage step documentation] for a list of available configuration parameters.
* `spotbugs`, `checkstyle`: (default: `null`) - a map of parameters to archive SpotBugs or CheckStyle warnings, respectively.
These values can replace or amend the default configuration for the `recordIssues` step of the https://github.com/jenkinsci/warnings-ng-plugin[Warnings NG Plugin].
See https://github.com/jenkinsci/warnings-ng-plugin/blob/master/doc/Documentation.md#configuration[Warnings NG Plugin documentation]
for a list of available configuration parameters.
* `timeout`: (default: `60`) - the number of minutes for build timeout, cannot be bigger than 180, i.e. 3 hours.

==== Limitations
Expand All @@ -126,7 +131,6 @@ 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` 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)

Expand Down
72 changes: 72 additions & 0 deletions test/groovy/BuildPluginWithGradleStepTests.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,76 @@ class BuildPluginWithGradleStepTests extends BaseTest {
assertTrue(assertMethodCallContainsPattern('error', 'There were test failures'))
assertJobStatusFailure()
}

@Test
void test_buildPluginWithGradle_with_warnings_ng() throws Exception {
def script = loadScript(scriptName)
script.call()
printCallStack()

assertTrue(assertMethodCall('java'))
assertTrue(assertMethodCall('javaDoc'))
assertTrue(assertMethodCallContainsPattern('recordIssues', '{enabledForFailure=true, tools=[java, javadoc], filters=[true], sourceCodeEncoding=UTF-8, skipBlames=true, trendChartType=TOOLS_ONLY}'))

assertTrue(assertMethodCall('spotBugs'))
assertTrue(assertMethodCallContainsPattern('recordIssues', '{tool=spotbugs, sourceCodeEncoding=UTF-8, skipBlames=true, trendChartType=TOOLS_ONLY, qualityGates=[{threshold=1, type=NEW, unstable=true}]}'))

assertTrue(assertMethodCall('checkStyle'))
assertTrue(assertMethodCallContainsPattern('recordIssues', '{tool=checkstyle, sourceCodeEncoding=UTF-8, skipBlames=true, trendChartType=TOOLS_ONLY, qualityGates=[{threshold=1, type=TOTAL, unstable=true}]}'))

assertTrue(assertMethodCallContainsPattern('taskScanner', '{includePattern=**/*.java, excludePattern=**/build/**, highTags=FIXME, normalTags=TODO}'))
assertTrue(assertMethodCallContainsPattern('recordIssues', '{enabledForFailure=true, tool=tasks, sourceCodeEncoding=UTF-8, skipBlames=true, trendChartType=NONE}'))
}

@Test
void test_buildPluginWithGradle_with_warnings_ng_and_thresholds() throws Exception {
def script = loadScript(scriptName)
script.call(spotbugs: [
qualityGates : [
[threshold: 3, type: 'TOTAL', unstable: true],
[threshold: 4, type: 'NEW', unstable: true],
],
sourceCodeEncoding: 'UTF-16'])
printCallStack()

assertTrue(assertMethodCallContainsPattern('recordIssues', '{tool=spotbugs, sourceCodeEncoding=UTF-16, skipBlames=true, trendChartType=TOOLS_ONLY, qualityGates=[{threshold=3, type=TOTAL, unstable=true}, {threshold=4, type=NEW, unstable=true}]}'))
}

@Test
void test_buildPluginWithGradle_with_warnings_ng_and_checkstyle() throws Exception {
def script = loadScript(scriptName)
script.call(checkstyle: [
qualityGates: [
[threshold: 3, type: 'TOTAL', unstable: true],
[threshold: 4, type: 'NEW', unstable: true],
],
filters : '[includeFile(\'MyFile.*.java\'), excludeCategory(\'WHITESPACE\')]'])
printCallStack()

assertTrue(assertMethodCallContainsPattern('recordIssues', '{tool=checkstyle, sourceCodeEncoding=UTF-8, skipBlames=true, trendChartType=TOOLS_ONLY, qualityGates=[{threshold=3, type=TOTAL, unstable=true}, {threshold=4, type=NEW, unstable=true}], filters=[includeFile(\'MyFile.*.java\'), excludeCategory(\'WHITESPACE\')]}'))
}

@Test
void test_buildPluginWithGradle_with_record_coverage_defaults() throws Exception {
def script = loadScript(scriptName)
script.call()
printCallStack()

assertTrue(assertMethodCall('recordCoverage'))
assertDefaultRecordCoverageWithJaCoCo()
}

private assertDefaultRecordCoverageWithJaCoCo() {
assertTrue(assertMethodCallContainsPattern('recordCoverage', '{tools=[{parser=JACOCO, pattern=**/build/reports/jacoco/**/*.xml}], sourceCodeRetention=MODIFIED}'))
}

@Test
void test_buildPluginWithGradle_with_record_coverage_custom() throws Exception {
def script = loadScript(scriptName)
script.call(jacoco: [sourceCodeRetention: 'EVERY_BUILD', sourceDirectories: [[path: 'plugin/src/main/java']]])
printCallStack()

assertTrue(assertMethodCall('recordCoverage'))
assertTrue(assertMethodCallContainsPattern('recordCoverage', '{tools=[{parser=JACOCO, pattern=**/build/reports/jacoco/**/*.xml}], sourceCodeRetention=EVERY_BUILD, sourceDirectories=[{path=plugin/src/main/java}]}'))
}
}
56 changes: 54 additions & 2 deletions vars/buildPluginWithGradle.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,63 @@ def call(Map params = [:]) {
}

stage("Archive (${stageIdentifier})") {
//TODO(oleg-nenashev): Add static analysis results publishing like in buildPlugin() for Maven

if (failFast && currentBuild.result == 'UNSTABLE') {
error 'There were test failures; halting early'
}
echo "Recording static analysis results on '${stageIdentifier}'"

recordIssues(
enabledForFailure: true,
tools: [java(), javaDoc()],
filters: [excludeFile('.*Assert.java')],
sourceCodeEncoding: 'UTF-8',
skipBlames: true,
trendChartType: 'TOOLS_ONLY'
)

// Default configuration for SpotBugs can be overwritten using a `spotbugs`, `checkstyle', etc. parameter (map).
// Configuration see: https://github.com/jenkinsci/warnings-ng-plugin/blob/master/doc/Documentation.md#configuration
Map spotbugsArguments = [tool: spotBugs(pattern: '**/build/reports/spotbugs/*.xml'),
sourceCodeEncoding: 'UTF-8',
skipBlames: true,
trendChartType: 'TOOLS_ONLY',
qualityGates: [[threshold: 1, type: 'NEW', unstable: true]]]
if (params?.spotbugs) {
spotbugsArguments.putAll(params.spotbugs as Map)
}
recordIssues spotbugsArguments

Map checkstyleArguments = [tool: checkStyle(pattern: '**/build/reports/checkstyle/*.xml'),
sourceCodeEncoding: 'UTF-8',
skipBlames: true,
trendChartType: 'TOOLS_ONLY',
qualityGates: [[threshold: 1, type: 'TOTAL', unstable: true]]]
if (params?.checkstyle) {
checkstyleArguments.putAll(params.checkstyle as Map)
}
recordIssues checkstyleArguments

Map jacocoArguments = [tools: [[parser: 'JACOCO', pattern: '**/build/reports/jacoco/**/*.xml']], sourceCodeRetention: 'MODIFIED']
if (params?.jacoco) {
jacocoArguments.putAll(params.jacoco as Map)
}
recordCoverage jacocoArguments


recordIssues(
enabledForFailure: true, tool: taskScanner(
includePattern:'**/*.java',
excludePattern:'**/build/**',
highTags:'FIXME',
normalTags:'TODO'),
sourceCodeEncoding: 'UTF-8',
skipBlames: true,
trendChartType: 'NONE'
)
if (failFast && currentBuild.result == 'UNSTABLE') {
error 'Static analysis quality gates not passed; halting early'
}

if (doArchiveArtifacts) {
archiveArtifacts artifacts: '**/build/libs/*.hpi,**/build/libs/*.jpi', fingerprint: true, allowEmptyArchive: true
}
Expand Down
2 changes: 1 addition & 1 deletion vars/buildPluginWithGradle.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<p>
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.
some key features are not supported: Incrementals - JEP-305, etc.
The current version also does not allow configuring the <code>jenkinsVersion</code>.
</p>

Expand Down