Child pages
  • Violation Comments to GitHub Plugin
Skip to end of metadata
Go to start of metadata

Plugin Information

View Violation Comments to GitHub on the plugin site for more information.

This plugin uses Violation Comments to GitHub Lib. It will find report files from static code analysis and comment GitHub pull requests with the content.

Example of supported reports are available here.

A number of parsers have been implemented. Some parsers can parse output from several reporters.


ReporterParserNotes
ARM-GCCCLANG
AndroidLintANDROIDLINT
AnsibleLintFLAKE8With -p
CLangCLANG
CPDCPD
CPPCheckCPPCHECK
CPPLintCPPLINT
CSSLintCSSLINT
CheckstyleCHECKSTYLE
CodeNarcCODENARC
DetektCHECKSTYLEWith --output-format xml.
DocFXDOCFX
DoxygenCLANG
ESLintCHECKSTYLEWith format: 'checkstyle'.
FindbugsFINDBUGS
Flake8FLAKE8
FxCopFXCOP
GCCCLANG
GendarmeGENDARME
GoLintGOLINT
GoVetGOLINTSame format as GoLint.
GoogleErrorProneGOOGLEERRORPRONE
InferPMDFacebook Infer. With --pmd-xml.
JCReportJCREPORT
JSHintJSHINT
KTLintCHECKSTYLE
KlocworkKLOCWORK
KotlinGradleKOTLINGRADLEOutput from Kotlin Gradle Plugin.
KotlinMavenKOTLINMAVENOutput from Kotlin Maven Plugin.
LintLINTA common XML format, used by different linters.
MccabeFLAKE8
MyPyMYPY
NullAwayGOOGLEERRORPRONESame format as Google Error Prone.
PCLintPCLINTPC-Lint using the same output format as the Jenkins warnings plugin, details here
PHPCSCHECKSTYLEwith phpcs api.php --report=checkstyle.
PHPPMDPMDwith phpmd api.php xml ruleset.xml.
PMDPMD
Pep8FLAKE8
PerlCriticPERLCRITIC
PiTestPITEST
PyDocStylePYDOCSTYLE
PyFlakesFLAKE8
PyLintPYLINTWith pylint --output-format=parseable.
ReSharperRESHARPER
RubyCopCLANGWith rubycop -f clang file.rb
SbtScalacSBTSCALAC
SimianSIMIAN
SpotbugsFINDBUGS
StyleCopSTYLECOP
SwiftLintCHECKSTYLEWith --reporter checkstyle.
TSLintCHECKSTYLEWith -t checkstyle
XMLLintXMLLINT
YAMLLintYAMLLINTWith -f parsable
ZPTLintZPTLINT


There is also:Missing a format? Open an issue here!

Notify Jenkins from GitHub

Merge

You must perform the merge before build. If you don't perform the merge, the reported violations will refer to other lines then those in the pull request. The merge can be done with a shell script like this.

Merge
echo ---
echo --- Merging from $FROM in $FROMREPO to $TO in $TOREPO
echo ---
git clone $TOREPO
cd *
git reset --hard $TO
git status
git remote add from $FROMREPO
git fetch from
git merge $FROM
git --no-pager log --max-count=10 --graph --abbrev-commit

Your build command here!

Screenshots

When installed, a post build action will be available.

The pull request will be commented like this.

Job DSL

This plugin can be used with the Job DSL Plugin. In this example the GitHub Pull Request Builder Plugin is used to trigger, merge and provide environment variables needed.

DSL
job('GitHub_PR_Builder') {
 concurrentBuild()
 quietPeriod(0)
 scm {
  git {
   remote {
    github('tomasbjerre/violations-test')
    refspec('+refs/pull/*:refs/remotes/origin/pr/*')
   }
   branch('${sha1}')
  }
 }

 triggers {
  githubPullRequest {
   cron('* * * * *')
   permitAll()
   extensions {
    buildStatus {
     completedStatus('SUCCESS', 'There were no errors, go have a cup of coffee...')
     completedStatus('FAILURE', 'There were errors, for info, please see...')
     completedStatus('ERROR', 'There was an error in the infrastructure, please contact...')
    }
   }
  }
 }

 steps {
  shell('''
./gradlew build
  ''')
 }

 publishers {
  violationsToGitHubRecorder {
   config {
    gitHubUrl("https://api.github.com/")
    repositoryOwner("tomasbjerre")
    repositoryName("violations-test")
    pullRequestId("\$ghprbPullId")

    // Only specify one of these!
    oAuth2Token("")
    credentialsId("githubtoken")
    
    createSingleFileComments(true)
    createCommentWithAllSingleFileComments(true)
    commentOnlyChangedContent(true)
    minSeverity('INFO')
    keepOldComments(false)
    
    violationConfigs {
     violationConfig {
      parser("FINDBUGS")
      reporter("Findbugs")
      pattern(".*/findbugs/.*\\.xml\$")
     }
     violationConfig {
      parser("CHECKSTYLE")
      reporter("Checkstyle")
      pattern(".*/checkstyle/.*\\.xml\$")
     }
    }
   }
  }
 }
}


Here is another example using Generic Webhook Trigger plugin. You will need to add a webhook in GitHub and point it to http://JENKINS_URL/generic-webhook-trigger/invokeYou may want to combine this with HTTP Request Plugin to comment the pull requests with a link to the job. And also Conditional BuildStep Plugin to have different comments depending on build status.

DSL
job('GitHub_PR_Builder Generic') {
 concurrentBuild()
 quietPeriod(0)
 parameters {
  stringParam('PULL_REQUEST_HEAD_URL', '')
  stringParam('PULL_REQUEST_BASE_URL', '')
  stringParam('PULL_REQUEST_HEAD_REF', '')
  stringParam('PULL_REQUEST_BASE_REF', '')
 }
 scm {
  git {
   remote {
    name('origin')
    url('$PULL_REQUEST_BASE_URL')
   }
   remote {
    name('upstream')
    url('$PULL_REQUEST_HEAD_URL')
   }
   branch('$PULL_REQUEST_HEAD_REF')
   extensions {
    mergeOptions {
     remote('upstream')
     branch('$PULL_REQUEST_BASE_REF')
    }
   }
  }
 }
 triggers {
  genericTrigger {
   genericVariables {
    genericVariable {
     key("PULL_REQUEST_HEAD_URL")
     value("\$.pull_request.head.repo.clone_url")
     expressionType("JSONPath")
     regexpFilter("")
    }
    genericVariable {
     key("PULL_REQUEST_HEAD_REF")
     value("\$.pull_request.head.ref")
     expressionType("JSONPath")
     regexpFilter("")
    }
    genericVariable {
     key("PULL_REQUEST_BASE_URL")
     value("\$.pull_request.base.repo.clone_url")
     expressionType("JSONPath")
     regexpFilter("")
    }
    genericVariable {
     key("PULL_REQUEST_BASE_REF")
     value("\$.pull_request.base.ref")
     expressionType("JSONPath")
     regexpFilter("")
    }
    genericVariable {
     key("PULL_REQUEST_BASE_OWNER")
     value("\$.pull_request.base.repo.owner.login")
     expressionType("JSONPath")
     regexpFilter("")
    }
    genericVariable {
     key("PULL_REQUEST_BASE_REPO")
     value("\$.pull_request.base.repo.name")
     expressionType("JSONPath")
     regexpFilter("")
    }
    genericVariable {
     key("PULL_REQUEST_ID")
     value("\$.number")
     expressionType("JSONPath")
     regexpFilter("")
    }
    genericVariable {
     key("ACTION")
     value("\$.action")
     expressionType("JSONPath")
     regexpFilter("")
    }
   }
   regexpFilterText("\$ACTION")
   regexpFilterExpression("opened|reopened|synchronize")
  }
 }

 steps {
  shell('./gradlew build')
 }

 publishers {
  violationsToGitHubRecorder {
   config {
    gitHubUrl("https://api.github.com/")
    repositoryOwner("\$PULL_REQUEST_BASE_OWNER")
    repositoryName("\$PULL_REQUEST_BASE_REPO")
    pullRequestId("\$PULL_REQUEST_ID")

    // Only specify one of these!
    oAuth2Token("oh no!")
    credentialsId("githubtoken")

    createSingleFileComments(true)
    createCommentWithAllSingleFileComments(true)
    commentOnlyChangedContent(true)
    minSeverity('INFO')
    keepOldComments(false)
    
    violationConfigs {
     violationConfig {
      parser("FINDBUGS")
      reporter("Findbugs")
      pattern(".*/findbugs/.*\\.xml\$")
     }
     violationConfig {
      parser("CHECKSTYLE")
      reporter("Checkstyle")
      pattern(".*/checkstyle/.*\\.xml\$")
     }
    }
   }
  }
 }
}

Pipeline

This plugin can be used with the Pipeline Plugin:

Pipeline
node {
 def mvnHome = tool 'Maven 3.3.9'
 deleteDir()
 
 stage('Merge') {
  sh "git init"
  sh "git fetch --no-tags --progress git@git:group/reponame.git +refs/heads/*:refs/remotes/origin/* --depth=200"
  sh "git checkout origin/${env.targetBranch}"
  sh "git merge origin/${env.sourceBranch}"
  sh "git log --graph --abbrev-commit --max-count=10"
 }

 stage('Static code analysis') {
  sh "${mvnHome}/bin/mvn package -DskipTests -Dmaven.test.failure.ignore=false -Dsurefire.skip=true -Dmaven.compile.fork=true -Dmaven.javadoc.skip=true"

  step([
   $class: 'ViolationsToGitHubRecorder', 
   config: [
    gitHubUrl: 'https://api.github.com/', 
    repositoryOwner: 'tomasbjerre', 
    repositoryName: 'violations-test', 
    pullRequestId: '2', 

    // Only specify one of these!
    oAuth2Token: '',
    credentialsId: '',

    createCommentWithAllSingleFileComments: true, 
    createSingleFileComments: true, 
    commentOnlyChangedContent: true, 
    minSeverity: 'INFO',
    keepOldComments: false,
    violationConfigs: [
     [ pattern: '.*/checkstyle-result\\.xml$', parser: 'CHECKSTYLE', reporter: 'Checkstyle' ], 
     [ pattern: '.*/findbugsXml\\.xml$', parser: 'FINDBUGS', reporter: 'Findbugs' ], 
     [ pattern: '.*/pmd\\.xml$', parser: 'PMD', reporter: 'PMD' ], 
    ]
   ]
  ])
 }
}


Changelog

https://github.com/jenkinsci/violation-comments-to-github-plugin/blob/master/CHANGELOG.md

1 Comment

  1. Could you provide DSL for this plugin? Specifically the part where pattern needs to be given?