{"id":14008404,"url":"https://github.com/jenkinsci/violation-comments-to-gitlab-plugin","last_synced_at":"2025-07-12T05:03:44.088Z","repository":{"id":18206736,"uuid":"83757346","full_name":"jenkinsci/violation-comments-to-gitlab-plugin","owner":"jenkinsci","description":"Comments GitLab merge requests with static code analyzer findings.","archived":false,"fork":false,"pushed_at":"2024-08-09T16:03:08.000Z","size":721,"stargazers_count":21,"open_issues_count":10,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-05T03:11:11.994Z","etag":null,"topics":["gitlab-plugin","jenkins-plugin","pipeline","static-code-analysis","violation-comments"],"latest_commit_sha":null,"homepage":"https://plugins.jenkins.io/violation-comments-to-gitlab","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jenkinsci.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["tomasbjerre"]}},"created_at":"2017-03-03T04:27:55.000Z","updated_at":"2025-04-04T04:18:51.000Z","dependencies_parsed_at":"2024-03-02T08:32:17.107Z","dependency_job_id":"2916f3bd-44f1-4e8d-bf1f-bd49cd1aa9d3","html_url":"https://github.com/jenkinsci/violation-comments-to-gitlab-plugin","commit_stats":null,"previous_names":[],"tags_count":93,"template":false,"template_full_name":null,"purl":"pkg:github/jenkinsci/violation-comments-to-gitlab-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fviolation-comments-to-gitlab-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fviolation-comments-to-gitlab-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fviolation-comments-to-gitlab-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fviolation-comments-to-gitlab-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jenkinsci","download_url":"https://codeload.github.com/jenkinsci/violation-comments-to-gitlab-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenkinsci%2Fviolation-comments-to-gitlab-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264940386,"owners_count":23686243,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gitlab-plugin","jenkins-plugin","pipeline","static-code-analysis","violation-comments"],"created_at":"2024-08-10T11:01:38.947Z","updated_at":"2025-07-12T05:03:44.060Z","avatar_url":"https://github.com/jenkinsci.png","language":"Java","funding_links":["https://github.com/sponsors/tomasbjerre"],"categories":["Java"],"sub_categories":[],"readme":"# Violation Comments to GitLab Plugin\n\n\nThis is a Jenkins plugin for [Violation Comments to GitLab Lib](https://github.com/tomasbjerre/violation-comments-to-gitlab-lib). This plugin will find report files from static code analysis and comment GitLab pull requests with the content.\n\nAn alternative is also to have [violations-command-line](https://github.com/tomasbjerre/violations-command-line) convert the violations to `CodeClimate` format and upload that to GitLab. It is explained in readme of [violations-command-line](https://github.com/tomasbjerre/violations-command-line).\n\nAvailable in Jenkins [here](https://wiki.jenkins-ci.org/display/JENKINS/Violation+Comments+to+GitLab+Plugin).\n\nExample of supported reports are available [here](https://github.com/tomasbjerre/violations-lib/tree/master/src/test/resources).\n\nThere is a complete running example available here: https://github.com/tomasbjerre/jenkins-configuration-as-code-sandbox\n\nYou can also do this with a [command line tool](https://www.npmjs.com/package/violation-comments-to-gitlab-command-line).\n\nA number of **parsers** have been implemented. Some **parsers** can parse output from several **reporters**.\n\n| Reporter | Parser | Notes\n| --- | --- | ---\n| [_ARM-GCC_](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm)               | `CLANG`              | \n| [_AndroidLint_](http://developer.android.com/tools/help/lint.html)                    | `ANDROIDLINT`        | \n| [_Ansible-Later_](https://github.com/thegeeklab/ansible-later)                        | `ANSIBLELATER`       | With `json` format\n| [_AnsibleLint_](https://github.com/willthames/ansible-lint)                           | `FLAKE8`             | With `-p`\n| [_Bandit_](https://github.com/PyCQA/bandit)                                           | `CLANG`              | With `bandit -r examples/ -f custom -o bandit.out --msg-template \"{abspath}:{line}: {severity}: {test_id}: {msg}\"`\n| [_CLang_](https://clang-analyzer.llvm.org/)                                           | `CLANG`              | \n| [_CPD_](http://pmd.sourceforge.net/pmd-4.3.0/cpd.html)                                | `CPD`                | \n| [_CPPCheck_](http://cppcheck.sourceforge.net/)                                        | `CPPCHECK`           | With `cppcheck test.cpp --output-file=cppcheck.xml --xml`\n| [_CPPLint_](https://github.com/theandrewdavis/cpplint)                                | `CPPLINT`            | \n| [_CSSLint_](https://github.com/CSSLint/csslint)                                       | `CSSLINT`            | \n| [_Checkstyle_](http://checkstyle.sourceforge.net/)                                    | `CHECKSTYLE`         | \n| [_CloudFormation Linter_](https://github.com/aws-cloudformation/cfn-lint)             | `JUNIT`              | `cfn-lint . -f junit --output-file report-junit.xml`\n| [_CodeClimate_](https://codeclimate.com/)                                             | `CODECLIMATE`        | \n| [_CodeNarc_](http://codenarc.sourceforge.net/)                                        | `CODENARC`           | \n| [_Coverity_](https://scan.coverity.com/)                                              | `COVERITY`           | \n| [_Dart_](https://dart.dev/)                                                           | `MACHINE`            | With `dart analyze --format=machine`\n| [_Dependency Check_](https://jeremylong.github.io/DependencyCheck/)                   | `SARIF`              | Using `--format SARIF`\n| [_Detekt_](https://github.com/arturbosch/detekt)                                      | `CHECKSTYLE`         | With `--output-format xml`.\n| [_DocFX_](http://dotnet.github.io/docfx/)                                             | `DOCFX`              | \n| [_Doxygen_](https://www.stack.nl/~dimitri/doxygen/)                                   | `CLANG`              | \n| [_ERB_](https://www.puppetcookbook.com/posts/erb-template-validation.html)            | `CLANG`              | With `erb -P -x -T '-' \"${it}\" \\| ruby -c 2\u003e\u00261 \u003e/dev/null \\| grep '^-' \\| sed -E 's/^-([a-zA-Z0-9:]+)/${filename}\\1 ERROR:/p' \u003e erbfiles.out`.\n| [_ESLint_](https://github.com/sindresorhus/grunt-eslint)                              | `CHECKSTYLE`         | With `format: 'checkstyle'`.\n| [_Findbugs_](http://findbugs.sourceforge.net/)                                        | `FINDBUGS`           | \n| [_Flake8_](http://flake8.readthedocs.org/en/latest/)                                  | `FLAKE8`             | \n| [_FxCop_](https://en.wikipedia.org/wiki/FxCop)                                        | `FXCOP`              | \n| [_GCC_](https://gcc.gnu.org/)                                                         | `CLANG`              | \n| [_GHS_](https://www.ghs.com/)                                                         | `GHS`                | \n| [_Gendarme_](http://www.mono-project.com/docs/tools+libraries/tools/gendarme/)        | `GENDARME`           | \n| [_Generic reporter_]()                                                                | `GENERIC`            | Will create one single violation with all the content as message.\n| [_GoLint_](https://github.com/golang/lint)                                            | `GOLINT`             | \n| [_GoVet_](https://golang.org/cmd/vet/)                                                | `GOLINT`             | Same format as GoLint.\n| [_GolangCI-Lint_](https://github.com/golangci/golangci-lint/)                         | `CHECKSTYLE`         | With `--out-format=checkstyle`.\n| [_GoogleErrorProne_](https://github.com/google/error-prone)                           | `GOOGLEERRORPRONE`   | \n| [_HadoLint_](https://github.com/hadolint/hadolint/)                                   | `CHECKSTYLE`         | With `-f checkstyle`\n| [_IAR_](https://www.iar.com/iar-embedded-workbench/)                                  | `IAR`                | With `--no_wrap_diagnostics`\n| [_Infer_](http://fbinfer.com/)                                                        | `PMD`                | Facebook Infer. With `--pmd-xml`.\n| [_JACOCO_](https://www.jacoco.org/)                                                   | `JACOCO`             | \n| [_JCReport_](https://github.com/jCoderZ/fawkez/wiki/JcReport)                         | `JCREPORT`           | \n| [_JSHint_](http://jshint.com/)                                                        | `JSLINT`             | With `--reporter=jslint` or the CHECKSTYLE parser with `--reporter=checkstyle`\n| [_JUnit_](https://junit.org/junit4/)                                                  | `JUNIT`              | It only contains the failures.\n| [_KTLint_](https://github.com/shyiko/ktlint)                                          | `CHECKSTYLE`         | \n| [_Klocwork_](http://www.klocwork.com/products-services/klocwork/static-code-analysis)  | `KLOCWORK`           | \n| [_KotlinGradle_](https://github.com/JetBrains/kotlin)                                 | `KOTLINGRADLE`       | Output from Kotlin Gradle Plugin.\n| [_KotlinMaven_](https://github.com/JetBrains/kotlin)                                  | `KOTLINMAVEN`        | Output from Kotlin Maven Plugin.\n| [_Lint_]()                                                                            | `LINT`               | A common XML format, used by different linters.\n| [_MSBuildLog_](https://docs.microsoft.com/en-us/visualstudio/msbuild/obtaining-build-logs-with-msbuild?view=vs-2019)  | `MSBULDLOG`          | With `-fileLogger` use `.*msbuild\\\\.log$` as pattern or `-fl -flp:logfile=MyProjectOutput.log;verbosity=diagnostic` for a custom output filename\n| [_MSCpp_](https://visualstudio.microsoft.com/vs/features/cplusplus/)                  | `MSCPP`              | \n| [_Mccabe_](https://pypi.python.org/pypi/mccabe)                                       | `FLAKE8`             | \n| [_MyPy_](https://pypi.python.org/pypi/mypy-lang)                                      | `MYPY`               | \n| [_NullAway_](https://github.com/uber/NullAway)                                        | `GOOGLEERRORPRONE`   | Same format as Google Error Prone.\n| [_PCLint_](http://www.gimpel.com/html/pcl.htm)                                        | `PCLINT`             | PC-Lint using the same output format as the Jenkins warnings plugin, [_details here_](https://wiki.jenkins.io/display/JENKINS/PcLint+options)\n| [_PHPCS_](https://github.com/squizlabs/PHP_CodeSniffer)                               | `CHECKSTYLE`         | With `phpcs api.php --report=checkstyle`.\n| [_PHPPMD_](https://phpmd.org/)                                                        | `PMD`                | With `phpmd api.php xml ruleset.xml`.\n| [_PMD_](https://pmd.github.io/)                                                       | `PMD`                | \n| [_Pep8_](https://github.com/PyCQA/pycodestyle)                                        | `FLAKE8`             | \n| [_PerlCritic_](https://github.com/Perl-Critic)                                        | `PERLCRITIC`         | \n| [_PiTest_](http://pitest.org/)                                                        | `PITEST`             | \n| [_ProtoLint_](https://github.com/yoheimuta/protolint)                                 | `PROTOLINT`          | \n| [_Puppet-Lint_](http://puppet-lint.com/)                                              | `CLANG`              | With `-log-format %{fullpath}:%{line}:%{column}: %{kind}: %{message}`\n| [_PyDocStyle_](https://pypi.python.org/pypi/pydocstyle)                               | `PYDOCSTYLE`         | \n| [_PyFlakes_](https://pypi.python.org/pypi/pyflakes)                                   | `FLAKE8`             | \n| [_PyLint_](https://www.pylint.org/)                                                   | `PYLINT`             | With `pylint --output-format=parseable`.\n| [_ReSharper_](https://www.jetbrains.com/resharper/)                                   | `RESHARPER`          | \n| [_RubyCop_](http://rubocop.readthedocs.io/en/latest/formatters/)                      | `CLANG`              | With `rubycop -f clang file.rb`\n| [_SARIF_](https://github.com/oasis-tcs/sarif-spec)                                    | `SARIF`              | v2.x. Microsoft Visual C# can generate it with `ErrorLog=\"BuildErrors.sarif,version=2\"`.\n| [_SbtScalac_](http://www.scala-sbt.org/)                                              | `SBTSCALAC`          | \n| [_Scalastyle_](http://www.scalastyle.org/)                                            | `CHECKSTYLE`         | \n| [_Semgrep_](https://semgrep.dev/)                                                     | `SEMGREP`            | With `--json`.\n| [_Simian_](http://www.harukizaemon.com/simian/)                                       | `SIMIAN`             | \n| [_Sonar_](https://www.sonarqube.org/)                                                 | `SONAR`              | With `mvn sonar:sonar -Dsonar.analysis.mode=preview -Dsonar.report.export.path=sonar-report.json`. Removed in 7.7, see [SONAR-11670](https://jira.sonarsource.com/browse/SONAR-11670) but can be retrieved with: `curl --silent 'http://sonar-server/api/issues/search?componentKeys=unique-key\u0026resolved=false' \\| jq -f sonar-report-builder.jq \u003e sonar-report.json`.\n| [_Spotbugs_](https://spotbugs.github.io/)                                             | `FINDBUGS`           | \n| [_StyleCop_](https://stylecop.codeplex.com/)                                          | `STYLECOP`           | \n| [_SwiftLint_](https://github.com/realm/SwiftLint)                                     | `CHECKSTYLE`         | With `--reporter checkstyle`.\n| [_TSLint_](https://palantir.github.io/tslint/usage/cli/)                              | `CHECKSTYLE`         | With `-t checkstyle`\n| [_Valgrind_](https://valgrind.org/)                                                   | `VALGRIND`           | With `--xml=yes`.\n| [_XMLLint_](http://xmlsoft.org/xmllint.html)                                          | `XMLLINT`            | \n| [_XUnit_](https://xunit.net/)                                                         | `XUNIT`              | It only contains the failures.\n| [_YAMLLint_](https://yamllint.readthedocs.io/en/stable/index.html)                    | `YAMLLINT`           | With `-f parsable`\n| [_ZPTLint_](https://pypi.python.org/pypi/zptlint)                                     | `ZPTLINT`            |\n\n52 parsers and 79 reporters.\n\nMissing a format? Open an issue [here](https://github.com/tomasbjerre/violations-lib/issues)!\n\nThere is also:\n * [violation-comments-to-gitlab-command-line](https://github.com/tomasbjerre/violation-comments-to-gitlab-command-line).\n * [violations-command-line](https://github.com/tomasbjerre/violations-command-line), can transform reports to `CodeClimate`.\n\n## Notify Jenkins from GitLab\n\n* You may trigger with a [webhook](https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#merge-request-events) in GitLab. And consume it with [Generic Webhook Trigger plugin](https://github.com/jenkinsci/generic-webhook-trigger-plugin) to get the variables you need.\n\n* Or, trigger with [GitLab plugin](https://github.com/jenkinsci/gitlab-plugin).\n\n* Or, trigger with [GitLab Merge Request Builder Plugin](https://github.com/timols/jenkins-gitlab-merge-request-builder-plugin).\n\n## Merge\n\n**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.\n\n```shell\necho ---\necho --- Merging from $FROM in $FROMREPO to $TO in $TOREPO\necho ---\ngit clone $TOREPO\ncd *\ngit reset --hard $TO\ngit status\ngit remote add from $FROMREPO\ngit fetch from\ngit merge $FROM\ngit --no-pager log --max-count=10 --graph --abbrev-commit\n\nYour build command here!\n```\n\n# Screenshots\n\nComments can be made on the diff with one comment per violation `createSingleFileComments`.\n\n![Example comment on diff](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/blob/master/sandbox/gitlab-comment-diff.png)\n\nOr one big comment can be made, `createCommentWithAllSingleFileComments`.\n\n![Example comment](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/blob/master/sandbox/mergerequest-onecomment.png)\n\n## Job DSL Plugin\n\nThis plugin can be used with the Job DSL Plugin. Here is an example using [Generic Webhook Trigger plugin](https://github.com/jenkinsci/generic-webhook-trigger-plugin), [HTTP Request Plugin](https://wiki.jenkins-ci.org/display/JENKINS/HTTP+Request+Plugin) and [Conditional BuildStep Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Conditional+BuildStep+Plugin).\n\n```groovy\njob('GitLab_MR_Builder') {\n concurrentBuild()\n quietPeriod(0)\n parameters {\n  stringParam('MERGE_REQUEST_TO_URL', '')\n  stringParam('MERGE_REQUEST_FROM_URL', '')\n  stringParam('MERGE_REQUEST_TO_BRANCH', '')\n  stringParam('MERGE_REQUEST_FROM_BRANCH', '')\n }\n scm {\n  git {\n   remote {\n    name('origin')\n    url('$MERGE_REQUEST_TO_URL')\n   }\n   remote {\n    name('upstream')\n    url('$MERGE_REQUEST_FROM_URL')\n   }\n   branch('$MERGE_REQUEST_FROM_BRANCH')\n   extensions {\n    mergeOptions {\n     remote('upstream')\n     branch('$MERGE_REQUEST_TO_BRANCH')\n    }\n   }\n  }\n }\n triggers {\n  genericTrigger {\n   genericVariables {\n    genericVariable {\n     key(\"MERGE_REQUEST_TO_URL\")\n     value(\"\\$.object_attributes.target.git_http_url\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUEST_FROM_URL\")\n     value(\"\\$.object_attributes.source.git_http_url\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUEST_TO_BRANCH\")\n     value(\"\\$.object_attributes.target_branch\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUEST_FROM_BRANCH\")\n     value(\"\\$.object_attributes.source_branch\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"PROJECT_ID\")\n     value(\"\\$.object_attributes.target_project_id\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUST_ID\")\n     value(\"\\$.object_attributes.id\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MR_OBJECT_KIND\")\n     value(\"\\$.object_kind\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MR_OLD_REV\")\n     value(\"\\$.object_attributes.oldrev\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MR_ACTION\")\n     value(\"\\$.object_attributes.action\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n   }\n   regexpFilterText(\"\\$MR_OBJECT_KIND \\$MR_ACTION \\$MR_OLD_REV\")\n   regexpFilterExpression(\"^merge_request\\\\s(update\\\\s.{40}\\$|open.*)\")\n  }\n }\n steps {\n  httpRequest {\n   url(\"http://gitlab:880/api/v3/projects/\\$PROJECT_ID/merge_requests/\\$MERGE_REQUST_ID/notes?private_token=AvAkp6HtUvzpesPypXSk\")\n   consoleLogResponseBody(true)\n   httpMode(\"POST\")\n   requestBody('body=Building... %20\\$BUILD_URL')\n   }\n \n  shell('./gradlew build')\n \n  conditionalBuilder {\n   runCondition {\n    statusCondition {\n     worstResult('SUCCESS')\n     bestResult('SUCCESS')\n    }\n    runner {\n     runUnstable()\n    }\n    conditionalbuilders {\n     httpRequest {\n      url('http://gitlab:880/api/v3/projects/\\$PROJECT_ID/merge_requests/\\$MERGE_REQUST_ID/notes?private_token=AvAkp6HtUvzpesPypXSk')\n      consoleLogResponseBody(true)\n      httpMode('POST')\n      requestBody('body=SUCCESS%20\\$BUILD_URL')\n     }\n    }\n   }\n  }\n \n  conditionalBuilder {\n   runCondition {\n    statusCondition {\n     worstResult('FAILURE')\n     bestResult('FAILURE')\n    }\n    runner {\n     runUnstable()\n    }\n    conditionalbuilders {\n     httpRequest {\n      url('http://gitlab:880/api/v3/projects/\\$PROJECT_ID/merge_requests/\\$MERGE_REQUST_ID/notes?private_token=AvAkp6HtUvzpesPypXSk')\n      consoleLogResponseBody(true)\n      httpMode('POST')\n      requestBody('body=FAIL%20\\$BUILD_URL')\n     }\n    }\n   }\n  }\n }\n publishers {\n  violationsToGitLabRecorder {\n   config {\n    gitLabUrl(\"http://gitlab:880/\")\n    projectId(\"\\$PROJECT_ID\")\n    mergeRequestIid(\"\\$MERGE_REQUST_IID\")\n    \n    // Only specify proxy if you need it\n    proxyUri('')\n    proxyCredentialsId('') // A username/password credential\n \n    commentOnlyChangedContent(true)\n    commentOnlyChangedContentContext(0)\n    commentOnlyChangedFiles(true)\n    createSingleFileComments(true)\n    createCommentWithAllSingleFileComments(true)\n    minSeverity('INFO')\n    maxNumberOfViolations(99999)\n    \n    //You may want this when troubleshooting things\n    enableLogging(true)\n    \n \n    apiTokenCredentialsId(\"gitlabtoken\") // A secret text credential\n    apiTokenPrivate(true)\n    authMethodHeader(true)\n    ignoreCertificateErrors(true)\n    \n    commentTemplate(\"\"\"\n    **Reporter**: {{violation.reporter}}{{#violation.rule}}\n    \n    **Rule**: {{violation.rule}}{{/violation.rule}}\n    **Severity**: {{violation.severity}}\n    **File**: {{violation.file}} L{{violation.startLine}}{{#violation.source}}\n    \n    **Source**: {{violation.source}}{{/violation.source}}\n    \n    {{violation.message}}\n    \"\"\")\n \n    violationConfigs {\n     violationConfig {\n      parser(\"FINDBUGS\")\n      reporter(\"Findbugs\")\n      pattern(\".*/findbugs/.*\\\\.xml\\$\")\n     }\n     violationConfig {\n      parser(\"CHECKSTYLE\")\n      reporter(\"Checkstyle\")\n      pattern(\".*/checkstyle/.*\\\\.xml\\$\")\n     }\n    }\n   }\n  }\n }\n}\n```\n\n## Pipeline Plugin\n\nHere is an example pipeline that will merge, run unit tests, run static code analysis and finally report back to GitLab. It requires the [GitLab Plugin](https://github.com/jenkinsci/gitlab-plugin).\n\n```groovy\npipelineJob(\"merge-request-pipeline\") {\n concurrentBuild()\n quietPeriod(0)\n authenticationToken(\"thetoken\")\n triggers {\n  genericTrigger {\n   genericVariables {\n    genericVariable {\n     key(\"MERGE_REQUEST_TO_URL\")\n     value(\"\\$.object_attributes.target.git_http_url\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUEST_FROM_URL\")\n     value(\"\\$.object_attributes.source.git_http_url\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUEST_TO_BRANCH\")\n     value(\"\\$.object_attributes.target_branch\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUEST_FROM_BRANCH\")\n     value(\"\\$.object_attributes.source_branch\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"PROJECT_ID\")\n     value(\"\\$.object_attributes.target_project_id\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"PROJECT_PATH\")\n     value(\"\\$.object_attributes.target.path_with_namespace\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MERGE_REQUST_IID\")\n     value(\"\\$.object_attributes.iid\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MR_OBJECT_KIND\")\n     value(\"\\$.object_kind\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MR_OLD_REV\")\n     value(\"\\$.object_attributes.oldrev\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MR_ACTION\")\n     value(\"\\$.object_attributes.action\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n    genericVariable {\n     key(\"MR_TITLE\")\n     value(\"\\$.object_attributes.title\")\n     expressionType(\"JSONPath\")\n     regexpFilter(\"\")\n    }\n   }\n   regexpFilterText(\"\\$MR_OBJECT_KIND \\$MR_ACTION \\$MR_OLD_REV\")\n   regexpFilterExpression(\"^merge_request\\\\s(update\\\\s.{40}\\$|open.*)\")\n  }\n }\n \n definition {\n  cps {\n   script(readFileFromWorkspace('merge_request_pipeline.pipeline'))\n   sandbox()\n  }\n }\n}\n```\n\nAnd the merge_request_pipeline.pipeline contains\n```groovy\ndef commentMr(projectId, mergeRequestIid, comment) {\n def body = comment\n .replaceAll(\" \",\"%20\")\n .replaceAll(\"/\",\"%2F\")\n def project = projectId\n .replaceAll(\"/\",\"%2F\")\n sh \"curl http://gitlab:80/api/v4/projects/$project/merge_requests/$mergeRequestIid/notes -H 'PRIVATE-TOKEN: 6xRcmSzPzzEXeS2qqr7R' -X POST -d \\\"body=\"+body+\"\\\"\"\n}\n  \nnode {\n deleteDir()\n currentBuild.description = \"$MR_TITLE from $MERGE_REQUEST_FROM_BRANCH to $MERGE_REQUEST_TO_BRANCH\"\n  \n commentMr(env.PROJECT_PATH,env.MERGE_REQUST_IID,\"Verifierar $MERGE_REQUEST_FROM_BRANCH... ${env.BUILD_URL}\")\n  \n stage('Merge') {\n  sh \"git init\"\n  sh \"git fetch --no-tags $MERGE_REQUEST_TO_URL +refs/heads/*:refs/remotes/origin/* --depth=200\"\n  sh \"git checkout origin/${env.MERGE_REQUEST_TO_BRANCH}\"\n  sh \"git config user.email 'je@nkins.domain'\"\n  sh \"git config user.name 'jenkins'\"\n  sh \"git merge origin/${env.MERGE_REQUEST_FROM_BRANCH}\"\n  sh \"git log --graph --abbrev-commit --max-count=10\"\n }\n  \n stage('Compile') {\n  sh \"./gradlew assemble\"\n }\n  \n stage('Unit test') {\n  sh \"./gradlew test\"\n  commentMr(env.PROJECT_PATH,env.MERGE_REQUST_IID,\"Test ok in $MERGE_REQUEST_FROM_BRANCH =) ${env.BUILD_URL}\")\n }\n  \n stage('Regression test') {\n  sh \"echo regtest\"\n  commentMr(env.PROJECT_PATH,env.MERGE_REQUST_IID,\"Regression test ok in $MERGE_REQUEST_FROM_BRANCH =) ${env.BUILD_URL}\")\n }\n  \n stage('Static code analysis') {\n sh \"./gradlew check\"\n step([\n $class: 'ViolationsToGitLabRecorder',\n config: [\n  gitLabUrl: 'http://gitlab:80/',\n  projectId: env.PROJECT_PATH,\n  mergeRequestIid: env.MERGE_REQUST_IID,\n  commentOnlyChangedContent: true,\n  commentOnlyChangedContentContext: 0,\n  commentOnlyChangedFiles: true,\n  createSingleFileComments: true,\n  createCommentWithAllSingleFileComments: true,\n  minSeverity: 'INFO',\n  maxNumberOfViolations: 99999,\n \n  // You may want this when troubleshooting things\n  enableLogging: true,\n \n  // Only specify proxy if you need it\n  proxyUri: '',\n  proxyCredentialsId: '', // A username/password credential\n \n  apiTokenCredentialsId: 'id', // A secret text credential\n  apiTokenPrivate: true,\n  authMethodHeader: true,\n  ignoreCertificateErrors: true,\n  keepOldComments: false,\n  shouldSetWip: true,\n \n  commentTemplate: \"\"\"\n **Reporter**: {{violation.reporter}}{{#violation.rule}}\n \n **Rule**: {{violation.rule}}{{/violation.rule}}\n **Severity**: {{violation.severity}}\n **File**: {{violation.file}} L{{violation.startLine}}{{#violation.source}}\n \n **Source**: {{violation.source}}{{/violation.source}}\n \n {{violation.message}}\n  \"\"\",\n \n  violationConfigs: [\n   [ pattern: '.*/checkstyle/.*\\\\.xml$', parser: 'CHECKSTYLE', reporter: 'Checkstyle' ],\n   [ pattern: '.*/findbugs/.*\\\\.xml$', parser: 'FINDBUGS', reporter: 'Findbugs' ],\n   [ pattern: '.*/pmd/.*\\\\.xml$', parser: 'PMD', reporter: 'PMD' ],\n  ]\n ]\n ])\n }\n}\n```\n\n# Encoding\n\nThe `commentTemplate` parameter can be used to fix encoding problems, or just adjust what is being commented. [See README in violation-comments-lib](https://github.com/tomasbjerre/violation-comments-lib).\n\n# Plugin development\nMore details on Jenkins plugin development is available [here](https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial).\n\nThere is a ```/build.sh``` that will perform a full build and test the plugin.\n\nIf you have release-permissions this is how you do a release:\n\n```\nmvn release:prepare release:perform\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenkinsci%2Fviolation-comments-to-gitlab-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjenkinsci%2Fviolation-comments-to-gitlab-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenkinsci%2Fviolation-comments-to-gitlab-plugin/lists"}