├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── jenkins-security-scan.yml ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CHANGELOG.md ├── ISSUE_TEMPLATE ├── Jenkinsfile ├── LICENSE ├── README.md ├── debug.sh ├── logging.properties ├── mvnw ├── mvnw.cmd ├── pom.xml ├── release.sh ├── run.sh ├── sandbox ├── gitlab-comment-diff.png ├── gitlab-mergerequest-comment.json ├── gitlab-mergerequest-push.json ├── gitlab.com.testpipeline.jenkinsfile ├── hints.txt ├── mergerequest-onecomment.png └── settings.xml └── src ├── main ├── java │ └── org │ │ └── jenkinsci │ │ └── plugins │ │ └── jvctgl │ │ ├── ViolationsToGitLabDescriptor.java │ │ ├── ViolationsToGitLabGlobalConfiguration.java │ │ ├── ViolationsToGitLabRecorder.java │ │ ├── config │ │ ├── CredentialsHelper.java │ │ ├── ViolationConfig.java │ │ ├── ViolationsToGitLabConfig.java │ │ └── ViolationsToGitLabConfigHelper.java │ │ └── perform │ │ └── JvctglPerformer.java ├── resources │ ├── index.jelly │ └── org │ │ └── jenkinsci │ │ └── plugins │ │ └── jvctgl │ │ ├── ViolationsToGitLabGlobalConfiguration │ │ ├── config.jelly │ │ └── help.html │ │ ├── ViolationsToGitLabRecorder │ │ ├── config.jelly │ │ └── help.html │ │ └── config │ │ ├── ViolationConfig │ │ └── config.jelly │ │ └── ViolationsToGitLabConfig │ │ └── config.jelly └── webapp │ └── findbugs │ └── messages.xml └── test └── java ├── org └── jenkinsci │ └── plugins │ └── jvctgl │ ├── config │ └── ViolationsToGitLabConfigTest.java │ └── perform │ └── JvctglPerformerTest.java └── se └── bjurr └── violations └── UpdateReadmeTest.java /.gitattributes: -------------------------------------------------------------------------------- 1 | *.java text eol=lf 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [tomasbjerre] 2 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-security-scan.yml: -------------------------------------------------------------------------------- 1 | name: Jenkins Security Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | types: [ opened, synchronize, reopened ] 9 | workflow_dispatch: 10 | 11 | permissions: 12 | security-events: write 13 | contents: read 14 | actions: read 15 | 16 | jobs: 17 | security-scan: 18 | uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 19 | with: 20 | java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. 21 | # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.versionsBackup 2 | .factorypath 3 | pom.xml.releaseBackup 4 | release.properties 5 | target 6 | .project 7 | .settings 8 | .classpath 9 | *.class 10 | *.log 11 | *.bak 12 | *~ 13 | work* 14 | bin 15 | gradle 16 | gradlew 17 | .gradle 18 | build 19 | .okhttpcache 20 | .idea/ 21 | *iml 22 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/violation-comments-to-gitlab-plugin/cece529c8bf429d6151c279b592489413954afe1/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # violation-comments-to-gitlab-plugin changelog 2 | 3 | Changelog of violation-comments-to-gitlab-plugin. 4 | 5 | ## 2.62.0 (2024-03-24) 6 | 7 | ### Features 8 | 9 | - coverity ([70ec5](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/70ec557513b4057) Tomas Bjerre) 10 | 11 | ## 2.61.1 (2024-03-02) 12 | 13 | ### Other changes 14 | 15 | **docs** 16 | 17 | 18 | [f92c3](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/f92c3637bd94131) Tomas Bjerre *2024-03-02 07:51:02* 19 | 20 | 21 | ## 2.61 (2024-03-02) 22 | 23 | ### Bug Fixes 24 | 25 | - stepping client to gitlab4j-api:5.5.0 ([00c92](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/00c926389d0dee3) Tomas Bjerre) 26 | 27 | ### Other changes 28 | 29 | **docs** 30 | 31 | 32 | [cf110](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/cf110ddb313745f) Tomas Bjerre *2024-03-02 07:47:36* 33 | 34 | 35 | ## 2.60 (2023-09-17) 36 | 37 | ### Bug Fixes 38 | 39 | - allow MSBuild in Program Files (x86) and support NU1701 ([7a838](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7a83889a9c76ff7) Tomas Bjerre) 40 | 41 | ### Other changes 42 | 43 | **Update README.md** 44 | 45 | 46 | [26a7e](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/26a7ec15e1bba63) Tomas Bjerre *2023-07-30 19:51:26* 47 | 48 | 49 | ## 2.59 (2023-03-26) 50 | 51 | ### Features 52 | 53 | - stepping violations-lib ([17f73](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/17f73e56ba9f89e) Tomas Bjerre) 54 | 55 | ## 2.58 (2023-03-11) 56 | 57 | ### Features 58 | 59 | - replacing Mustache with Handlebars ([38dfa](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/38dfaab0af02e11) Tomas Bjerre) 60 | 61 | ## 2.57 (2023-01-19) 62 | 63 | ### Features 64 | 65 | - semgrep parser ([36eb0](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/36eb090ee8006ad) Tomas Bjerre) 66 | 67 | ## 2.56 (2023-01-16) 68 | 69 | ### Features 70 | 71 | - ansible-later parser ([80017](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/80017793bc5b6f2) Tomas Bjerre) 72 | 73 | ## 2.55 (2022-05-22) 74 | 75 | ### Features 76 | 77 | - favoring mardown from sarif reports ([6c76e](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/6c76ec93f72e47a) Tomas Bjerre) 78 | 79 | ## 2.54 (2022-05-07) 80 | 81 | ### Features 82 | 83 | - Introduce Java-11 builds. ([ddc56](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/ddc56e838c169b2) Alexander Falkenstern) 84 | - stepping lib versions ([917e2](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/917e2a71a4649e8) Alexander Falkenstern) 85 | 86 | ### Other changes 87 | 88 | **Merge pull request #34 from falkena/feature/BumpRevisions** 89 | 90 | * feat: stepping lib versions 91 | 92 | [5df37](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5df3715aee1cf75) Tomas Bjerre *2022-05-07 14:08:18* 93 | 94 | 95 | ## 2.53 (2022-03-27) 96 | 97 | ### Features 98 | 99 | - stepping lib versions ([6186b](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/6186bbf3d45d5c9) Tomas Bjerre) 100 | 101 | ## 2.52 (2021-09-11) 102 | 103 | ### Bug Fixes 104 | 105 | - mapping engine_name and check_name in CodeClimate ([7d25a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7d25adea72a35d1) Tomas Bjerre) 106 | 107 | ## 2.51 (2021-08-02) 108 | 109 | ### Other changes 110 | 111 | **jacoco** 112 | 113 | 114 | [e422f](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/e422f0bf2403607) Tomas Bjerre *2021-08-02 16:12:47* 115 | 116 | **stepping violations lib** 117 | 118 | 119 | [f564a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/f564aae4468f81d) Tomas Bjerre *2021-08-02 16:12:07* 120 | 121 | 122 | ## 2.49 (2021-07-06) 123 | 124 | ### Other changes 125 | 126 | **Merge pull request #32 from ateglas/issue-15** 127 | 128 | * Giving access to the commentOnlyChangedContentContext parameter 129 | 130 | [7ce38](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7ce384128406607) Tomas Bjerre *2021-07-06 04:58:16* 131 | 132 | **Giving access to the commentOnlyChangedContentContext parameter** 133 | 134 | 135 | [7cbdf](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7cbdf2565be1ea0) Aurelian Teglas *2021-07-05 18:02:55* 136 | 137 | 138 | ## 2.48 (2021-07-03) 139 | 140 | ### Bug Fixes 141 | 142 | - Added test cases and fix for large new files ([63f10](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/63f10759f917013) Tomas Bjerre) 143 | 144 | ## 2.47 (2021-06-16) 145 | 146 | ### Features 147 | 148 | - MSBuild parser ([2907e](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/2907ecc76e727a9) Tomas Bjerre) 149 | 150 | ### Other changes 151 | 152 | **doc** 153 | 154 | 155 | [f17a2](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/f17a296512f4471) Tomas Bjerre *2021-01-23 17:40:16* 156 | 157 | 158 | ## 2.46 (2021-01-23) 159 | 160 | ### Other changes 161 | 162 | **Correcting pipeline syntax generator #29** 163 | 164 | 165 | [230c6](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/230c615eb0105ee) Tomas Bjerre *2021-01-23 17:36:19* 166 | 167 | 168 | ## 2.45 (2020-12-14) 169 | 170 | ### Other changes 171 | 172 | **Correctings in patchparsing tomasbjerre/violations-lib#117** 173 | 174 | 175 | [742b3](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/742b399c86631da) Tomas Bjerre *2020-12-14 15:10:16* 176 | 177 | **Spotbugs report** 178 | 179 | 180 | [240ec](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/240ec6a51a29fbf) Tomas Bjerre *2020-09-27 17:32:19* 181 | 182 | 183 | ## 2.44 (2020-09-27) 184 | 185 | ### Other changes 186 | 187 | **Find Security Bugs messages** 188 | 189 | 190 | [5e28d](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5e28dd147a34c95) Tomas Bjerre *2020-09-27 17:28:20* 191 | 192 | **Merge pull request #27 from timja/patch-1** 193 | 194 | * Remove unneeded configuration in buildPlugin 195 | 196 | [68370](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/683705f04a5b573) Tomas Bjerre *2020-07-26 06:27:57* 197 | 198 | **Remove unneeded configuration in buildPlugin** 199 | 200 | * Spotbugs reporting is being enabled by default in https://github.com/jenkins-infra/pipeline-library/pull/121, update to parent pom 4.x to use spotbugs instead of findbugs. 201 | 202 | [25093](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/25093f6449cc9c4) Tim Jacomb *2020-07-25 14:42:25* 203 | 204 | 205 | ## 2.43 (2020-07-05) 206 | 207 | ## 2.42 (2020-05-20) 208 | 209 | ### Other changes 210 | 211 | **Fixing SECURITY-1854** 212 | 213 | 214 | [05a72](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/05a72d36f15ce8b) Tomas Bjerre *2020-05-20 14:48:21* 215 | 216 | 217 | ## 2.41 (2020-05-12) 218 | 219 | ## 2.40 (2020-04-28) 220 | 221 | ### Other changes 222 | 223 | **gitlab4j-api 4.12.3 -> 4.14.27 jenkinsci/violation-comments-to-gitlab-plugin#26** 224 | 225 | 226 | [118c3](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/118c37c2dcddece) Tomas Bjerre *2020-04-28 17:58:37* 227 | 228 | 229 | ## 2.39 (2020-02-03) 230 | 231 | ### Other changes 232 | 233 | **CPPCheckParser with auto closed tags tomasbjerre/violations-lib#82** 234 | 235 | 236 | [d8e6a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/d8e6a17274a0b13) Tomas Bjerre *2020-02-03 16:46:22* 237 | 238 | 239 | ## 2.38 (2020-01-03) 240 | 241 | ### Other changes 242 | 243 | **Add support for sonar issue report formats >= v7.5 tomasbjerre/violations-lib#80** 244 | 245 | 246 | [5537c](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5537cfaa1145bfd) Tomas Bjerre *2020-01-03 07:46:46* 247 | 248 | 249 | ## 2.37 (2019-10-24) 250 | 251 | ### Other changes 252 | 253 | **Setting URL to README.md to update plugins.jenkins.io** 254 | 255 | 256 | [68701](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/68701aaba373c97) Tomas Bjerre *2019-10-24 18:44:16* 257 | 258 | 259 | ## 2.36 (2019-10-22) 260 | 261 | ### Other changes 262 | 263 | **Protolint tomasbjerre/violations-lib#79** 264 | 265 | 266 | [7052c](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7052cc0d12d16c5) Tomas Bjerre *2019-10-22 03:28:26* 267 | 268 | 269 | ## 2.35 (2019-10-14) 270 | 271 | ### Other changes 272 | 273 | **Merge pull request #25 from jenkinsci/feature/hadolint** 274 | 275 | * Correcting ReSharper och PyDocStyle 276 | 277 | [17e2e](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/17e2e8d8be75988) Tomas Bjerre *2019-10-14 15:44:42* 278 | 279 | **Correcting ReSharper och PyDocStyle** 280 | 281 | 282 | [c6e0c](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/c6e0c8dacd25192) Tomas Bjerre *2019-10-14 15:43:29* 283 | 284 | 285 | ## 2.33 (2019-10-09) 286 | 287 | ### Other changes 288 | 289 | **Avoiding NPE when getting diff_refs #23** 290 | 291 | 292 | [3f7cd](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/3f7cd7020a1f10a) Tomas Bjerre *2019-10-09 18:46:03* 293 | 294 | 295 | ## 2.32 (2019-10-08) 296 | 297 | ### Other changes 298 | 299 | **Clearer error message when diffRefs null #23** 300 | 301 | 302 | [3318b](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/3318b39fdac0c8b) Tomas Bjerre *2019-10-08 13:51:45* 303 | 304 | **Merge pull request #24 from daniel-beck-bot/https-urls-pom** 305 | 306 | * Use HTTPS URLs in pom.xml 307 | 308 | [8bdfc](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/8bdfc581d09b037) Tomas Bjerre *2019-10-08 11:47:18* 309 | 310 | **Use HTTPS URLs in pom.xml** 311 | 312 | 313 | [2a5b9](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/2a5b903c57b9ed0) Daniel Beck *2019-10-08 11:12:55* 314 | 315 | **Create FUNDING.yml** 316 | 317 | 318 | [210bb](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/210bbef9c33cd39) Tomas Bjerre *2019-09-28 06:52:46* 319 | 320 | 321 | ## 2.31 (2019-09-14) 322 | 323 | ### Other changes 324 | 325 | **Doc** 326 | 327 | 328 | [8937d](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/8937db2fd0a315c) Tomas Bjerre *2019-09-14 16:52:01* 329 | 330 | 331 | ## 2.30 (2019-09-14) 332 | 333 | ### Other changes 334 | 335 | **Removing raw proxy username/password forcing credentials** 336 | 337 | * SECURITY-1577 338 | 339 | [76ee6](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/76ee602dc529706) Tomas Bjerre *2019-09-14 07:58:30* 340 | 341 | 342 | ## 2.29 (2019-09-13) 343 | 344 | ### Other changes 345 | 346 | **Removing raw API Token and forcing credential** 347 | 348 | * In a pipeline you can no longer do `apiToken: 'asd'` and will have to do `apiTokenCredentialsId: 'id'`. 349 | * SECURITY-1577 350 | 351 | [e8237](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/e8237a803012bae) Tomas Bjerre *2019-09-13 19:00:13* 352 | 353 | 354 | ## 2.28 (2019-09-04) 355 | 356 | ### Other changes 357 | 358 | **Correcting Sonar-parser when severity missing** 359 | 360 | 361 | [6f5be](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/6f5be3ffa0d3a96) Tomas Bjerre *2019-09-04 19:35:37* 362 | 363 | 364 | ## 2.26 (2019-06-16) 365 | 366 | ### Other changes 367 | 368 | **commentOnlyChangedFiles** 369 | 370 | 371 | [df613](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/df61346ce397ce5) Tomas Bjerre *2019-06-16 17:55:05* 372 | 373 | **doc** 374 | 375 | 376 | [4d1e1](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/4d1e161f87cdd97) Tomas Bjerre *2019-06-13 14:43:32* 377 | 378 | 379 | ## 2.25 (2019-04-24) 380 | 381 | ### Other changes 382 | 383 | **Cpplint correction to handle line None** 384 | 385 | 386 | [871ab](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/871ab05fb62592b) Tomas Bjerre *2019-04-24 15:58:35* 387 | 388 | 389 | ## 2.24 (2019-03-31) 390 | 391 | ### Other changes 392 | 393 | **maxNumberOfViolations** 394 | 395 | 396 | [821f2](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/821f2807e070a49) Tomas Bjerre *2019-03-31 12:22:45* 397 | 398 | 399 | ## 2.23 (2019-03-30) 400 | 401 | ### Other changes 402 | 403 | **Correcting Sonar severity** 404 | 405 | 406 | [5d70c](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5d70cb6adbd5500) Tomas Bjerre *2019-03-30 06:08:22* 407 | 408 | 409 | ## 2.22 (2019-03-23) 410 | 411 | ### Other changes 412 | 413 | **Sonar Report** 414 | 415 | 416 | [b1148](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/b1148a048103e37) Tomas Bjerre *2019-03-23 14:39:17* 417 | 418 | 419 | ## 2.21 (2019-03-13) 420 | 421 | ### Other changes 422 | 423 | **Klocwork line numbers** 424 | 425 | 426 | [27dd1](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/27dd19b212cc2b7) Tomas Bjerre *2019-03-13 19:19:57* 427 | 428 | 429 | ## 2.20 (2019-03-07) 430 | 431 | ### Other changes 432 | 433 | **golangci-lint** 434 | 435 | 436 | [33e72](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/33e722a77cd0442) Tomas Bjerre *2019-03-07 16:28:28* 437 | 438 | 439 | ## 2.19 (2019-03-05) 440 | 441 | ### Other changes 442 | 443 | **Allowing logging to be disabled #20** 444 | 445 | 446 | [1b2d6](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/1b2d68cf770beb8) Tomas Bjerre *2019-03-05 12:02:16* 447 | 448 | 449 | ## 2.18 (2019-03-04) 450 | 451 | ### Other changes 452 | 453 | **Proxy support #17** 454 | 455 | 456 | [dab37](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/dab372c83a52501) Tomas Bjerre *2019-03-04 17:10:24* 457 | 458 | **Doc** 459 | 460 | 461 | [012d4](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/012d46c0fd844ce) Tomas Bjerre *2019-02-08 19:02:26* 462 | 463 | 464 | ## 2.17 (2019-01-29) 465 | 466 | ### Other changes 467 | 468 | **MSCPP and IAR** 469 | 470 | 471 | [134ca](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/134cabe32aca09b) Tomas Bjerre *2019-01-29 17:28:23* 472 | 473 | 474 | ## 2.16 (2019-01-14) 475 | 476 | ### Other changes 477 | 478 | **Avoiding faulty slash with CodeNarc** 479 | 480 | 481 | [8c352](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/8c3524df918fff5) Tomas Bjerre *2019-01-14 17:53:21* 482 | 483 | 484 | ## 2.15 (2019-01-09) 485 | 486 | ### Other changes 487 | 488 | **Making CodeNarc respect source directory** 489 | 490 | 491 | [5a965](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5a965cbe34ba401) Tomas Bjerre *2019-01-09 19:53:08* 492 | 493 | 494 | ## 2.14 (2019-01-03) 495 | 496 | ### Other changes 497 | 498 | **Correcting AnsibleLint parsing** 499 | 500 | 501 | [0f30f](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/0f30fdc2de2e2c0) Tomas Bjerre *2019-01-03 17:42:38* 502 | 503 | 504 | ## 2.13 (2018-10-08) 505 | 506 | ### Other changes 507 | 508 | **Avoid NPE when commenting diff** 509 | 510 | 511 | [32be7](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/32be727bb879acc) Tomas Bjerre *2018-10-08 17:33:05* 512 | 513 | 514 | ## 2.12 (2018-10-07) 515 | 516 | ### Other changes 517 | 518 | **Support commenting on diff #1** 519 | 520 | 521 | [cf469](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/cf469bb3d8b0e0e) Tomas Bjerre *2018-10-07 14:08:52* 522 | 523 | **Automatically stepping dependencies** 524 | 525 | 526 | [31bc8](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/31bc850d83cc32e) Tomas Bjerre *2018-09-23 19:05:37* 527 | 528 | 529 | ## 2.11 (2018-09-23) 530 | 531 | ### Other changes 532 | 533 | **Clarifying parsers** 534 | 535 | 536 | [4b3bc](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/4b3bc79ff2c29c2) Tomas Bjerre *2018-09-23 13:38:10* 537 | 538 | **Automating reporters in readme** 539 | 540 | 541 | [a1389](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/a1389d2f25b299a) Tomas Bjerre *2018-09-23 12:58:32* 542 | 543 | **Doc** 544 | 545 | 546 | [52529](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/52529caeb5b81d6) Tomas Bjerre *2018-09-22 18:21:14* 547 | 548 | 549 | ## 2.10 (2018-09-22) 550 | 551 | ### Other changes 552 | 553 | **Avoid java-gitlab-api bug to spam logs with exception #3** 554 | 555 | 556 | [1f0bf](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/1f0bf0afcf93af7) Tomas Bjerre *2018-09-22 17:03:11* 557 | 558 | **Documenting parsers as a table** 559 | 560 | 561 | [6a062](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/6a06250d3afab0d) Tomas Bjerre *2018-09-22 08:46:28* 562 | 563 | 564 | ## 2.9 (2018-09-21) 565 | 566 | ### Other changes 567 | 568 | **Correcting Kotlin parsers** 569 | 570 | 571 | [0b9dc](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/0b9dc8349ce97e9) Tomas Bjerre *2018-09-20 23:59:00* 572 | 573 | 574 | ## 2.8 (2018-09-20) 575 | 576 | ### Other changes 577 | 578 | **Kotlin Maven and Gradle parsers** 579 | 580 | 581 | [2492d](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/2492ddd6dd6d885) Tomas Bjerre *2018-09-20 14:25:28* 582 | 583 | 584 | ## 2.7 (2018-09-18) 585 | 586 | ### Other changes 587 | 588 | **Exception logging in build job log** 589 | 590 | 591 | [fd368](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/fd36871f2baa0ac) Tomas Bjerre *2018-09-18 18:58:47* 592 | 593 | 594 | ## 2.6 (2018-09-18) 595 | 596 | ### Other changes 597 | 598 | **More information in log** 599 | 600 | 601 | [94249](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/942494eb055d547) Tomas Bjerre *2018-09-18 10:07:33* 602 | 603 | **Issue template** 604 | 605 | 606 | [e42c8](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/e42c8be70ba2283) Tomas Bjerre *2018-09-17 17:01:06* 607 | 608 | 609 | ## 2.5 (2018-09-17) 610 | 611 | ### Other changes 612 | 613 | **Fix optional rule in YAMLLint** 614 | 615 | 616 | [a377f](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/a377fe3c89daf3c) Tomas Bjerre *2018-09-17 13:42:06* 617 | 618 | 619 | ## 2.4 (2018-09-15) 620 | 621 | ### Other changes 622 | 623 | **YAMLLint** 624 | 625 | 626 | [15611](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/15611403072863a) Tomas Bjerre *2018-09-15 08:23:05* 627 | 628 | 629 | ## 2.3 (2018-09-13) 630 | 631 | ### Other changes 632 | 633 | **Correcting ownerName and CPD** 634 | 635 | 636 | [8820c](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/8820c490992f5fa) Tomas Bjerre *2018-09-13 05:20:53* 637 | 638 | **Updating readme with parsers** 639 | 640 | 641 | [bdc23](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/bdc23b97cf24813) Tomas Bjerre *2018-09-12 17:08:18* 642 | 643 | **Updating fmt-maven-plugin** 644 | 645 | 646 | [904e3](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/904e31377cd6552) Tomas Bjerre *2018-08-30 17:50:22* 647 | 648 | **Using java-gitlab-api from Central** 649 | 650 | 651 | [deb0d](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/deb0d8db45be051) Tomas Bjerre *2018-08-29 18:04:25* 652 | 653 | 654 | ## 2.2 (2018-07-04) 655 | 656 | ### Other changes 657 | 658 | **GCC, ARM GCC and Doxygen** 659 | 660 | 661 | [ef01e](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/ef01edce558aabd) Tomas Bjerre *2018-07-04 18:30:30* 662 | 663 | 664 | ## 2.1 (2018-07-04) 665 | 666 | ### Other changes 667 | 668 | **Custom template** 669 | 670 | 671 | [3e4c6](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/3e4c660b1aff27a) Tomas Bjerre *2018-07-04 11:49:40* 672 | 673 | **Correcting license** 674 | 675 | 676 | [939fa](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/939fa35d9c7d295) Tomas Bjerre *2018-06-21 17:21:42* 677 | 678 | **License** 679 | 680 | 681 | [7a2a4](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7a2a48bb72d193f) Tomas Bjerre *2018-06-14 15:27:59* 682 | 683 | 684 | ## 2.0 (2018-04-22) 685 | 686 | ### Other changes 687 | 688 | **Changing mergeRequestId to mergeRequestIid** 689 | 690 | * Because it is named wrong in the Java GitLab API Lib! 691 | * This breaks API for Pipelines. 692 | 693 | [5a9db](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5a9db9a63559fc6) Tomas Bjerre *2018-04-22 16:53:45* 694 | 695 | **NullAway #33** 696 | 697 | 698 | [79786](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/79786fa2ccb5111) Tomas Bjerre *2018-04-14 05:16:48* 699 | 700 | 701 | ## 1.28 (2018-02-27) 702 | 703 | ### Other changes 704 | 705 | **Looking for credentials with the id** 706 | 707 | 708 | [13e8e](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/13e8e54325c3731) Tomas Bjerre *2018-02-27 18:09:50* 709 | 710 | **Merge pull request #12 from casz/master** 711 | 712 | * Provide item context 713 | 714 | [ebb9a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/ebb9a4223c0b6f5) Tomas Bjerre *2018-02-27 17:51:56* 715 | 716 | **Styles** 717 | 718 | 719 | [6d6a2](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/6d6a2d5657e1855) Joseph Petersen *2018-02-24 20:22:08* 720 | 721 | **Remove unused code** 722 | 723 | 724 | [ecdba](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/ecdba0af35cbcae) Joseph Petersen *2018-02-24 20:17:05* 725 | 726 | **provide credentials item** 727 | 728 | 729 | [c8a74](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/c8a743162a4cc24) Joseph Petersen *2018-02-24 20:16:48* 730 | 731 | **Javax nonnull is bad due to licensing** 732 | 733 | 734 | [cf998](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/cf99843f1e86f34) Joseph Petersen *2018-02-24 20:03:54* 735 | 736 | **avoid commit nightmare on windows due to formatter** 737 | 738 | 739 | [3f250](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/3f2508ff48a1072) Joseph Petersen *2018-02-24 20:03:54* 740 | 741 | **ignore .idea** 742 | 743 | 744 | [2e6d9](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/2e6d99125a783a0) Joseph Petersen *2018-02-24 20:03:54* 745 | 746 | **Merge pull request #11 from casz/patch-1** 747 | 748 | * Update Jenkinsfile 749 | 750 | [e5d92](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/e5d925ef1066d50) Tomas Bjerre *2018-02-24 18:20:26* 751 | 752 | **Update Jenkinsfile** 753 | 754 | 755 | [e4016](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/e40160cb454776b) Joseph Petersen *2018-02-24 15:12:29* 756 | 757 | 758 | ## 1.27 (2018-02-22) 759 | 760 | ### Other changes 761 | 762 | **Avoid need to save global config before use #10** 763 | 764 | 765 | [facbb](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/facbbea73c6f76b) Tomas Bjerre *2018-02-22 19:37:11* 766 | 767 | 768 | ## 1.26 (2018-02-13) 769 | 770 | ### Other changes 771 | 772 | **PCLint** 773 | 774 | 775 | [7249a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7249ae415f3853d) Tomas Bjerre *2018-02-13 20:13:26* 776 | 777 | 778 | ## 1.25 (2018-02-13) 779 | 780 | ### Other changes 781 | 782 | **PCLint** 783 | 784 | 785 | [9a5ad](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/9a5adfb19a4625d) Tomas Bjerre *2018-02-13 19:21:08* 786 | 787 | 788 | ## 1.24 (2018-01-28) 789 | 790 | ### Other changes 791 | 792 | **Refactoring** 793 | 794 | 795 | [669fc](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/669fc52d95825cc) Tomas Bjerre *2018-01-28 15:03:42* 796 | 797 | **Jenkinsfile** 798 | 799 | 800 | [22f12](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/22f12c73e6e44ce) Tomas Bjerre *2018-01-27 18:32:50* 801 | 802 | 803 | ## 1.23 (2018-01-14) 804 | 805 | ### Other changes 806 | 807 | **Google error-prone** 808 | 809 | 810 | [a42ac](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/a42ac995850c8c1) Tomas Bjerre *2018-01-14 12:04:31* 811 | 812 | 813 | ## 1.22 (2017-12-31) 814 | 815 | ### Other changes 816 | 817 | **Relocating to correct Java identifier** 818 | 819 | 820 | [6becb](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/6becb07178f0ec4) Tomas Bjerre *2017-12-31 11:58:55* 821 | 822 | 823 | ## 1.20 (2017-12-25) 824 | 825 | ### Other changes 826 | 827 | **Fixing encoding issues** 828 | 829 | 830 | [3e2af](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/3e2af04b327f268) Tomas Bjerre *2017-12-25 20:01:30* 831 | 832 | **Bumping version to fix faulty release** 833 | 834 | 835 | [73dd2](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/73dd2806c3ec2c1) Tomas Bjerre *2017-12-22 19:56:13* 836 | 837 | 838 | ## 1.19 (2017-12-22) 839 | 840 | ### Other changes 841 | 842 | **DocFX parsing JSON with Gson, not ScriptEngine** 843 | 844 | 845 | [449b3](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/449b39057ee5687) Tomas Bjerre *2017-12-22 12:57:39* 846 | 847 | 848 | ## 1.18 (2017-12-21) 849 | 850 | ### Other changes 851 | 852 | **DocFX** 853 | 854 | 855 | [04057](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/04057d3c556f9e9) Tomas Bjerre *2017-12-21 15:00:37* 856 | 857 | 858 | ## 1.17 (2017-12-07) 859 | 860 | ### Other changes 861 | 862 | **Accepting PMD files without ruleset-tag** 863 | 864 | 865 | [ab716](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/ab716dd2c83d527) Tomas Bjerre *2017-12-07 16:13:04* 866 | 867 | **Doc** 868 | 869 | 870 | [15b40](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/15b4097739a44c5) Tomas Bjerre *2017-11-18 13:50:20* 871 | 872 | 873 | ## 1.16 (2017-11-01) 874 | 875 | ### Other changes 876 | 877 | **Better error message if project cannot be found #8** 878 | 879 | 880 | [88c48](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/88c4817400b182a) Tomas Bjerre *2017-11-01 18:49:22* 881 | 882 | 883 | ## 1.15 (2017-10-13) 884 | 885 | ### Other changes 886 | 887 | **Resharper WikiUrl** 888 | 889 | 890 | [1fd31](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/1fd3145fcd48d2e) Tomas Bjerre *2017-10-13 11:35:09* 891 | 892 | 893 | ## 1.14 (2017-10-09) 894 | 895 | ### Other changes 896 | 897 | **Added handling for empty IssueType Description attributes for Resharper** 898 | 899 | 900 | [854f6](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/854f6f787a0a52a) Tomas Bjerre *2017-10-09 16:58:00* 901 | 902 | 903 | ## 1.13 (2017-09-26) 904 | 905 | ### Other changes 906 | 907 | **Allowing reporter to be unset** 908 | 909 | 910 | [48ade](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/48ade8a79d4e978) Tomas Bjerre *2017-09-26 19:44:30* 911 | 912 | **Doc** 913 | 914 | 915 | [085c5](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/085c5b5751e5b8e) Tomas Bjerre *2017-09-03 08:13:59* 916 | 917 | 918 | ## 1.12 (2017-09-02) 919 | 920 | ### Other changes 921 | 922 | **Keeping comments and adjusting checkstyle** 923 | 924 | * Checkstyle now allows empty source attribute. 925 | * Comments can optionaly be kept and not removed when new comments are added. 926 | * Will no longer re-create identical comments. 927 | * Using API V4 928 | 929 | [3ec3b](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/3ec3b9a97663a01) Tomas Bjerre *2017-09-02 14:49:39* 930 | 931 | **Keeping comments and adjusting checkstyle** 932 | 933 | * Checkstyle now allows empty source attribute. 934 | * Comments can optionaly be kept and not removed when new comments are added. 935 | * Will no longer re-create identical comments. 936 | * Using GitLab API V4 937 | 938 | [5780a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5780a2457e06631) Tomas Bjerre *2017-09-02 09:30:44* 939 | 940 | 941 | ## 1.11 (2017-08-11) 942 | 943 | ### Other changes 944 | 945 | **Ignoring violation configs with null config** 946 | 947 | 948 | [5f8c9](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5f8c94518aeaf9a) Tomas Bjerre *2017-08-11 11:36:58* 949 | 950 | 951 | ## 1.10 (2017-08-11) 952 | 953 | ### Other changes 954 | 955 | **Ignoring violation configs with null config** 956 | 957 | 958 | [b6720](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/b6720937a4c1e04) Tomas Bjerre *2017-08-11 11:35:05* 959 | 960 | **Cleaning** 961 | 962 | 963 | [8db36](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/8db36c5d2049ae4) Tomas Bjerre *2017-07-20 19:33:33* 964 | 965 | **doc** 966 | 967 | 968 | [cf45a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/cf45a5aa041e3c8) Tomas Bjerre *2017-07-15 13:11:30* 969 | 970 | 971 | ## 1.9 (2017-07-15) 972 | 973 | ### Other changes 974 | 975 | **Bugfix, were unable to save reporter from GUI** 976 | 977 | 978 | [ad870](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/ad8703d0989ca57) Tomas Bjerre *2017-07-15 13:09:22* 979 | 980 | 981 | ## 1.8 (2017-07-15) 982 | 983 | ### Other changes 984 | 985 | **Violations-lib 1.29 with reporter field** 986 | 987 | * This breaks backwards compatibilty a bit. Reporter is renamed to Parser and an optional text-field called reporter is introduced. If something like Detekt is used to produce a checkstyle-report, then reporter can be set to Detekt and the parser set to CHECKSTYLE. 988 | 989 | [82057](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/820577dd8dc4546) Tomas Bjerre *2017-07-15 07:54:40* 990 | 991 | **Updating doc on Infer** 992 | 993 | 994 | [93bc6](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/93bc67d232b2521) Tomas Bjerre *2017-06-23 12:53:38* 995 | 996 | **doc** 997 | 998 | 999 | [1869d](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/1869d23af48a0f1) Tomas Bjerre *2017-06-13 18:01:27* 1000 | 1001 | **doc** 1002 | 1003 | 1004 | [1f06f](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/1f06fa98af3d4b4) Tomas Bjerre *2017-04-22 04:32:55* 1005 | 1006 | 1007 | ## 1.7 (2017-04-21) 1008 | 1009 | ### Other changes 1010 | 1011 | **Allow String as projectId** 1012 | 1013 | 1014 | [318bd](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/318bde3205e8ed6) Tomas Bjerre *2017-04-21 17:00:23* 1015 | 1016 | 1017 | ## 1.6 (2017-04-11) 1018 | 1019 | ### Other changes 1020 | 1021 | **URL in Klocwork** 1022 | 1023 | 1024 | [8f123](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/8f123582ea0373f) Tomas Bjerre *2017-04-11 18:29:45* 1025 | 1026 | **doc** 1027 | 1028 | 1029 | [4e252](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/4e252dd22d077f8) Tomas Bjerre *2017-04-10 20:17:24* 1030 | 1031 | 1032 | ## 1.5 (2017-04-10) 1033 | 1034 | ### Other changes 1035 | 1036 | **SbtScalac** 1037 | 1038 | 1039 | [895fe](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/895fe8717e5a255) Tomas Bjerre *2017-04-10 18:42:20* 1040 | 1041 | **doc** 1042 | 1043 | 1044 | [38c25](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/38c25c7f2d22f4e) Tomas Bjerre *2017-04-10 17:31:51* 1045 | 1046 | 1047 | ## 1.4 (2017-03-30) 1048 | 1049 | ### Other changes 1050 | 1051 | **Klocwork parser** 1052 | 1053 | 1054 | [03d28](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/03d28f8442fd2cd) Tomas Bjerre *2017-03-30 17:39:30* 1055 | 1056 | **doc** 1057 | 1058 | 1059 | [2d9ed](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/2d9ed88aac0ab80) Tomas Bjerre *2017-03-18 19:25:05* 1060 | 1061 | 1062 | ## 1.3 (2017-03-17) 1063 | 1064 | ### Other changes 1065 | 1066 | **Persisting severity filter on global config** 1067 | 1068 | 1069 | [22266](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/222665cc5b92adb) Tomas Bjerre *2017-03-17 20:57:23* 1070 | 1071 | 1072 | ## 1.2 (2017-03-17) 1073 | 1074 | ### Other changes 1075 | 1076 | **Allow filtering on severity** 1077 | 1078 | * And reducing logging in server log. 1079 | 1080 | [f2438](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/f2438c25e94162b) Tomas Bjerre *2017-03-17 19:44:18* 1081 | 1082 | **doc** 1083 | 1084 | 1085 | [7e25d](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/7e25d0de1f34d17) Tomas Bjerre *2017-03-14 18:31:23* 1086 | 1087 | **Jenkinsfile** 1088 | 1089 | 1090 | [b8e05](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/b8e058e54415664) Tomas Bjerre *2017-03-10 17:38:13* 1091 | 1092 | 1093 | ## 1.1 (2017-03-04) 1094 | 1095 | ### Other changes 1096 | 1097 | **doc** 1098 | 1099 | 1100 | [5767a](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/5767ae9c726bf18) Tomas Bjerre *2017-03-04 09:25:07* 1101 | 1102 | 1103 | ## 1.0 (2017-03-03) 1104 | 1105 | ### Other changes 1106 | 1107 | **Initial** 1108 | 1109 | 1110 | [1d13e](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/commit/1d13e23e39656fb) Tomas Bjerre *2017-03-03 13:08:31* 1111 | 1112 | 1113 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE: -------------------------------------------------------------------------------- 1 | It may be a good idea to look at old issues, both closed and open. 2 | 3 | Some recurring problems are: 4 | 5 | * The user did not perform the merge before doing the analysis. 6 | * No violations were reported because: 7 | * The user tested the plugin on a PR that did not introduce any new violations. 8 | * The user had both `createSingleFileComments` and `createCommentWithAllSingleFileComments` set to `false` 9 | 10 | When reporting a bug, please **try** to provide as much information as possible. 11 | 12 | * Plugin version used. 13 | * Jenkins version used. 14 | * Your configuration. 15 | * Pipeline script or screenshot. 16 | * Expected result and actual result. 17 | * Any information from the logs: 18 | * Jenkins log: http://jenkins-server/log/ 19 | * Build log. 20 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | /* `buildPlugin` step provided by: https://github.com/jenkins-infra/pipeline-library */ 4 | buildPlugin(useContainerAgent: true, configurations: [ 5 | [ platform: "linux", jdk: "8" ], 6 | [ platform: "windows", jdk: "8" ], 7 | [ platform: "linux", jdk: "11" ], 8 | [ platform: "windows", jdk: "11" ] 9 | ]) 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Tomas Bjerre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Violation Comments to GitLab Plugin 2 | 3 | 4 | This 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. 5 | 6 | An 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). 7 | 8 | Available in Jenkins [here](https://wiki.jenkins-ci.org/display/JENKINS/Violation+Comments+to+GitLab+Plugin). 9 | 10 | Example of supported reports are available [here](https://github.com/tomasbjerre/violations-lib/tree/master/src/test/resources). 11 | 12 | There is a complete running example available here: https://github.com/tomasbjerre/jenkins-configuration-as-code-sandbox 13 | 14 | You can also do this with a [command line tool](https://www.npmjs.com/package/violation-comments-to-gitlab-command-line). 15 | 16 | A number of **parsers** have been implemented. Some **parsers** can parse output from several **reporters**. 17 | 18 | | Reporter | Parser | Notes 19 | | --- | --- | --- 20 | | [_ARM-GCC_](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm) | `CLANG` | 21 | | [_AndroidLint_](http://developer.android.com/tools/help/lint.html) | `ANDROIDLINT` | 22 | | [_Ansible-Later_](https://github.com/thegeeklab/ansible-later) | `ANSIBLELATER` | With `json` format 23 | | [_AnsibleLint_](https://github.com/willthames/ansible-lint) | `FLAKE8` | With `-p` 24 | | [_Bandit_](https://github.com/PyCQA/bandit) | `CLANG` | With `bandit -r examples/ -f custom -o bandit.out --msg-template "{abspath}:{line}: {severity}: {test_id}: {msg}"` 25 | | [_CLang_](https://clang-analyzer.llvm.org/) | `CLANG` | 26 | | [_CPD_](http://pmd.sourceforge.net/pmd-4.3.0/cpd.html) | `CPD` | 27 | | [_CPPCheck_](http://cppcheck.sourceforge.net/) | `CPPCHECK` | With `cppcheck test.cpp --output-file=cppcheck.xml --xml` 28 | | [_CPPLint_](https://github.com/theandrewdavis/cpplint) | `CPPLINT` | 29 | | [_CSSLint_](https://github.com/CSSLint/csslint) | `CSSLINT` | 30 | | [_Checkstyle_](http://checkstyle.sourceforge.net/) | `CHECKSTYLE` | 31 | | [_CloudFormation Linter_](https://github.com/aws-cloudformation/cfn-lint) | `JUNIT` | `cfn-lint . -f junit --output-file report-junit.xml` 32 | | [_CodeClimate_](https://codeclimate.com/) | `CODECLIMATE` | 33 | | [_CodeNarc_](http://codenarc.sourceforge.net/) | `CODENARC` | 34 | | [_Coverity_](https://scan.coverity.com/) | `COVERITY` | 35 | | [_Dart_](https://dart.dev/) | `MACHINE` | With `dart analyze --format=machine` 36 | | [_Dependency Check_](https://jeremylong.github.io/DependencyCheck/) | `SARIF` | Using `--format SARIF` 37 | | [_Detekt_](https://github.com/arturbosch/detekt) | `CHECKSTYLE` | With `--output-format xml`. 38 | | [_DocFX_](http://dotnet.github.io/docfx/) | `DOCFX` | 39 | | [_Doxygen_](https://www.stack.nl/~dimitri/doxygen/) | `CLANG` | 40 | | [_ERB_](https://www.puppetcookbook.com/posts/erb-template-validation.html) | `CLANG` | With `erb -P -x -T '-' "${it}" \| ruby -c 2>&1 >/dev/null \| grep '^-' \| sed -E 's/^-([a-zA-Z0-9:]+)/${filename}\1 ERROR:/p' > erbfiles.out`. 41 | | [_ESLint_](https://github.com/sindresorhus/grunt-eslint) | `CHECKSTYLE` | With `format: 'checkstyle'`. 42 | | [_Findbugs_](http://findbugs.sourceforge.net/) | `FINDBUGS` | 43 | | [_Flake8_](http://flake8.readthedocs.org/en/latest/) | `FLAKE8` | 44 | | [_FxCop_](https://en.wikipedia.org/wiki/FxCop) | `FXCOP` | 45 | | [_GCC_](https://gcc.gnu.org/) | `CLANG` | 46 | | [_GHS_](https://www.ghs.com/) | `GHS` | 47 | | [_Gendarme_](http://www.mono-project.com/docs/tools+libraries/tools/gendarme/) | `GENDARME` | 48 | | [_Generic reporter_]() | `GENERIC` | Will create one single violation with all the content as message. 49 | | [_GoLint_](https://github.com/golang/lint) | `GOLINT` | 50 | | [_GoVet_](https://golang.org/cmd/vet/) | `GOLINT` | Same format as GoLint. 51 | | [_GolangCI-Lint_](https://github.com/golangci/golangci-lint/) | `CHECKSTYLE` | With `--out-format=checkstyle`. 52 | | [_GoogleErrorProne_](https://github.com/google/error-prone) | `GOOGLEERRORPRONE` | 53 | | [_HadoLint_](https://github.com/hadolint/hadolint/) | `CHECKSTYLE` | With `-f checkstyle` 54 | | [_IAR_](https://www.iar.com/iar-embedded-workbench/) | `IAR` | With `--no_wrap_diagnostics` 55 | | [_Infer_](http://fbinfer.com/) | `PMD` | Facebook Infer. With `--pmd-xml`. 56 | | [_JACOCO_](https://www.jacoco.org/) | `JACOCO` | 57 | | [_JCReport_](https://github.com/jCoderZ/fawkez/wiki/JcReport) | `JCREPORT` | 58 | | [_JSHint_](http://jshint.com/) | `JSLINT` | With `--reporter=jslint` or the CHECKSTYLE parser with `--reporter=checkstyle` 59 | | [_JUnit_](https://junit.org/junit4/) | `JUNIT` | It only contains the failures. 60 | | [_KTLint_](https://github.com/shyiko/ktlint) | `CHECKSTYLE` | 61 | | [_Klocwork_](http://www.klocwork.com/products-services/klocwork/static-code-analysis) | `KLOCWORK` | 62 | | [_KotlinGradle_](https://github.com/JetBrains/kotlin) | `KOTLINGRADLE` | Output from Kotlin Gradle Plugin. 63 | | [_KotlinMaven_](https://github.com/JetBrains/kotlin) | `KOTLINMAVEN` | Output from Kotlin Maven Plugin. 64 | | [_Lint_]() | `LINT` | A common XML format, used by different linters. 65 | | [_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 66 | | [_MSCpp_](https://visualstudio.microsoft.com/vs/features/cplusplus/) | `MSCPP` | 67 | | [_Mccabe_](https://pypi.python.org/pypi/mccabe) | `FLAKE8` | 68 | | [_MyPy_](https://pypi.python.org/pypi/mypy-lang) | `MYPY` | 69 | | [_NullAway_](https://github.com/uber/NullAway) | `GOOGLEERRORPRONE` | Same format as Google Error Prone. 70 | | [_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) 71 | | [_PHPCS_](https://github.com/squizlabs/PHP_CodeSniffer) | `CHECKSTYLE` | With `phpcs api.php --report=checkstyle`. 72 | | [_PHPPMD_](https://phpmd.org/) | `PMD` | With `phpmd api.php xml ruleset.xml`. 73 | | [_PMD_](https://pmd.github.io/) | `PMD` | 74 | | [_Pep8_](https://github.com/PyCQA/pycodestyle) | `FLAKE8` | 75 | | [_PerlCritic_](https://github.com/Perl-Critic) | `PERLCRITIC` | 76 | | [_PiTest_](http://pitest.org/) | `PITEST` | 77 | | [_ProtoLint_](https://github.com/yoheimuta/protolint) | `PROTOLINT` | 78 | | [_Puppet-Lint_](http://puppet-lint.com/) | `CLANG` | With `-log-format %{fullpath}:%{line}:%{column}: %{kind}: %{message}` 79 | | [_PyDocStyle_](https://pypi.python.org/pypi/pydocstyle) | `PYDOCSTYLE` | 80 | | [_PyFlakes_](https://pypi.python.org/pypi/pyflakes) | `FLAKE8` | 81 | | [_PyLint_](https://www.pylint.org/) | `PYLINT` | With `pylint --output-format=parseable`. 82 | | [_ReSharper_](https://www.jetbrains.com/resharper/) | `RESHARPER` | 83 | | [_RubyCop_](http://rubocop.readthedocs.io/en/latest/formatters/) | `CLANG` | With `rubycop -f clang file.rb` 84 | | [_SARIF_](https://github.com/oasis-tcs/sarif-spec) | `SARIF` | v2.x. Microsoft Visual C# can generate it with `ErrorLog="BuildErrors.sarif,version=2"`. 85 | | [_SbtScalac_](http://www.scala-sbt.org/) | `SBTSCALAC` | 86 | | [_Scalastyle_](http://www.scalastyle.org/) | `CHECKSTYLE` | 87 | | [_Semgrep_](https://semgrep.dev/) | `SEMGREP` | With `--json`. 88 | | [_Simian_](http://www.harukizaemon.com/simian/) | `SIMIAN` | 89 | | [_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&resolved=false' \| jq -f sonar-report-builder.jq > sonar-report.json`. 90 | | [_Spotbugs_](https://spotbugs.github.io/) | `FINDBUGS` | 91 | | [_StyleCop_](https://stylecop.codeplex.com/) | `STYLECOP` | 92 | | [_SwiftLint_](https://github.com/realm/SwiftLint) | `CHECKSTYLE` | With `--reporter checkstyle`. 93 | | [_TSLint_](https://palantir.github.io/tslint/usage/cli/) | `CHECKSTYLE` | With `-t checkstyle` 94 | | [_Valgrind_](https://valgrind.org/) | `VALGRIND` | With `--xml=yes`. 95 | | [_XMLLint_](http://xmlsoft.org/xmllint.html) | `XMLLINT` | 96 | | [_XUnit_](https://xunit.net/) | `XUNIT` | It only contains the failures. 97 | | [_YAMLLint_](https://yamllint.readthedocs.io/en/stable/index.html) | `YAMLLINT` | With `-f parsable` 98 | | [_ZPTLint_](https://pypi.python.org/pypi/zptlint) | `ZPTLINT` | 99 | 100 | 52 parsers and 79 reporters. 101 | 102 | Missing a format? Open an issue [here](https://github.com/tomasbjerre/violations-lib/issues)! 103 | 104 | There is also: 105 | * [violation-comments-to-gitlab-command-line](https://github.com/tomasbjerre/violation-comments-to-gitlab-command-line). 106 | * [violations-command-line](https://github.com/tomasbjerre/violations-command-line), can transform reports to `CodeClimate`. 107 | 108 | ## Notify Jenkins from GitLab 109 | 110 | * 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. 111 | 112 | * Or, trigger with [GitLab plugin](https://github.com/jenkinsci/gitlab-plugin). 113 | 114 | * Or, trigger with [GitLab Merge Request Builder Plugin](https://github.com/timols/jenkins-gitlab-merge-request-builder-plugin). 115 | 116 | ## Merge 117 | 118 | **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. 119 | 120 | ```shell 121 | echo --- 122 | echo --- Merging from $FROM in $FROMREPO to $TO in $TOREPO 123 | echo --- 124 | git clone $TOREPO 125 | cd * 126 | git reset --hard $TO 127 | git status 128 | git remote add from $FROMREPO 129 | git fetch from 130 | git merge $FROM 131 | git --no-pager log --max-count=10 --graph --abbrev-commit 132 | 133 | Your build command here! 134 | ``` 135 | 136 | # Screenshots 137 | 138 | Comments can be made on the diff with one comment per violation `createSingleFileComments`. 139 | 140 | ![Example comment on diff](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/blob/master/sandbox/gitlab-comment-diff.png) 141 | 142 | Or one big comment can be made, `createCommentWithAllSingleFileComments`. 143 | 144 | ![Example comment](https://github.com/jenkinsci/violation-comments-to-gitlab-plugin/blob/master/sandbox/mergerequest-onecomment.png) 145 | 146 | ## Job DSL Plugin 147 | 148 | This 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). 149 | 150 | ```groovy 151 | job('GitLab_MR_Builder') { 152 | concurrentBuild() 153 | quietPeriod(0) 154 | parameters { 155 | stringParam('MERGE_REQUEST_TO_URL', '') 156 | stringParam('MERGE_REQUEST_FROM_URL', '') 157 | stringParam('MERGE_REQUEST_TO_BRANCH', '') 158 | stringParam('MERGE_REQUEST_FROM_BRANCH', '') 159 | } 160 | scm { 161 | git { 162 | remote { 163 | name('origin') 164 | url('$MERGE_REQUEST_TO_URL') 165 | } 166 | remote { 167 | name('upstream') 168 | url('$MERGE_REQUEST_FROM_URL') 169 | } 170 | branch('$MERGE_REQUEST_FROM_BRANCH') 171 | extensions { 172 | mergeOptions { 173 | remote('upstream') 174 | branch('$MERGE_REQUEST_TO_BRANCH') 175 | } 176 | } 177 | } 178 | } 179 | triggers { 180 | genericTrigger { 181 | genericVariables { 182 | genericVariable { 183 | key("MERGE_REQUEST_TO_URL") 184 | value("\$.object_attributes.target.git_http_url") 185 | expressionType("JSONPath") 186 | regexpFilter("") 187 | } 188 | genericVariable { 189 | key("MERGE_REQUEST_FROM_URL") 190 | value("\$.object_attributes.source.git_http_url") 191 | expressionType("JSONPath") 192 | regexpFilter("") 193 | } 194 | genericVariable { 195 | key("MERGE_REQUEST_TO_BRANCH") 196 | value("\$.object_attributes.target_branch") 197 | expressionType("JSONPath") 198 | regexpFilter("") 199 | } 200 | genericVariable { 201 | key("MERGE_REQUEST_FROM_BRANCH") 202 | value("\$.object_attributes.source_branch") 203 | expressionType("JSONPath") 204 | regexpFilter("") 205 | } 206 | genericVariable { 207 | key("PROJECT_ID") 208 | value("\$.object_attributes.target_project_id") 209 | expressionType("JSONPath") 210 | regexpFilter("") 211 | } 212 | genericVariable { 213 | key("MERGE_REQUST_ID") 214 | value("\$.object_attributes.id") 215 | expressionType("JSONPath") 216 | regexpFilter("") 217 | } 218 | genericVariable { 219 | key("MR_OBJECT_KIND") 220 | value("\$.object_kind") 221 | expressionType("JSONPath") 222 | regexpFilter("") 223 | } 224 | genericVariable { 225 | key("MR_OLD_REV") 226 | value("\$.object_attributes.oldrev") 227 | expressionType("JSONPath") 228 | regexpFilter("") 229 | } 230 | genericVariable { 231 | key("MR_ACTION") 232 | value("\$.object_attributes.action") 233 | expressionType("JSONPath") 234 | regexpFilter("") 235 | } 236 | } 237 | regexpFilterText("\$MR_OBJECT_KIND \$MR_ACTION \$MR_OLD_REV") 238 | regexpFilterExpression("^merge_request\\s(update\\s.{40}\$|open.*)") 239 | } 240 | } 241 | steps { 242 | httpRequest { 243 | url("http://gitlab:880/api/v3/projects/\$PROJECT_ID/merge_requests/\$MERGE_REQUST_ID/notes?private_token=AvAkp6HtUvzpesPypXSk") 244 | consoleLogResponseBody(true) 245 | httpMode("POST") 246 | requestBody('body=Building... %20\$BUILD_URL') 247 | } 248 | 249 | shell('./gradlew build') 250 | 251 | conditionalBuilder { 252 | runCondition { 253 | statusCondition { 254 | worstResult('SUCCESS') 255 | bestResult('SUCCESS') 256 | } 257 | runner { 258 | runUnstable() 259 | } 260 | conditionalbuilders { 261 | httpRequest { 262 | url('http://gitlab:880/api/v3/projects/\$PROJECT_ID/merge_requests/\$MERGE_REQUST_ID/notes?private_token=AvAkp6HtUvzpesPypXSk') 263 | consoleLogResponseBody(true) 264 | httpMode('POST') 265 | requestBody('body=SUCCESS%20\$BUILD_URL') 266 | } 267 | } 268 | } 269 | } 270 | 271 | conditionalBuilder { 272 | runCondition { 273 | statusCondition { 274 | worstResult('FAILURE') 275 | bestResult('FAILURE') 276 | } 277 | runner { 278 | runUnstable() 279 | } 280 | conditionalbuilders { 281 | httpRequest { 282 | url('http://gitlab:880/api/v3/projects/\$PROJECT_ID/merge_requests/\$MERGE_REQUST_ID/notes?private_token=AvAkp6HtUvzpesPypXSk') 283 | consoleLogResponseBody(true) 284 | httpMode('POST') 285 | requestBody('body=FAIL%20\$BUILD_URL') 286 | } 287 | } 288 | } 289 | } 290 | } 291 | publishers { 292 | violationsToGitLabRecorder { 293 | config { 294 | gitLabUrl("http://gitlab:880/") 295 | projectId("\$PROJECT_ID") 296 | mergeRequestIid("\$MERGE_REQUST_IID") 297 | 298 | // Only specify proxy if you need it 299 | proxyUri('') 300 | proxyCredentialsId('') // A username/password credential 301 | 302 | commentOnlyChangedContent(true) 303 | commentOnlyChangedContentContext(0) 304 | commentOnlyChangedFiles(true) 305 | createSingleFileComments(true) 306 | createCommentWithAllSingleFileComments(true) 307 | minSeverity('INFO') 308 | maxNumberOfViolations(99999) 309 | 310 | //You may want this when troubleshooting things 311 | enableLogging(true) 312 | 313 | 314 | apiTokenCredentialsId("gitlabtoken") // A secret text credential 315 | apiTokenPrivate(true) 316 | authMethodHeader(true) 317 | ignoreCertificateErrors(true) 318 | 319 | commentTemplate(""" 320 | **Reporter**: {{violation.reporter}}{{#violation.rule}} 321 | 322 | **Rule**: {{violation.rule}}{{/violation.rule}} 323 | **Severity**: {{violation.severity}} 324 | **File**: {{violation.file}} L{{violation.startLine}}{{#violation.source}} 325 | 326 | **Source**: {{violation.source}}{{/violation.source}} 327 | 328 | {{violation.message}} 329 | """) 330 | 331 | violationConfigs { 332 | violationConfig { 333 | parser("FINDBUGS") 334 | reporter("Findbugs") 335 | pattern(".*/findbugs/.*\\.xml\$") 336 | } 337 | violationConfig { 338 | parser("CHECKSTYLE") 339 | reporter("Checkstyle") 340 | pattern(".*/checkstyle/.*\\.xml\$") 341 | } 342 | } 343 | } 344 | } 345 | } 346 | } 347 | ``` 348 | 349 | ## Pipeline Plugin 350 | 351 | Here 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). 352 | 353 | ```groovy 354 | pipelineJob("merge-request-pipeline") { 355 | concurrentBuild() 356 | quietPeriod(0) 357 | authenticationToken("thetoken") 358 | triggers { 359 | genericTrigger { 360 | genericVariables { 361 | genericVariable { 362 | key("MERGE_REQUEST_TO_URL") 363 | value("\$.object_attributes.target.git_http_url") 364 | expressionType("JSONPath") 365 | regexpFilter("") 366 | } 367 | genericVariable { 368 | key("MERGE_REQUEST_FROM_URL") 369 | value("\$.object_attributes.source.git_http_url") 370 | expressionType("JSONPath") 371 | regexpFilter("") 372 | } 373 | genericVariable { 374 | key("MERGE_REQUEST_TO_BRANCH") 375 | value("\$.object_attributes.target_branch") 376 | expressionType("JSONPath") 377 | regexpFilter("") 378 | } 379 | genericVariable { 380 | key("MERGE_REQUEST_FROM_BRANCH") 381 | value("\$.object_attributes.source_branch") 382 | expressionType("JSONPath") 383 | regexpFilter("") 384 | } 385 | genericVariable { 386 | key("PROJECT_ID") 387 | value("\$.object_attributes.target_project_id") 388 | expressionType("JSONPath") 389 | regexpFilter("") 390 | } 391 | genericVariable { 392 | key("PROJECT_PATH") 393 | value("\$.object_attributes.target.path_with_namespace") 394 | expressionType("JSONPath") 395 | regexpFilter("") 396 | } 397 | genericVariable { 398 | key("MERGE_REQUST_IID") 399 | value("\$.object_attributes.iid") 400 | expressionType("JSONPath") 401 | regexpFilter("") 402 | } 403 | genericVariable { 404 | key("MR_OBJECT_KIND") 405 | value("\$.object_kind") 406 | expressionType("JSONPath") 407 | regexpFilter("") 408 | } 409 | genericVariable { 410 | key("MR_OLD_REV") 411 | value("\$.object_attributes.oldrev") 412 | expressionType("JSONPath") 413 | regexpFilter("") 414 | } 415 | genericVariable { 416 | key("MR_ACTION") 417 | value("\$.object_attributes.action") 418 | expressionType("JSONPath") 419 | regexpFilter("") 420 | } 421 | genericVariable { 422 | key("MR_TITLE") 423 | value("\$.object_attributes.title") 424 | expressionType("JSONPath") 425 | regexpFilter("") 426 | } 427 | } 428 | regexpFilterText("\$MR_OBJECT_KIND \$MR_ACTION \$MR_OLD_REV") 429 | regexpFilterExpression("^merge_request\\s(update\\s.{40}\$|open.*)") 430 | } 431 | } 432 | 433 | definition { 434 | cps { 435 | script(readFileFromWorkspace('merge_request_pipeline.pipeline')) 436 | sandbox() 437 | } 438 | } 439 | } 440 | ``` 441 | 442 | And the merge_request_pipeline.pipeline contains 443 | ```groovy 444 | def commentMr(projectId, mergeRequestIid, comment) { 445 | def body = comment 446 | .replaceAll(" ","%20") 447 | .replaceAll("/","%2F") 448 | def project = projectId 449 | .replaceAll("/","%2F") 450 | sh "curl http://gitlab:80/api/v4/projects/$project/merge_requests/$mergeRequestIid/notes -H 'PRIVATE-TOKEN: 6xRcmSzPzzEXeS2qqr7R' -X POST -d \"body="+body+"\"" 451 | } 452 | 453 | node { 454 | deleteDir() 455 | currentBuild.description = "$MR_TITLE from $MERGE_REQUEST_FROM_BRANCH to $MERGE_REQUEST_TO_BRANCH" 456 | 457 | commentMr(env.PROJECT_PATH,env.MERGE_REQUST_IID,"Verifierar $MERGE_REQUEST_FROM_BRANCH... ${env.BUILD_URL}") 458 | 459 | stage('Merge') { 460 | sh "git init" 461 | sh "git fetch --no-tags $MERGE_REQUEST_TO_URL +refs/heads/*:refs/remotes/origin/* --depth=200" 462 | sh "git checkout origin/${env.MERGE_REQUEST_TO_BRANCH}" 463 | sh "git config user.email 'je@nkins.domain'" 464 | sh "git config user.name 'jenkins'" 465 | sh "git merge origin/${env.MERGE_REQUEST_FROM_BRANCH}" 466 | sh "git log --graph --abbrev-commit --max-count=10" 467 | } 468 | 469 | stage('Compile') { 470 | sh "./gradlew assemble" 471 | } 472 | 473 | stage('Unit test') { 474 | sh "./gradlew test" 475 | commentMr(env.PROJECT_PATH,env.MERGE_REQUST_IID,"Test ok in $MERGE_REQUEST_FROM_BRANCH =) ${env.BUILD_URL}") 476 | } 477 | 478 | stage('Regression test') { 479 | sh "echo regtest" 480 | commentMr(env.PROJECT_PATH,env.MERGE_REQUST_IID,"Regression test ok in $MERGE_REQUEST_FROM_BRANCH =) ${env.BUILD_URL}") 481 | } 482 | 483 | stage('Static code analysis') { 484 | sh "./gradlew check" 485 | step([ 486 | $class: 'ViolationsToGitLabRecorder', 487 | config: [ 488 | gitLabUrl: 'http://gitlab:80/', 489 | projectId: env.PROJECT_PATH, 490 | mergeRequestIid: env.MERGE_REQUST_IID, 491 | commentOnlyChangedContent: true, 492 | commentOnlyChangedContentContext: 0, 493 | commentOnlyChangedFiles: true, 494 | createSingleFileComments: true, 495 | createCommentWithAllSingleFileComments: true, 496 | minSeverity: 'INFO', 497 | maxNumberOfViolations: 99999, 498 | 499 | // You may want this when troubleshooting things 500 | enableLogging: true, 501 | 502 | // Only specify proxy if you need it 503 | proxyUri: '', 504 | proxyCredentialsId: '', // A username/password credential 505 | 506 | apiTokenCredentialsId: 'id', // A secret text credential 507 | apiTokenPrivate: true, 508 | authMethodHeader: true, 509 | ignoreCertificateErrors: true, 510 | keepOldComments: false, 511 | shouldSetWip: true, 512 | 513 | commentTemplate: """ 514 | **Reporter**: {{violation.reporter}}{{#violation.rule}} 515 | 516 | **Rule**: {{violation.rule}}{{/violation.rule}} 517 | **Severity**: {{violation.severity}} 518 | **File**: {{violation.file}} L{{violation.startLine}}{{#violation.source}} 519 | 520 | **Source**: {{violation.source}}{{/violation.source}} 521 | 522 | {{violation.message}} 523 | """, 524 | 525 | violationConfigs: [ 526 | [ pattern: '.*/checkstyle/.*\\.xml$', parser: 'CHECKSTYLE', reporter: 'Checkstyle' ], 527 | [ pattern: '.*/findbugs/.*\\.xml$', parser: 'FINDBUGS', reporter: 'Findbugs' ], 528 | [ pattern: '.*/pmd/.*\\.xml$', parser: 'PMD', reporter: 'PMD' ], 529 | ] 530 | ] 531 | ]) 532 | } 533 | } 534 | ``` 535 | 536 | # Encoding 537 | 538 | The `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). 539 | 540 | # Plugin development 541 | More details on Jenkins plugin development is available [here](https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial). 542 | 543 | There is a ```/build.sh``` that will perform a full build and test the plugin. 544 | 545 | If you have release-permissions this is how you do a release: 546 | 547 | ``` 548 | mvn release:prepare release:perform 549 | ``` 550 | -------------------------------------------------------------------------------- /debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mvnDebug -q hpi:run -Djava.util.logging.config.file=logging.properties -Djenkins.version=2.121.3 -Denforcer.skip=true 3 | 4 | -------------------------------------------------------------------------------- /logging.properties: -------------------------------------------------------------------------------- 1 | # Logging 2 | handlers = java.util.logging.ConsoleHandler 3 | org.jenkinsci.plugins.jvcts.level = FINE 4 | 5 | # Console Logging 6 | java.util.logging.ConsoleHandler.level = FINE 7 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | org.jenkins-ci.plugins 6 | plugin 7 | 4.74 8 | 9 | 10 | 11 | 2.361.4 12 | false 13 | true 14 | 2.1.0 15 | 1.89.0 16 | 1.157.0 17 | 2.1.0 18 | 2.9 19 | 20 | 21 | violation-comments-to-gitlab 22 | 2.62.1-SNAPSHOT 23 | hpi 24 | Violation Comments to GitLab Plugin 25 | https://github.com/jenkinsci/violation-comments-to-gitlab-plugin 26 | 27 | 28 | 29 | MIT License 30 | http://opensource.org/licenses/MIT 31 | 32 | 33 | 34 | 35 | 36 | tomasbjerre 37 | Tomas Bjerre 38 | tomas.bjerre85@gmail.com 39 | 40 | 41 | 42 | 43 | GitHub 44 | https://github.com/tomasbjerre/violation-comments-to-gitlab-plugin 45 | 46 | 47 | 48 | scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git 49 | scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git 50 | git@github.com:jenkinsci/${project.artifactId}-plugin 51 | violation-comments-to-gitlab-2.61 52 | 53 | 54 | 55 | 56 | repo.jenkins-ci.org 57 | https://repo.jenkins-ci.org/public/ 58 | 59 | 60 | jitpack.io 61 | https://jitpack.io 62 | 63 | 64 | 65 | 66 | 67 | repo.jenkins-ci.org 68 | https://repo.jenkins-ci.org/public/ 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-surefire-plugin 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-eclipse-plugin 81 | 82 | true 83 | true 84 | 85 | 86 | 87 | se.bjurr.gitchangelog 88 | git-changelog-maven-plugin 89 | ${changelog} 90 | 91 | -([^-]+?)$ 92 | ^\[maven-release-plugin\].* 93 | 94 | 95 | 96 | com.coveo 97 | fmt-maven-plugin 98 | 2.9 99 | 100 | 101 | 102 | format 103 | 104 | 105 | 106 | 107 | 108 | se.bjurr.violations 109 | violations-maven-plugin 110 | ${violations-maven} 111 | 112 | INFO 113 | VERBOSE 114 | 99999999 115 | true 116 | 117 | 118 | FINDBUGS 119 | Spotbugs 120 | . 121 | .*/spotbugsXml.*\.xml$ 122 | 123 | 124 | 125 | 126 | 127 | verify 128 | 129 | violations 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | org.slf4j 140 | slf4j-api 141 | 1.7.26 142 | 143 | 144 | org.jenkins-ci.plugins 145 | credentials 146 | 2.6.1 147 | 148 | 149 | org.jenkins-ci.plugins 150 | plain-credentials 151 | 1.8 152 | 153 | 154 | com.github.spotbugs 155 | spotbugs-annotations 156 | 4.2.3 157 | 158 | 159 | se.bjurr.violations 160 | violations-lib 161 | ${violations-lib} 162 | 163 | 164 | se.bjurr.violations 165 | violation-comments-to-gitlab-lib 166 | ${violation-comments-lib} 167 | 168 | 169 | org.slf4j 170 | slf4j-api 171 | 172 | 173 | javax.servlet 174 | javax.servlet-api 175 | 176 | 177 | javax.xml.bind 178 | jaxb-api 179 | 180 | 181 | 182 | 183 | org.jenkins-ci.plugins 184 | structs 185 | 1.24 186 | 187 | 188 | 189 | uk.co.jemos.podam 190 | podam 191 | 7.1.1.RELEASE 192 | test 193 | 194 | 195 | javax.xml.ws 196 | jaxws-api 197 | 2.3.1 198 | test 199 | 200 | 201 | junit 202 | junit 203 | 4.13.1 204 | test 205 | 206 | 207 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./mvnw se.bjurr.gitchangelog:git-changelog-maven-plugin:semantic-version \ 4 | && git commit -a -m "chore: setting version in pom" && git push || echo "No new version" \ 5 | && ./mvnw release:prepare release:perform -B \ 6 | && ./mvnw se.bjurr.gitchangelog:git-changelog-maven-plugin:git-changelog \ 7 | && git commit -a -m "chore: updating changelog" \ 8 | && git push \ 9 | || git clean -f 10 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./mvnw versions:update-properties 3 | ./mvnw -q hpi:run -Djava.util.logging.config.file=logging.properties -Djenkins.version=2.401.1 -Denforcer.skip=true 4 | -------------------------------------------------------------------------------- /sandbox/gitlab-comment-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/violation-comments-to-gitlab-plugin/cece529c8bf429d6151c279b592489413954afe1/sandbox/gitlab-comment-diff.png -------------------------------------------------------------------------------- /sandbox/gitlab-mergerequest-comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "object_kind":"note", 3 | "user":{ 4 | "name":"Administrator", 5 | "username":"root", 6 | "avatar_url":"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon" 7 | }, 8 | "project_id":1, 9 | "project":{ 10 | "name":"violations-test", 11 | "description":"", 12 | "web_url":"http://a3dffa263a40/root/violations-test", 13 | "avatar_url":null, 14 | "git_ssh_url":"git@a3dffa263a40:root/violations-test.git", 15 | "git_http_url":"http://a3dffa263a40/root/violations-test.git", 16 | "namespace":"root", 17 | "visibility_level":20, 18 | "path_with_namespace":"root/violations-test", 19 | "default_branch":"feature/addingcrap", 20 | "homepage":"http://a3dffa263a40/root/violations-test", 21 | "url":"git@a3dffa263a40:root/violations-test.git", 22 | "ssh_url":"git@a3dffa263a40:root/violations-test.git", 23 | "http_url":"http://a3dffa263a40/root/violations-test.git" 24 | }, 25 | "object_attributes":{ 26 | "id":28, 27 | "note":"asdasd", 28 | "noteable_type":"MergeRequest", 29 | "author_id":1, 30 | "created_at":"2017-03-03 23:31:59 UTC", 31 | "updated_at":"2017-03-03 23:31:59 UTC", 32 | "project_id":1, 33 | "attachment":null, 34 | "line_code":null, 35 | "commit_id":"", 36 | "noteable_id":1, 37 | "system":false, 38 | "st_diff":null, 39 | "updated_by_id":null, 40 | "type":null, 41 | "position":null, 42 | "original_position":null, 43 | "resolved_at":null, 44 | "resolved_by_id":null, 45 | "discussion_id":"56f0eeee7c7f486a2b0070d1c6ccdf2bd9919e6f", 46 | "original_discussion_id":null, 47 | "url":"http://a3dffa263a40/root/violations-test/merge_requests/1#note_28" 48 | }, 49 | "repository":{ 50 | "name":"violations-test", 51 | "url":"git@a3dffa263a40:root/violations-test.git", 52 | "description":"", 53 | "homepage":"http://a3dffa263a40/root/violations-test" 54 | }, 55 | "merge_request":{ 56 | "id":1, 57 | "target_branch":"master", 58 | "source_branch":"feature/addingcrap", 59 | "source_project_id":1, 60 | "author_id":1, 61 | "assignee_id":null, 62 | "title":"some crap", 63 | "created_at":"2017-02-20 19:54:06 UTC", 64 | "updated_at":"2017-03-03 23:31:59 UTC", 65 | "milestone_id":null, 66 | "state":"opened", 67 | "merge_status":"can_be_merged", 68 | "target_project_id":1, 69 | "iid":1, 70 | "description":"", 71 | "position":0, 72 | "locked_at":null, 73 | "updated_by_id":null, 74 | "merge_error":null, 75 | "merge_params":{ 76 | "force_remove_source_branch":null 77 | }, 78 | "merge_when_build_succeeds":false, 79 | "merge_user_id":null, 80 | "merge_commit_sha":null, 81 | "deleted_at":null, 82 | "in_progress_merge_commit_sha":null, 83 | "lock_version":null, 84 | "time_estimate":0, 85 | "source":{ 86 | "name":"violations-test", 87 | "description":"", 88 | "web_url":"http://a3dffa263a40/root/violations-test", 89 | "avatar_url":null, 90 | "git_ssh_url":"git@a3dffa263a40:root/violations-test.git", 91 | "git_http_url":"http://a3dffa263a40/root/violations-test.git", 92 | "namespace":"root", 93 | "visibility_level":20, 94 | "path_with_namespace":"root/violations-test", 95 | "default_branch":"feature/addingcrap", 96 | "homepage":"http://a3dffa263a40/root/violations-test", 97 | "url":"git@a3dffa263a40:root/violations-test.git", 98 | "ssh_url":"git@a3dffa263a40:root/violations-test.git", 99 | "http_url":"http://a3dffa263a40/root/violations-test.git" 100 | }, 101 | "target":{ 102 | "name":"violations-test", 103 | "description":"", 104 | "web_url":"http://a3dffa263a40/root/violations-test", 105 | "avatar_url":null, 106 | "git_ssh_url":"git@a3dffa263a40:root/violations-test.git", 107 | "git_http_url":"http://a3dffa263a40/root/violations-test.git", 108 | "namespace":"root", 109 | "visibility_level":20, 110 | "path_with_namespace":"root/violations-test", 111 | "default_branch":"feature/addingcrap", 112 | "homepage":"http://a3dffa263a40/root/violations-test", 113 | "url":"git@a3dffa263a40:root/violations-test.git", 114 | "ssh_url":"git@a3dffa263a40:root/violations-test.git", 115 | "http_url":"http://a3dffa263a40/root/violations-test.git" 116 | }, 117 | "last_commit":{ 118 | "id":"1c3e5deb451353c34264b98c77836012a2106515", 119 | "message":"asd\n", 120 | "timestamp":"2017-02-21T21:14:14+01:00", 121 | "url":"http://a3dffa263a40/root/violations-test/commit/1c3e5deb451353c34264b98c77836012a2106515", 122 | "author":{ 123 | "name":"Tomas Bjerre", 124 | "email":"tomas.bjerre85@gmail.com" 125 | } 126 | }, 127 | "work_in_progress":false 128 | } 129 | } -------------------------------------------------------------------------------- /sandbox/gitlab-mergerequest-push.json: -------------------------------------------------------------------------------- 1 | { 2 | "object_kind":"merge_request", 3 | "user":{ 4 | "name":"Administrator", 5 | "username":"root", 6 | "avatar_url":"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon" 7 | }, 8 | "project":{ 9 | "name":"violations-test", 10 | "description":"", 11 | "web_url":"http://846c453ea620/root/violations-test", 12 | "avatar_url":null, 13 | "git_ssh_url":"git@846c453ea620:root/violations-test.git", 14 | "git_http_url":"http://846c453ea620/root/violations-test.git", 15 | "namespace":"root", 16 | "visibility_level":20, 17 | "path_with_namespace":"root/violations-test", 18 | "default_branch":"master", 19 | "homepage":"http://846c453ea620/root/violations-test", 20 | "url":"git@846c453ea620:root/violations-test.git", 21 | "ssh_url":"git@846c453ea620:root/violations-test.git", 22 | "http_url":"http://846c453ea620/root/violations-test.git" 23 | }, 24 | "object_attributes":{ 25 | "id":1, 26 | "target_branch":"master", 27 | "source_branch":"feature/addingcrap", 28 | "source_project_id":1, 29 | "author_id":1, 30 | "assignee_id":null, 31 | "title":"some crap 2", 32 | "created_at":"2017-07-15 07:31:01 UTC", 33 | "updated_at":"2017-07-20 18:49:48 UTC", 34 | "milestone_id":null, 35 | "state":"opened", 36 | "merge_status":"unchecked", 37 | "target_project_id":1, 38 | "iid":1, 39 | "description":"", 40 | "position":0, 41 | "locked_at":null, 42 | "updated_by_id":1, 43 | "merge_error":null, 44 | "merge_params":{ 45 | "force_remove_source_branch":"0" 46 | }, 47 | "merge_when_pipeline_succeeds":false, 48 | "merge_user_id":null, 49 | "merge_commit_sha":null, 50 | "deleted_at":null, 51 | "in_progress_merge_commit_sha":null, 52 | "lock_version":1, 53 | "time_estimate":0, 54 | "source":{ 55 | "name":"violations-test", 56 | "description":"", 57 | "web_url":"http://846c453ea620/root/violations-test", 58 | "avatar_url":null, 59 | "git_ssh_url":"git@846c453ea620:root/violations-test.git", 60 | "git_http_url":"http://846c453ea620/root/violations-test.git", 61 | "namespace":"root", 62 | "visibility_level":20, 63 | "path_with_namespace":"root/violations-test", 64 | "default_branch":"master", 65 | "homepage":"http://846c453ea620/root/violations-test", 66 | "url":"git@846c453ea620:root/violations-test.git", 67 | "ssh_url":"git@846c453ea620:root/violations-test.git", 68 | "http_url":"http://846c453ea620/root/violations-test.git" 69 | }, 70 | "target":{ 71 | "name":"violations-test", 72 | "description":"", 73 | "web_url":"http://846c453ea620/root/violations-test", 74 | "avatar_url":null, 75 | "git_ssh_url":"git@846c453ea620:root/violations-test.git", 76 | "git_http_url":"http://846c453ea620/root/violations-test.git", 77 | "namespace":"root", 78 | "visibility_level":20, 79 | "path_with_namespace":"root/violations-test", 80 | "default_branch":"master", 81 | "homepage":"http://846c453ea620/root/violations-test", 82 | "url":"git@846c453ea620:root/violations-test.git", 83 | "ssh_url":"git@846c453ea620:root/violations-test.git", 84 | "http_url":"http://846c453ea620/root/violations-test.git" 85 | }, 86 | "last_commit":{ 87 | "id":"29c79ef42415790839584003088fa9f6032af0d4", 88 | "message":"some crap\n", 89 | "timestamp":"2017-07-20T20:49:38+02:00", 90 | "url":"http://846c453ea620/root/violations-test/commit/29c79ef42415790839584003088fa9f6032af0d4", 91 | "author":{ 92 | "name":"Tomas Bjerre", 93 | "email":"tomas.bjerre85@gmail.com" 94 | } 95 | }, 96 | "work_in_progress":false, 97 | "total_time_spent":0, 98 | "human_total_time_spent":null, 99 | "human_time_estimate":null, 100 | "url":"http://846c453ea620/root/violations-test/merge_requests/1", 101 | "action":"update", 102 | "oldrev":"7e23c9a980197fe49fae67fb23687c857ff42f86" 103 | }, 104 | "labels":[ 105 | 106 | ], 107 | "repository":{ 108 | "name":"violations-test", 109 | "url":"git@846c453ea620:root/violations-test.git", 110 | "description":"", 111 | "homepage":"http://846c453ea620/root/violations-test" 112 | } 113 | } -------------------------------------------------------------------------------- /sandbox/gitlab.com.testpipeline.jenkinsfile: -------------------------------------------------------------------------------- 1 | node { 2 | deleteDir() 3 | 4 | stage('Merge') { 5 | sh "git init" 6 | sh "git fetch --no-tags --progress https://gitlab.com/tomas.bjerre85/violations-test.git +refs/heads/*:refs/remotes/origin/* --depth=200" 7 | sh "git checkout origin/master" 8 | sh "git merge origin/feature/addingcrap" 9 | sh "git log --graph --abbrev-commit --max-count=10" 10 | } 11 | 12 | stage('Analyze') { 13 | sh "./gradlew build" 14 | sh "find" 15 | } 16 | 17 | stage('Report') { 18 | 19 | step([ 20 | $class: 'ViolationsToGitLabRecorder', 21 | config: [ 22 | gitLabUrl: 'https://gitlab.com/', 23 | projectId: "2732496", 24 | mergeRequestIid: "1", 25 | commentOnlyChangedContent: true, 26 | commentOnlyChangedContentContext: 0, 27 | commentOnlyChangedFiles: true, 28 | createCommentWithAllSingleFileComments: true, 29 | minSeverity: 'INFO', 30 | apiTokenCredentialsId: 'id', 31 | apiTokenPrivate: true, 32 | authMethodHeader: true, 33 | ignoreCertificateErrors: true, 34 | keepOldComments: false, 35 | shouldSetWip: false, 36 | violationConfigs: [ 37 | [ pattern: '.*/checkstyle/.*\\.xml$', parser: 'CHECKSTYLE', reporter: 'Checkstyle' ], 38 | [ pattern: '.*/findbugs/.*\\.xml$', parser: 'FINDBUGS', reporter: 'Findbugs' ], 39 | [ pattern: '.*/pmd/.*\\.xml$', parser: 'PMD', reporter: 'PMD' ], 40 | ] 41 | ] 42 | ]) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sandbox/hints.txt: -------------------------------------------------------------------------------- 1 | Get project id: curl -XGET "https://gitlab.com/api/v4/projects/tomas.bjerre85%2Fviolations-test" 2 | MR: https://gitlab.com/api/v4/projects/2732496/merge_requests 3 | -------------------------------------------------------------------------------- /sandbox/mergerequest-onecomment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/violation-comments-to-gitlab-plugin/cece529c8bf429d6151c279b592489413954afe1/sandbox/mergerequest-onecomment.png -------------------------------------------------------------------------------- /sandbox/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.jenkins-ci.tools 4 | 5 | 6 | 7 | 8 | jenkins 9 | 10 | true 11 | 12 | 13 | 14 | repo.jenkins-ci.org 15 | http://repo.jenkins-ci.org/public/ 16 | 17 | 18 | 19 | 20 | repo.jenkins-ci.org 21 | http://repo.jenkins-ci.org/public/ 22 | 23 | 24 | 25 | 26 | 27 | 28 | repo.jenkins-ci.org 29 | http://repo.jenkins-ci.org/public/ 30 | m.g.o-public 31 | 32 | 33 | 34 | smack 35 | smack 36 | http://repository.opencastproject.org/nexus/content/repositories/public/ 37 | central 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/ViolationsToGitLabDescriptor.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl; 2 | 3 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_MINSEVERITY; 4 | 5 | import edu.umd.cs.findbugs.annotations.NonNull; 6 | import hudson.Extension; 7 | import hudson.model.AbstractProject; 8 | import hudson.tasks.BuildStepDescriptor; 9 | import hudson.tasks.Publisher; 10 | import net.sf.json.JSONObject; 11 | import org.apache.commons.lang.StringUtils; 12 | import org.jenkinsci.Symbol; 13 | import org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfig; 14 | import org.kohsuke.stapler.StaplerRequest; 15 | 16 | @Extension 17 | @Symbol("ViolationsToGitLab") 18 | public final class ViolationsToGitLabDescriptor extends BuildStepDescriptor { 19 | private ViolationsToGitLabConfig config; 20 | 21 | public ViolationsToGitLabDescriptor() { 22 | super(ViolationsToGitLabRecorder.class); 23 | load(); 24 | if (this.config == null) { 25 | this.config = new ViolationsToGitLabConfig(); 26 | } 27 | } 28 | 29 | @Override 30 | public String getDisplayName() { 31 | return "Report Violations to GitLab"; 32 | } 33 | 34 | @Override 35 | public String getHelpFile() { 36 | return super.getHelpFile(); 37 | } 38 | 39 | @Override 40 | public boolean isApplicable( 41 | @SuppressWarnings("rawtypes") final Class jobType) { 42 | return true; 43 | } 44 | 45 | @Override 46 | public Publisher newInstance(final StaplerRequest req, @NonNull final JSONObject formData) 47 | throws hudson.model.Descriptor.FormException { 48 | assert req != null; 49 | if (formData.has("config")) { 50 | final JSONObject config = formData.getJSONObject("config"); 51 | final String minSeverity = config.getString(FIELD_MINSEVERITY); 52 | if (StringUtils.isBlank(minSeverity)) { 53 | config.remove(FIELD_MINSEVERITY); 54 | } 55 | } 56 | 57 | return req.bindJSON(ViolationsToGitLabRecorder.class, formData); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/ViolationsToGitLabGlobalConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl; 2 | 3 | import hudson.Extension; 4 | import hudson.model.Item; 5 | import hudson.util.FormValidation; 6 | import hudson.util.ListBoxModel; 7 | import java.io.Serializable; 8 | import jenkins.model.GlobalConfiguration; 9 | import net.sf.json.JSONObject; 10 | import org.jenkinsci.plugins.jvctgl.config.CredentialsHelper; 11 | import org.kohsuke.accmod.Restricted; 12 | import org.kohsuke.accmod.restrictions.NoExternalUse; 13 | import org.kohsuke.stapler.AncestorInPath; 14 | import org.kohsuke.stapler.DataBoundSetter; 15 | import org.kohsuke.stapler.QueryParameter; 16 | import org.kohsuke.stapler.StaplerRequest; 17 | import se.bjurr.violations.lib.model.SEVERITY; 18 | 19 | @Extension 20 | public class ViolationsToGitLabGlobalConfiguration extends GlobalConfiguration 21 | implements Serializable { 22 | 23 | private static final long serialVersionUID = -7071307231169224261L; 24 | 25 | /** 26 | * Returns this singleton instance. 27 | * 28 | * @return the singleton. 29 | */ 30 | public static ViolationsToGitLabGlobalConfiguration get() { 31 | return GlobalConfiguration.all().get(ViolationsToGitLabGlobalConfiguration.class); 32 | } 33 | 34 | private String gitLabUrl; 35 | 36 | private boolean ignoreCertificateErrors; 37 | 38 | private boolean apiTokenPrivate; 39 | private boolean authMethodHeader; 40 | private String apiTokenCredentialsId; 41 | private SEVERITY minSeverity = SEVERITY.INFO; 42 | 43 | public ViolationsToGitLabGlobalConfiguration() { 44 | load(); 45 | } 46 | 47 | @Override 48 | public boolean configure(final StaplerRequest req, final JSONObject json) throws FormException { 49 | req.bindJSON(this, json); 50 | save(); 51 | return true; 52 | } 53 | 54 | @Restricted(NoExternalUse.class) 55 | public ListBoxModel doFillMinSeverityItems() { 56 | final ListBoxModel items = new ListBoxModel(); 57 | for (final SEVERITY severity : SEVERITY.values()) { 58 | items.add(severity.name()); 59 | } 60 | return items; 61 | } 62 | 63 | @SuppressWarnings("unused") // Used by stapler 64 | public ListBoxModel doFillApiTokenCredentialsIdItems( 65 | @AncestorInPath final Item item, 66 | @QueryParameter final String apiTokenCredentialsId, 67 | @QueryParameter final String gitLabUrl) { 68 | return CredentialsHelper.doFillApiTokenCredentialsIdItems( 69 | item, apiTokenCredentialsId, gitLabUrl); 70 | } 71 | 72 | @SuppressWarnings("unused") // Used by stapler 73 | public FormValidation doCheckApiTokenCredentialsId( 74 | @AncestorInPath final Item item, 75 | @QueryParameter final String value, 76 | @QueryParameter final String gitLabUrl) { 77 | return CredentialsHelper.doCheckApiTokenCredentialsId(item, value, gitLabUrl); 78 | } 79 | 80 | public String getGitLabUrl() { 81 | return gitLabUrl; 82 | } 83 | 84 | public boolean isIgnoreCertificateErrors() { 85 | return ignoreCertificateErrors; 86 | } 87 | 88 | @DataBoundSetter 89 | public void setIgnoreCertificateErrors(final boolean ignoreCertificateErrors) { 90 | this.ignoreCertificateErrors = ignoreCertificateErrors; 91 | } 92 | 93 | @DataBoundSetter 94 | @Deprecated 95 | public void setApiToken(final String apiToken) { 96 | throw new RuntimeException( 97 | "Setting raw API token is removed, set the apiTokenCredentialsId with a secret text credential instead!"); 98 | } 99 | 100 | public String getApiTokenCredentialsId() { 101 | return apiTokenCredentialsId; 102 | } 103 | 104 | @DataBoundSetter 105 | public void setMinSeverity(final SEVERITY minSeverity) { 106 | this.minSeverity = minSeverity; 107 | } 108 | 109 | public SEVERITY getMinSeverity() { 110 | return minSeverity; 111 | } 112 | 113 | @DataBoundSetter 114 | public void setApiTokenCredentialsId(final String apiTokenCredentialsId) { 115 | this.apiTokenCredentialsId = apiTokenCredentialsId; 116 | } 117 | 118 | public static long getSerialversionuid() { 119 | return serialVersionUID; 120 | } 121 | 122 | @DataBoundSetter 123 | public void setGitLabUrl(final String gitLabUrl) { 124 | this.gitLabUrl = gitLabUrl; 125 | } 126 | 127 | public boolean isApiTokenPrivate() { 128 | return apiTokenPrivate; 129 | } 130 | 131 | @DataBoundSetter 132 | public void setApiTokenPrivate(final boolean apiTokenPrivate) { 133 | this.apiTokenPrivate = apiTokenPrivate; 134 | } 135 | 136 | public boolean isAuthMethodHeader() { 137 | return authMethodHeader; 138 | } 139 | 140 | @DataBoundSetter 141 | public void setAuthMethodHeader(final boolean authMethodHeader) { 142 | this.authMethodHeader = authMethodHeader; 143 | } 144 | 145 | @Override 146 | public int hashCode() { 147 | final int prime = 31; 148 | int result = 1; 149 | result = 150 | prime * result + (apiTokenCredentialsId == null ? 0 : apiTokenCredentialsId.hashCode()); 151 | result = prime * result + (apiTokenPrivate ? 1231 : 1237); 152 | result = prime * result + (authMethodHeader ? 1231 : 1237); 153 | result = prime * result + (gitLabUrl == null ? 0 : gitLabUrl.hashCode()); 154 | result = prime * result + (ignoreCertificateErrors ? 1231 : 1237); 155 | result = prime * result + (minSeverity == null ? 0 : minSeverity.hashCode()); 156 | return result; 157 | } 158 | 159 | @Override 160 | public boolean equals(final Object obj) { 161 | if (this == obj) { 162 | return true; 163 | } 164 | if (obj == null) { 165 | return false; 166 | } 167 | if (getClass() != obj.getClass()) { 168 | return false; 169 | } 170 | final ViolationsToGitLabGlobalConfiguration other = (ViolationsToGitLabGlobalConfiguration) obj; 171 | if (apiTokenCredentialsId == null) { 172 | if (other.apiTokenCredentialsId != null) { 173 | return false; 174 | } 175 | } else if (!apiTokenCredentialsId.equals(other.apiTokenCredentialsId)) { 176 | return false; 177 | } 178 | if (apiTokenPrivate != other.apiTokenPrivate) { 179 | return false; 180 | } 181 | if (authMethodHeader != other.authMethodHeader) { 182 | return false; 183 | } 184 | if (gitLabUrl == null) { 185 | if (other.gitLabUrl != null) { 186 | return false; 187 | } 188 | } else if (!gitLabUrl.equals(other.gitLabUrl)) { 189 | return false; 190 | } 191 | if (ignoreCertificateErrors != other.ignoreCertificateErrors) { 192 | return false; 193 | } 194 | if (minSeverity != other.minSeverity) { 195 | return false; 196 | } 197 | return true; 198 | } 199 | 200 | @Override 201 | public String toString() { 202 | return "ViolationsToGitLabGlobalConfiguration [gitLabUrl=" 203 | + gitLabUrl 204 | + ", ignoreCertificateErrors=" 205 | + ignoreCertificateErrors 206 | + ", apiTokenPrivate=" 207 | + apiTokenPrivate 208 | + ", authMethodHeader=" 209 | + authMethodHeader 210 | + ", apiTokenCredentialsId=" 211 | + apiTokenCredentialsId 212 | + ", minSeverity=" 213 | + minSeverity 214 | + "]"; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/ViolationsToGitLabRecorder.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl; 2 | 3 | import static hudson.tasks.BuildStepMonitor.NONE; 4 | import static org.jenkinsci.plugins.jvctgl.perform.JvctglPerformer.jvctsPerform; 5 | 6 | import edu.umd.cs.findbugs.annotations.NonNull; 7 | import hudson.FilePath; 8 | import hudson.Launcher; 9 | import hudson.model.Run; 10 | import hudson.model.TaskListener; 11 | import hudson.tasks.BuildStepDescriptor; 12 | import hudson.tasks.BuildStepMonitor; 13 | import hudson.tasks.Publisher; 14 | import hudson.tasks.Recorder; 15 | import java.io.IOException; 16 | import jenkins.tasks.SimpleBuildStep; 17 | import org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfig; 18 | import org.kohsuke.stapler.DataBoundConstructor; 19 | 20 | public class ViolationsToGitLabRecorder extends Recorder implements SimpleBuildStep { 21 | 22 | public static final BuildStepDescriptor DESCRIPTOR = 23 | new ViolationsToGitLabDescriptor(); 24 | 25 | private ViolationsToGitLabConfig config; 26 | 27 | public ViolationsToGitLabRecorder() {} 28 | 29 | @DataBoundConstructor 30 | public ViolationsToGitLabRecorder(final ViolationsToGitLabConfig config) { 31 | this.config = config; 32 | } 33 | 34 | public ViolationsToGitLabConfig getConfig() { 35 | return this.config; 36 | } 37 | 38 | @Override 39 | public BuildStepDescriptor getDescriptor() { 40 | return DESCRIPTOR; 41 | } 42 | 43 | @Override 44 | public BuildStepMonitor getRequiredMonitorService() { 45 | return NONE; 46 | } 47 | 48 | @Override 49 | public void perform( 50 | @NonNull final Run build, 51 | @NonNull final FilePath filePath, 52 | @NonNull final Launcher launcher, 53 | @NonNull final TaskListener listener) 54 | throws InterruptedException, IOException { 55 | 56 | final ViolationsToGitLabConfig combinedConfig = new ViolationsToGitLabConfig(this.config); 57 | final ViolationsToGitLabGlobalConfiguration defaults = 58 | ViolationsToGitLabGlobalConfiguration.get(); 59 | 60 | combinedConfig.applyDefaults(defaults); 61 | 62 | jvctsPerform(combinedConfig, filePath, build, listener); 63 | } 64 | 65 | public void setConfig(final ViolationsToGitLabConfig config) { 66 | this.config = config; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/config/CredentialsHelper.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl.config; 2 | 3 | import static com.cloudbees.plugins.credentials.CredentialsMatchers.allOf; 4 | import static com.cloudbees.plugins.credentials.CredentialsMatchers.firstOrNull; 5 | import static com.cloudbees.plugins.credentials.CredentialsMatchers.withId; 6 | import static com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials; 7 | import static com.google.common.base.Strings.isNullOrEmpty; 8 | import static hudson.security.ACL.SYSTEM; 9 | 10 | import com.cloudbees.plugins.credentials.Credentials; 11 | import com.cloudbees.plugins.credentials.CredentialsMatchers; 12 | import com.cloudbees.plugins.credentials.CredentialsProvider; 13 | import com.cloudbees.plugins.credentials.common.StandardCredentials; 14 | import com.cloudbees.plugins.credentials.common.StandardListBoxModel; 15 | import com.cloudbees.plugins.credentials.common.StandardUsernameListBoxModel; 16 | import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; 17 | import com.cloudbees.plugins.credentials.domains.DomainRequirement; 18 | import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; 19 | import hudson.model.Item; 20 | import hudson.model.ItemGroup; 21 | import hudson.model.Queue; 22 | import hudson.model.queue.Tasks; 23 | import hudson.security.ACL; 24 | import hudson.util.FormValidation; 25 | import hudson.util.ListBoxModel; 26 | import java.util.List; 27 | import java.util.Optional; 28 | import jenkins.model.Jenkins; 29 | import org.acegisecurity.Authentication; 30 | import org.jenkinsci.plugins.plaincredentials.StringCredentials; 31 | 32 | /* Read more about credentials api here: https://github.com/jenkinsci/credentials-plugin/blob/master/docs/consumer.adoc */ 33 | public class CredentialsHelper { 34 | public static ListBoxModel doFillApiTokenCredentialsIdItems( 35 | final Item item, final String credentialsId, final String uri) { 36 | final StandardListBoxModel result = new StandardListBoxModel(); 37 | if (item == null) { 38 | if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) { 39 | return result.includeCurrentValue(credentialsId); 40 | } 41 | } else { 42 | if (!item.hasPermission(Item.EXTENDED_READ) 43 | && !item.hasPermission(CredentialsProvider.USE_ITEM)) { 44 | return result.includeCurrentValue(credentialsId); 45 | } 46 | } 47 | return result // 48 | .includeEmptyValue() // 49 | .includeMatchingAs( 50 | item instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task) item) : ACL.SYSTEM, 51 | item, 52 | StandardCredentials.class, 53 | URIRequirementBuilder.fromUri(uri).build(), 54 | CredentialsMatchers.anyOf(CredentialsMatchers.instanceOf(StringCredentials.class))) 55 | .includeCurrentValue(credentialsId); 56 | } 57 | 58 | public static FormValidation doCheckApiTokenCredentialsId( 59 | final Item item, final String credentialsId, final String uri) { 60 | if (item == null) { 61 | if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) { 62 | return FormValidation.ok(); 63 | } 64 | } else { 65 | if (!item.hasPermission(Item.EXTENDED_READ) 66 | && !item.hasPermission(CredentialsProvider.USE_ITEM)) { 67 | return FormValidation.ok(); 68 | } 69 | } 70 | if (isNullOrEmpty(credentialsId)) { 71 | return FormValidation.ok(); 72 | } 73 | if (!findApiTokenCredentials(item, credentialsId, uri).isPresent()) { 74 | return FormValidation.error("Cannot find currently selected credentials"); 75 | } 76 | return FormValidation.ok(); 77 | } 78 | 79 | public static Optional findApiTokenCredentials( 80 | final Item item, final String credentialsId, final String uri) { 81 | if (isNullOrEmpty(credentialsId)) { 82 | return Optional.empty(); 83 | } 84 | return Optional.ofNullable( 85 | CredentialsMatchers.firstOrNull( 86 | CredentialsProvider.lookupCredentials( 87 | StringCredentials.class, 88 | item, 89 | item instanceof Queue.Task 90 | ? Tasks.getAuthenticationOf((Queue.Task) item) 91 | : ACL.SYSTEM, 92 | URIRequirementBuilder.fromUri(uri).build()), 93 | CredentialsMatchers.allOf( 94 | CredentialsMatchers.withId(credentialsId), 95 | CredentialsMatchers.instanceOf(StringCredentials.class)))); 96 | } 97 | 98 | public static Optional findUserCredentials( 99 | final String apiTokenCredentialsId) { 100 | if (isNullOrEmpty(apiTokenCredentialsId)) { 101 | return Optional.empty(); 102 | } 103 | 104 | return Optional.ofNullable( 105 | firstOrNull( 106 | getAllCredentials(StandardUsernamePasswordCredentials.class), 107 | allOf(withId(apiTokenCredentialsId)))); 108 | } 109 | 110 | public static ListBoxModel doFillUserNamePasswordCredentialsIdItems() { 111 | final List credentials = 112 | getAllCredentials(StandardUsernamePasswordCredentials.class); 113 | return new StandardUsernameListBoxModel() // 114 | .includeEmptyValue() // 115 | .withAll(credentials); 116 | } 117 | 118 | private static List getAllCredentials(final Class type) { 119 | final ItemGroup itemGroup = null; 120 | final Authentication authentication = SYSTEM; 121 | final DomainRequirement domainRequirement = null; 122 | 123 | return lookupCredentials(type, itemGroup, authentication, domainRequirement); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/config/ViolationConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl.config; 2 | 3 | import edu.umd.cs.findbugs.annotations.NonNull; 4 | import hudson.Extension; 5 | import hudson.model.AbstractDescribableImpl; 6 | import hudson.model.Descriptor; 7 | import hudson.util.ListBoxModel; 8 | import java.io.Serializable; 9 | import org.kohsuke.accmod.Restricted; 10 | import org.kohsuke.accmod.restrictions.NoExternalUse; 11 | import org.kohsuke.stapler.DataBoundConstructor; 12 | import se.bjurr.violations.lib.reports.Parser; 13 | 14 | public class ViolationConfig extends AbstractDescribableImpl 15 | implements Serializable { 16 | private static final long serialVersionUID = 9009372864417543781L; 17 | 18 | private String pattern; 19 | private Parser parser; 20 | private String reporter; 21 | 22 | public ViolationConfig() {} 23 | 24 | @DataBoundConstructor 25 | public ViolationConfig(final Parser parser, final String pattern, final String reporter) { 26 | this.parser = parser; 27 | this.pattern = pattern; 28 | this.reporter = reporter; 29 | } 30 | 31 | public String getPattern() { 32 | return this.pattern; 33 | } 34 | 35 | public Parser getParser() { 36 | return this.parser; 37 | } 38 | 39 | public String getReporter() { 40 | if (this.reporter == null) { 41 | return this.parser.name(); 42 | } 43 | return reporter; 44 | } 45 | 46 | public void setPattern(final String pattern) { 47 | this.pattern = pattern; 48 | } 49 | 50 | public void setParser(final Parser parser) { 51 | this.parser = parser; 52 | } 53 | 54 | public void setReporter(final String reporter) { 55 | this.reporter = reporter; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "ViolationConfig [pattern=" 61 | + pattern 62 | + ", parser=" 63 | + parser 64 | + ", reporter=" 65 | + reporter 66 | + "]"; 67 | } 68 | 69 | @Extension 70 | public static class DescriptorImpl extends Descriptor { 71 | @NonNull 72 | @Override 73 | public String getDisplayName() { 74 | return "Violations Parser Config"; 75 | } 76 | 77 | @Restricted(NoExternalUse.class) 78 | public ListBoxModel doFillParserItems() { 79 | final ListBoxModel items = new ListBoxModel(); 80 | for (final Parser parser : Parser.values()) { 81 | items.add(parser.name()); 82 | } 83 | return items; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/config/ViolationsToGitLabConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl.config; 2 | 3 | import static com.google.common.base.Strings.isNullOrEmpty; 4 | import static se.bjurr.violations.lib.util.Utils.firstNonNull; 5 | 6 | import edu.umd.cs.findbugs.annotations.NonNull; 7 | import hudson.Extension; 8 | import hudson.model.AbstractDescribableImpl; 9 | import hudson.model.Descriptor; 10 | import hudson.model.Item; 11 | import hudson.util.FormValidation; 12 | import hudson.util.ListBoxModel; 13 | import java.io.Serializable; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Objects; 17 | import org.jenkinsci.plugins.jvctgl.ViolationsToGitLabGlobalConfiguration; 18 | import org.kohsuke.accmod.Restricted; 19 | import org.kohsuke.accmod.restrictions.NoExternalUse; 20 | import org.kohsuke.stapler.AncestorInPath; 21 | import org.kohsuke.stapler.DataBoundConstructor; 22 | import org.kohsuke.stapler.DataBoundSetter; 23 | import org.kohsuke.stapler.QueryParameter; 24 | import se.bjurr.violations.lib.model.SEVERITY; 25 | 26 | public class ViolationsToGitLabConfig extends AbstractDescribableImpl 27 | implements Serializable { 28 | private static final long serialVersionUID = 4851568645021422528L; 29 | 30 | private boolean commentOnlyChangedContent; 31 | private Integer commentOnlyChangedContentContext = 0; 32 | private boolean commentOnlyChangedFiles = true; 33 | private boolean createCommentWithAllSingleFileComments; 34 | private boolean createSingleFileComments; 35 | private List violationConfigs; 36 | private String gitLabUrl; 37 | private String projectId; 38 | private String mergeRequestIid; 39 | private String apiTokenCredentialsId; 40 | private Boolean ignoreCertificateErrors; 41 | private Boolean apiTokenPrivate; 42 | private Boolean authMethodHeader; 43 | private SEVERITY minSeverity; 44 | private Boolean keepOldComments; 45 | private String commentTemplate; 46 | private Boolean shouldSetWip; 47 | private String proxyUri; 48 | private String proxyCredentialsId; 49 | private Boolean enableLogging; 50 | private Integer maxNumberOfViolations; 51 | 52 | @DataBoundConstructor 53 | public ViolationsToGitLabConfig( 54 | final String gitLabUrl, 55 | final String projectId, 56 | final String mergeRequestIid, 57 | final String apiTokenCredentialsId) { 58 | this.gitLabUrl = gitLabUrl; 59 | this.projectId = projectId; 60 | this.mergeRequestIid = mergeRequestIid; 61 | this.keepOldComments = true; 62 | this.shouldSetWip = false; 63 | this.enableLogging = false; 64 | this.maxNumberOfViolations = null; 65 | this.apiTokenCredentialsId = apiTokenCredentialsId; 66 | } 67 | 68 | public ViolationsToGitLabConfig(final ViolationsToGitLabConfig rhs) { 69 | this.violationConfigs = rhs.violationConfigs; 70 | this.createCommentWithAllSingleFileComments = rhs.createCommentWithAllSingleFileComments; 71 | this.createSingleFileComments = rhs.createSingleFileComments; 72 | this.commentOnlyChangedContent = rhs.commentOnlyChangedContent; 73 | this.commentOnlyChangedContentContext = rhs.commentOnlyChangedContentContext; 74 | this.commentOnlyChangedFiles = rhs.commentOnlyChangedFiles; 75 | this.gitLabUrl = rhs.gitLabUrl; 76 | this.projectId = rhs.projectId; 77 | this.mergeRequestIid = rhs.mergeRequestIid; 78 | this.apiTokenCredentialsId = rhs.apiTokenCredentialsId; 79 | this.ignoreCertificateErrors = rhs.ignoreCertificateErrors; 80 | this.apiTokenPrivate = rhs.apiTokenPrivate; 81 | this.authMethodHeader = rhs.authMethodHeader; 82 | this.minSeverity = rhs.minSeverity; 83 | this.keepOldComments = rhs.keepOldComments; 84 | this.commentTemplate = rhs.commentTemplate; 85 | this.shouldSetWip = rhs.shouldSetWip; 86 | this.proxyUri = rhs.proxyUri; 87 | this.proxyCredentialsId = rhs.proxyCredentialsId; 88 | this.enableLogging = rhs.enableLogging; 89 | this.maxNumberOfViolations = rhs.maxNumberOfViolations; 90 | } 91 | 92 | public String getCommentTemplate() { 93 | return this.commentTemplate; 94 | } 95 | 96 | @DataBoundSetter 97 | public void setCommentTemplate(final String commentTemplate) { 98 | this.commentTemplate = commentTemplate; 99 | } 100 | 101 | public ViolationsToGitLabConfig() { 102 | this.violationConfigs = new ArrayList<>(); 103 | } 104 | 105 | public void applyDefaults(final ViolationsToGitLabGlobalConfiguration defaults) { 106 | if (defaults == null) { 107 | return; 108 | } 109 | 110 | if (isNullOrEmpty(this.gitLabUrl)) { 111 | this.gitLabUrl = defaults.getGitLabUrl(); 112 | } 113 | if (isNullOrEmpty(this.apiTokenCredentialsId)) { 114 | this.apiTokenCredentialsId = defaults.getApiTokenCredentialsId(); 115 | } 116 | if (this.ignoreCertificateErrors == null) { 117 | this.ignoreCertificateErrors = defaults.isIgnoreCertificateErrors(); 118 | } 119 | if (this.apiTokenPrivate == null) { 120 | this.apiTokenPrivate = defaults.isApiTokenPrivate(); 121 | } 122 | if (this.authMethodHeader == null) { 123 | this.authMethodHeader = defaults.isAuthMethodHeader(); 124 | } 125 | if (this.minSeverity == null) { 126 | this.minSeverity = defaults.getMinSeverity(); 127 | } 128 | } 129 | 130 | public String getGitLabUrl() { 131 | return this.gitLabUrl; 132 | } 133 | 134 | public boolean getCommentOnlyChangedContent() { 135 | return this.commentOnlyChangedContent; 136 | } 137 | 138 | public Integer getCommentOnlyChangedContentContext() { 139 | return this.commentOnlyChangedContentContext; 140 | } 141 | 142 | public boolean getCreateCommentWithAllSingleFileComments() { 143 | return this.createCommentWithAllSingleFileComments; 144 | } 145 | 146 | public boolean getCreateSingleFileComments() { 147 | return this.createSingleFileComments; 148 | } 149 | 150 | public List getViolationConfigs() { 151 | return this.violationConfigs; 152 | } 153 | 154 | @DataBoundSetter 155 | public void setIgnoreCertificateErrors(final Boolean ignoreCertificateErrors) { 156 | this.ignoreCertificateErrors = ignoreCertificateErrors; 157 | } 158 | 159 | @DataBoundSetter 160 | public void setApiTokenPrivate(final Boolean apiTokenPrivate) { 161 | this.apiTokenPrivate = apiTokenPrivate; 162 | } 163 | 164 | public void setMergeRequestIid(final String mergeRequestIid) { 165 | this.mergeRequestIid = mergeRequestIid; 166 | } 167 | 168 | public void setProjectId(final String projectId) { 169 | this.projectId = projectId; 170 | } 171 | 172 | @DataBoundSetter 173 | public void setAuthMethodHeader(final Boolean authMethodHeader) { 174 | this.authMethodHeader = authMethodHeader; 175 | } 176 | 177 | public String getProjectId() { 178 | return this.projectId; 179 | } 180 | 181 | public Boolean getAuthMethodHeader() { 182 | return this.authMethodHeader; 183 | } 184 | 185 | public Boolean getApiTokenPrivate() { 186 | return this.apiTokenPrivate; 187 | } 188 | 189 | public String getMergeRequestIid() { 190 | return this.mergeRequestIid; 191 | } 192 | 193 | public String getApiTokenCredentialsId() { 194 | return this.apiTokenCredentialsId; 195 | } 196 | 197 | public Boolean getIgnoreCertificateErrors() { 198 | return firstNonNull(this.ignoreCertificateErrors, false); 199 | } 200 | 201 | @DataBoundSetter 202 | public void setCreateCommentWithAllSingleFileComments( 203 | final boolean createCommentWithAllSingleFileComments) { 204 | this.createCommentWithAllSingleFileComments = createCommentWithAllSingleFileComments; 205 | } 206 | 207 | @DataBoundSetter 208 | public void setCreateSingleFileComments(final boolean createSingleFileComments) { 209 | this.createSingleFileComments = createSingleFileComments; 210 | } 211 | 212 | public SEVERITY getMinSeverity() { 213 | return this.minSeverity; 214 | } 215 | 216 | @DataBoundSetter 217 | public void setMinSeverity(final SEVERITY minSeverity) { 218 | this.minSeverity = minSeverity; 219 | } 220 | 221 | @DataBoundSetter 222 | public void setCommentOnlyChangedContent(final boolean commentOnlyChangedContent) { 223 | this.commentOnlyChangedContent = commentOnlyChangedContent; 224 | } 225 | 226 | @DataBoundSetter 227 | public void setCommentOnlyChangedContentContext(final Integer commentOnlyChangedContentContext) { 228 | this.commentOnlyChangedContentContext = commentOnlyChangedContentContext; 229 | } 230 | 231 | @DataBoundSetter 232 | public void setCommentOnlyChangedFiles(final boolean commentOnlyChangedFiles) { 233 | this.commentOnlyChangedFiles = commentOnlyChangedFiles; 234 | } 235 | 236 | public boolean getCommentOnlyChangedFiles() { 237 | return this.commentOnlyChangedFiles; 238 | } 239 | 240 | @DataBoundSetter 241 | public void setViolationConfigs(final List violationConfigs) { 242 | this.violationConfigs = violationConfigs; 243 | } 244 | 245 | public void setGitLabUrl(final String gitLabUrl) { 246 | this.gitLabUrl = gitLabUrl; 247 | } 248 | 249 | public void setApiTokenCredentialsId(final String apiTokenCredentialsId) { 250 | this.apiTokenCredentialsId = apiTokenCredentialsId; 251 | } 252 | 253 | @Override 254 | public boolean equals(final Object o) { 255 | if (this == o) { 256 | return true; 257 | } 258 | if (o == null || this.getClass() != o.getClass()) { 259 | return false; 260 | } 261 | final ViolationsToGitLabConfig that = (ViolationsToGitLabConfig) o; 262 | return this.commentOnlyChangedContent == that.commentOnlyChangedContent 263 | && Objects.equals( 264 | this.commentOnlyChangedContentContext, that.commentOnlyChangedContentContext) 265 | && this.commentOnlyChangedFiles == that.commentOnlyChangedFiles 266 | && this.createCommentWithAllSingleFileComments 267 | == that.createCommentWithAllSingleFileComments 268 | && this.createSingleFileComments == that.createSingleFileComments 269 | && Objects.equals(this.violationConfigs, that.violationConfigs) 270 | && Objects.equals(this.gitLabUrl, that.gitLabUrl) 271 | && Objects.equals(this.projectId, that.projectId) 272 | && Objects.equals(this.mergeRequestIid, that.mergeRequestIid) 273 | && Objects.equals(this.apiTokenCredentialsId, that.apiTokenCredentialsId) 274 | && Objects.equals(this.ignoreCertificateErrors, that.ignoreCertificateErrors) 275 | && Objects.equals(this.apiTokenPrivate, that.apiTokenPrivate) 276 | && Objects.equals(this.authMethodHeader, that.authMethodHeader) 277 | && this.minSeverity == that.minSeverity 278 | && Objects.equals(this.keepOldComments, that.keepOldComments) 279 | && Objects.equals(this.commentTemplate, that.commentTemplate) 280 | && Objects.equals(this.shouldSetWip, that.shouldSetWip) 281 | && Objects.equals(this.proxyUri, that.proxyUri) 282 | && Objects.equals(this.proxyCredentialsId, that.proxyCredentialsId) 283 | && Objects.equals(this.enableLogging, that.enableLogging); 284 | } 285 | 286 | @Override 287 | public int hashCode() { 288 | return Objects.hash( 289 | this.commentOnlyChangedContent, 290 | this.commentOnlyChangedContentContext, 291 | this.commentOnlyChangedFiles, 292 | this.createCommentWithAllSingleFileComments, 293 | this.createSingleFileComments, 294 | this.violationConfigs, 295 | this.gitLabUrl, 296 | this.projectId, 297 | this.mergeRequestIid, 298 | this.apiTokenCredentialsId, 299 | this.ignoreCertificateErrors, 300 | this.apiTokenPrivate, 301 | this.authMethodHeader, 302 | this.minSeverity, 303 | this.keepOldComments, 304 | this.commentTemplate, 305 | this.shouldSetWip, 306 | this.proxyUri, 307 | this.proxyCredentialsId, 308 | this.enableLogging); 309 | } 310 | 311 | @Override 312 | public String toString() { 313 | return "ViolationsToGitLabConfig{" 314 | + "commentOnlyChangedContent=" 315 | + this.commentOnlyChangedContent 316 | + "commentOnlyChangedContentContext=" 317 | + this.commentOnlyChangedContentContext 318 | + "commentOnlyChangedFiles=" 319 | + this.commentOnlyChangedFiles 320 | + ", createCommentWithAllSingleFileComments=" 321 | + this.createCommentWithAllSingleFileComments 322 | + ", createSingleFileComments=" 323 | + this.createSingleFileComments 324 | + ", violationConfigs=" 325 | + this.violationConfigs 326 | + ", gitLabUrl='" 327 | + this.gitLabUrl 328 | + '\'' 329 | + ", projectId='" 330 | + this.projectId 331 | + '\'' 332 | + ", mergeRequestIid='" 333 | + this.mergeRequestIid 334 | + '\'' 335 | + ", apiTokenCredentialsId='" 336 | + this.apiTokenCredentialsId 337 | + '\'' 338 | + ", ignoreCertificateErrors=" 339 | + this.ignoreCertificateErrors 340 | + ", apiTokenPrivate=" 341 | + this.apiTokenPrivate 342 | + ", authMethodHeader=" 343 | + this.authMethodHeader 344 | + ", minSeverity=" 345 | + this.minSeverity 346 | + ", keepOldComments=" 347 | + this.keepOldComments 348 | + ", commentTemplate='" 349 | + this.commentTemplate 350 | + '\'' 351 | + ", shouldSetWip=" 352 | + this.shouldSetWip 353 | + '}'; 354 | } 355 | 356 | public Boolean getKeepOldComments() { 357 | return this.keepOldComments; 358 | } 359 | 360 | public Boolean getShouldSetWip() { 361 | return this.shouldSetWip; 362 | } 363 | 364 | @DataBoundSetter 365 | public void setShouldSetWip(final Boolean shouldSetWip) { 366 | this.shouldSetWip = shouldSetWip; 367 | } 368 | 369 | @DataBoundSetter 370 | public void setKeepOldComments(final Boolean keepOldComments) { 371 | this.keepOldComments = keepOldComments; 372 | } 373 | 374 | @DataBoundSetter 375 | public void setProxyUri(final String proxyUri) { 376 | this.proxyUri = proxyUri; 377 | } 378 | 379 | public String getProxyUri() { 380 | return this.proxyUri; 381 | } 382 | 383 | @DataBoundSetter 384 | public void setProxyCredentialsId(final String proxyCredentialsId) { 385 | this.proxyCredentialsId = proxyCredentialsId; 386 | } 387 | 388 | public String getProxyCredentialsId() { 389 | return this.proxyCredentialsId; 390 | } 391 | 392 | @DataBoundSetter 393 | public void setEnableLogging(final Boolean enableLogging) { 394 | this.enableLogging = enableLogging; 395 | } 396 | 397 | public Boolean getEnableLogging() { 398 | return this.enableLogging; 399 | } 400 | 401 | public Integer getMaxNumberOfViolations() { 402 | return this.maxNumberOfViolations; 403 | } 404 | 405 | @DataBoundSetter 406 | public void setMaxNumberOfViolations(final Integer maxNumberOfViolations) { 407 | this.maxNumberOfViolations = maxNumberOfViolations; 408 | } 409 | 410 | @Extension 411 | public static class DescriptorImpl extends Descriptor { 412 | @NonNull 413 | @Override 414 | public String getDisplayName() { 415 | return "Violations To GitLab Server Config"; 416 | } 417 | 418 | @Restricted(NoExternalUse.class) 419 | public ListBoxModel doFillMinSeverityItems() { 420 | final ListBoxModel items = new ListBoxModel(); 421 | items.add("Default, Global Config or Info", ""); 422 | for (final SEVERITY severity : SEVERITY.values()) { 423 | items.add(severity.name()); 424 | } 425 | return items; 426 | } 427 | 428 | @SuppressWarnings("unused") // Used by stapler 429 | public ListBoxModel doFillProxyCredentialsIdItems( 430 | @AncestorInPath final Item item, 431 | @QueryParameter final String apiTokenCredentialsId, 432 | @QueryParameter final String gitLabUrl) { 433 | return CredentialsHelper.doFillUserNamePasswordCredentialsIdItems(); 434 | } 435 | 436 | @SuppressWarnings("unused") // Used by stapler 437 | public ListBoxModel doFillApiTokenCredentialsIdItems( 438 | @AncestorInPath final Item item, 439 | @QueryParameter final String apiTokenCredentialsId, 440 | @QueryParameter final String gitLabUrl) { 441 | return CredentialsHelper.doFillApiTokenCredentialsIdItems( 442 | item, apiTokenCredentialsId, gitLabUrl); 443 | } 444 | 445 | @SuppressWarnings("unused") // Used by stapler 446 | public FormValidation doCheckApiTokenCredentialsId( 447 | @AncestorInPath final Item item, 448 | @QueryParameter final String value, 449 | @QueryParameter final String gitLabUrl) { 450 | return CredentialsHelper.doCheckApiTokenCredentialsId(item, value, gitLabUrl); 451 | } 452 | } 453 | } 454 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/config/ViolationsToGitLabConfigHelper.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl.config; 2 | 3 | public class ViolationsToGitLabConfigHelper { 4 | public static final String FIELD_COMMENTONLYCHANGEDCONTENT = "commentOnlyChangedContent"; 5 | public static final String FIELD_COMMENTONLYCHANGEDCONTENTCONTEXT = 6 | "commentOnlyChangedContentContext"; 7 | public static final String FIELD_CREATECOMMENTWITHALLSINGLEFILECOMMENTS = 8 | "createCommentWithAllSingleFileComments"; 9 | public static final String FIELD_CREATESINGLEFILECOMMENTS = "createSingleFileComments"; 10 | public static final String FIELD_GITLABURL = "gitLabUrl"; 11 | public static final String FIELD_PATTERN = "pattern"; 12 | public static final String FIELD_REPORTER = "reporter"; 13 | public static final String FIELD_PARSER = "parser"; 14 | public static final String FIELD_PROJECTID = "projectId"; 15 | public static final String FIELD_MERGEREQUESTIID = "mergeRequestIid"; 16 | public static final String FIELD_APITOKENCREDENTIALSID = "apiTokenCredentialsId"; 17 | public static final String FIELD_IGNORECERTIFICATEERRORS = "ignoreCertificateErrors"; 18 | public static final String FIELD_APITOKENPRIVATE = "apiTokenPrivate"; 19 | public static final String FIELD_AUTHMETHODHEADER = "authMethodHeader"; 20 | public static final String FIELD_MINSEVERITY = "minSeverity"; 21 | public static final String FIELD_KEEP_OLD_COMMENTS = "keepOldComments"; 22 | public static final String FIELD_SHOULD_SET_WIP = "shouldSetWip"; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctgl/perform/JvctglPerformer.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl.perform; 2 | 3 | import static com.google.common.base.Strings.isNullOrEmpty; 4 | import static com.google.common.base.Strings.nullToEmpty; 5 | import static java.util.logging.Level.SEVERE; 6 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_APITOKENCREDENTIALSID; 7 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_APITOKENPRIVATE; 8 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_AUTHMETHODHEADER; 9 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_COMMENTONLYCHANGEDCONTENT; 10 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_COMMENTONLYCHANGEDCONTENTCONTEXT; 11 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_CREATECOMMENTWITHALLSINGLEFILECOMMENTS; 12 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_GITLABURL; 13 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_IGNORECERTIFICATEERRORS; 14 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_KEEP_OLD_COMMENTS; 15 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_MERGEREQUESTIID; 16 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_MINSEVERITY; 17 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_PROJECTID; 18 | import static org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfigHelper.FIELD_SHOULD_SET_WIP; 19 | import static se.bjurr.violations.comments.gitlab.lib.ViolationCommentsToGitLabApi.violationCommentsToGitLabApi; 20 | import static se.bjurr.violations.lib.ViolationsApi.violationsApi; 21 | 22 | import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; 23 | import com.google.common.annotations.VisibleForTesting; 24 | import hudson.EnvVars; 25 | import hudson.FilePath; 26 | import hudson.FilePath.FileCallable; 27 | import hudson.model.Run; 28 | import hudson.model.TaskListener; 29 | import hudson.remoting.VirtualChannel; 30 | import java.io.File; 31 | import java.io.IOException; 32 | import java.io.PrintStream; 33 | import java.io.PrintWriter; 34 | import java.io.StringWriter; 35 | import java.net.MalformedURLException; 36 | import java.util.Optional; 37 | import java.util.Set; 38 | import java.util.TreeSet; 39 | import java.util.logging.Level; 40 | import java.util.logging.Logger; 41 | import org.gitlab4j.api.Constants.TokenType; 42 | import org.jenkinsci.plugins.jvctgl.config.CredentialsHelper; 43 | import org.jenkinsci.plugins.jvctgl.config.ViolationConfig; 44 | import org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfig; 45 | import org.jenkinsci.plugins.plaincredentials.StringCredentials; 46 | import org.jenkinsci.remoting.RoleChecker; 47 | import se.bjurr.violations.lib.ViolationsLogger; 48 | import se.bjurr.violations.lib.model.SEVERITY; 49 | import se.bjurr.violations.lib.model.Violation; 50 | import se.bjurr.violations.lib.reports.Parser; 51 | import se.bjurr.violations.lib.util.Filtering; 52 | 53 | public class JvctglPerformer { 54 | private static Logger LOG = Logger.getLogger(JvctglPerformer.class.getSimpleName()); 55 | 56 | @VisibleForTesting 57 | public static void doPerform( 58 | final ViolationsToGitLabConfig config, 59 | final String apiToken, 60 | final File workspace, 61 | final TaskListener listener, 62 | final String proxyUser, 63 | final String proxyPassword) 64 | throws MalformedURLException { 65 | if (config.getMergeRequestIid() == null) { 66 | listener 67 | .getLogger() 68 | .println( 69 | "No merge request id defined, will not send violation comments. " 70 | + "\n\nPossible cause might be: mergeRequestId changed in version 2.0 and is now mergeRequestIid. " 71 | + "If you just updated the plugin, mergeRequestIid should have the same value that you previously used for mergeRequestId. " 72 | + "It is named wrong in the Java GitLab API and that wrong name has spread to this API." 73 | + "\n\n"); 74 | return; 75 | } 76 | 77 | final ViolationsLogger violationsLogger = 78 | new ViolationsLogger() { 79 | @Override 80 | public void log(final Level level, final String string) { 81 | if (!config.getEnableLogging()) { 82 | return; 83 | } 84 | Logger.getLogger(JvctglPerformer.class.getName()).log(level, string); 85 | if (level != Level.FINE) { 86 | listener.getLogger().println(level + " " + string); 87 | } 88 | } 89 | 90 | @Override 91 | public void log(final Level level, final String string, final Throwable t) { 92 | if (!config.getEnableLogging()) { 93 | return; 94 | } 95 | Logger.getLogger(JvctglPerformer.class.getName()).log(level, string); 96 | final StringWriter sw = new StringWriter(); 97 | t.printStackTrace(new PrintWriter(sw)); 98 | listener.getLogger().println(level + " " + string + "\n" + sw.toString()); 99 | } 100 | }; 101 | 102 | final Set allParsedViolations = new TreeSet<>(); 103 | for (final ViolationConfig violationConfig : config.getViolationConfigs()) { 104 | if (!isNullOrEmpty(violationConfig.getPattern())) { 105 | Set parsedViolations = 106 | violationsApi() 107 | .withViolationsLogger(violationsLogger) // 108 | .findAll(violationConfig.getParser()) // 109 | .withReporter(violationConfig.getReporter()) // 110 | .inFolder(workspace.getAbsolutePath()) // 111 | .withPattern(violationConfig.getPattern()) // 112 | .violations(); 113 | final SEVERITY minSeverity = config.getMinSeverity(); 114 | if (minSeverity != null) { 115 | parsedViolations = Filtering.withAtLEastSeverity(parsedViolations, minSeverity); 116 | } 117 | 118 | allParsedViolations.addAll(parsedViolations); 119 | listener 120 | .getLogger() 121 | .println( 122 | "Found " + parsedViolations.size() + " violations from " + violationConfig + "."); 123 | } 124 | } 125 | 126 | final String hostUrl = config.getGitLabUrl(); 127 | final String projectId = config.getProjectId(); 128 | final String mergeRequestIid = config.getMergeRequestIid(); 129 | 130 | listener 131 | .getLogger() 132 | .println("Will comment PR " + hostUrl + " " + projectId + " " + mergeRequestIid); 133 | 134 | try { 135 | final TokenType tokenType = 136 | config.getApiTokenPrivate() ? TokenType.PRIVATE : TokenType.ACCESS; 137 | final Long mergeRequestIidInteger = Long.parseLong(mergeRequestIid); 138 | final boolean shouldKeepOldComments = config.getKeepOldComments(); 139 | final boolean shouldSetWIP = config.getShouldSetWip(); 140 | final String commentTemplate = config.getCommentTemplate(); 141 | 142 | violationCommentsToGitLabApi() 143 | .setProxyServer(config.getProxyUri()) 144 | .setProxyUser(proxyUser) 145 | .setProxyPassword(proxyPassword) 146 | .setHostUrl(hostUrl) 147 | .setProjectId(projectId) 148 | .setMergeRequestIid(mergeRequestIidInteger) 149 | .setApiToken(apiToken) 150 | .setTokenType(tokenType) 151 | .setCommentOnlyChangedContent(config.getCommentOnlyChangedContent()) 152 | .setCommentOnlyChangedContentContext(config.getCommentOnlyChangedContentContext()) 153 | .withShouldCommentOnlyChangedFiles(config.getCommentOnlyChangedFiles()) 154 | .setCreateCommentWithAllSingleFileComments( 155 | config.getCreateCommentWithAllSingleFileComments()) 156 | .setCreateSingleFileComments(config.getCreateSingleFileComments()) 157 | .setIgnoreCertificateErrors(config.getIgnoreCertificateErrors()) // 158 | .setViolations(allParsedViolations) // 159 | .setShouldKeepOldComments(shouldKeepOldComments) // 160 | .setShouldSetWIP(shouldSetWIP) // 161 | .setCommentTemplate(commentTemplate) // 162 | .setViolationsLogger(violationsLogger) // 163 | .setMaxNumberOfViolations(config.getMaxNumberOfViolations()) // 164 | .toPullRequest(); 165 | } catch (final Exception e) { 166 | Logger.getLogger(JvctglPerformer.class.getName()).log(SEVERE, "", e); 167 | final StringWriter sw = new StringWriter(); 168 | e.printStackTrace(new PrintWriter(sw)); 169 | listener.getLogger().println(sw.toString()); 170 | } 171 | } 172 | 173 | /** Makes sure any Jenkins variable, used in the configuration fields, are evaluated. */ 174 | @VisibleForTesting 175 | static ViolationsToGitLabConfig expand( 176 | final ViolationsToGitLabConfig config, final EnvVars environment) { 177 | final ViolationsToGitLabConfig expanded = new ViolationsToGitLabConfig(); 178 | expanded.setGitLabUrl(environment.expand(config.getGitLabUrl())); 179 | expanded.setProjectId(environment.expand(config.getProjectId())); 180 | expanded.setMergeRequestIid(environment.expand(config.getMergeRequestIid())); 181 | 182 | expanded.setApiTokenCredentialsId(config.getApiTokenCredentialsId()); 183 | 184 | expanded.setAuthMethodHeader(config.getAuthMethodHeader()); 185 | expanded.setApiTokenPrivate(config.getApiTokenPrivate()); 186 | expanded.setIgnoreCertificateErrors(config.getIgnoreCertificateErrors()); 187 | 188 | expanded.setCommentOnlyChangedContent(config.getCommentOnlyChangedContent()); 189 | expanded.setCommentOnlyChangedContentContext(config.getCommentOnlyChangedContentContext()); 190 | expanded.setCommentOnlyChangedFiles(config.getCommentOnlyChangedFiles()); 191 | expanded.setCreateCommentWithAllSingleFileComments( 192 | config.getCreateCommentWithAllSingleFileComments()); 193 | expanded.setCreateSingleFileComments(config.getCreateSingleFileComments()); 194 | expanded.setMinSeverity(config.getMinSeverity()); 195 | expanded.setShouldSetWip(config.getShouldSetWip()); 196 | expanded.setKeepOldComments(config.getKeepOldComments()); 197 | expanded.setCommentTemplate(config.getCommentTemplate()); 198 | 199 | expanded.setProxyUri(config.getProxyUri()); 200 | expanded.setProxyCredentialsId(config.getProxyCredentialsId()); 201 | 202 | expanded.setEnableLogging(config.getEnableLogging()); 203 | 204 | expanded.setMaxNumberOfViolations(config.getMaxNumberOfViolations()); 205 | 206 | for (final ViolationConfig violationConfig : config.getViolationConfigs()) { 207 | final String pattern = environment.expand(violationConfig.getPattern()); 208 | final String reporter = violationConfig.getReporter(); 209 | final Parser parser = violationConfig.getParser(); 210 | if (isNullOrEmpty(pattern) || parser == null) { 211 | LOG.fine("Ignoring violationConfig because of null/empty -values: " + violationConfig); 212 | continue; 213 | } 214 | final ViolationConfig p = new ViolationConfig(); 215 | p.setPattern(pattern); 216 | p.setReporter(reporter); 217 | p.setParser(parser); 218 | expanded.getViolationConfigs().add(p); 219 | } 220 | return expanded; 221 | } 222 | 223 | public static void jvctsPerform( 224 | final ViolationsToGitLabConfig configUnexpanded, 225 | final FilePath fp, 226 | final Run build, 227 | final TaskListener listener) { 228 | try { 229 | final EnvVars env = build.getEnvironment(listener); 230 | final ViolationsToGitLabConfig configExpanded = expand(configUnexpanded, env); 231 | listener.getLogger().println("---"); 232 | listener.getLogger().println("--- Violation Comments to GitLab ---"); 233 | listener.getLogger().println("---"); 234 | logConfiguration(configExpanded, listener); 235 | 236 | final Optional apiTokenCredentials = 237 | CredentialsHelper.findApiTokenCredentials( 238 | build.getParent(), 239 | configExpanded.getApiTokenCredentialsId(), 240 | configExpanded.getGitLabUrl()); 241 | if (!apiTokenCredentials.isPresent()) { 242 | throw new RuntimeException("API Token not set!"); 243 | } 244 | final String apiToken = apiTokenCredentials.get().getSecret().getPlainText(); 245 | 246 | String proxyUserValue = ""; 247 | String proxyPasswordValue = ""; 248 | final Optional proxyCredentials = 249 | CredentialsHelper.findUserCredentials(configExpanded.getProxyCredentialsId()); 250 | if (proxyCredentials.isPresent()) { 251 | proxyUserValue = proxyCredentials.get().getUsername(); 252 | proxyPasswordValue = proxyCredentials.get().getPassword().getPlainText(); 253 | } 254 | final String proxyUser = proxyUserValue; 255 | final String proxyPassword = proxyPasswordValue; 256 | 257 | listener.getLogger().println("Running Violation Comments To GitLab"); 258 | listener.getLogger().println("Merge request: " + configExpanded.getMergeRequestIid()); 259 | 260 | fp.act( 261 | new FileCallable() { 262 | 263 | private static final long serialVersionUID = -7686563245942529513L; 264 | 265 | @Override 266 | public void checkRoles(final RoleChecker checker) throws SecurityException {} 267 | 268 | @Override 269 | public Void invoke(final File workspace, final VirtualChannel channel) 270 | throws IOException, InterruptedException { 271 | listener.getLogger().println("Workspace: " + workspace.getAbsolutePath()); 272 | doPerform(configExpanded, apiToken, workspace, listener, proxyUser, proxyPassword); 273 | return null; 274 | } 275 | }); 276 | } catch (final Exception e) { 277 | Logger.getLogger(JvctglPerformer.class.getName()).log(SEVERE, "", e); 278 | final StringWriter sw = new StringWriter(); 279 | e.printStackTrace(new PrintWriter(sw)); 280 | listener.getLogger().println(sw.toString()); 281 | return; 282 | } 283 | } 284 | 285 | private static void logConfiguration( 286 | final ViolationsToGitLabConfig config, final TaskListener listener) { 287 | final PrintStream logger = listener.getLogger(); 288 | logger.println(FIELD_GITLABURL + ": " + config.getGitLabUrl()); 289 | logger.println(FIELD_PROJECTID + ": " + config.getProjectId()); 290 | logger.println(FIELD_MERGEREQUESTIID + ": " + config.getMergeRequestIid()); 291 | 292 | logger.println( 293 | FIELD_APITOKENCREDENTIALSID + ": " + !isNullOrEmpty(config.getApiTokenCredentialsId())); 294 | logger.println(FIELD_IGNORECERTIFICATEERRORS + ": " + config.getIgnoreCertificateErrors()); 295 | logger.println(FIELD_APITOKENPRIVATE + ": " + config.getApiTokenPrivate()); 296 | logger.println(FIELD_AUTHMETHODHEADER + ": " + config.getAuthMethodHeader()); 297 | 298 | logger.println( 299 | FIELD_CREATECOMMENTWITHALLSINGLEFILECOMMENTS 300 | + ": " 301 | + config.getCreateCommentWithAllSingleFileComments()); 302 | logger.println("createSingleFileComments" + ": " + config.getCreateSingleFileComments()); 303 | logger.println(FIELD_COMMENTONLYCHANGEDCONTENT + ": " + config.getCommentOnlyChangedContent()); 304 | logger.println( 305 | FIELD_COMMENTONLYCHANGEDCONTENTCONTEXT 306 | + ": " 307 | + config.getCommentOnlyChangedContentContext()); 308 | logger.println("commentOnlyChangedFiles: " + config.getCommentOnlyChangedFiles()); 309 | 310 | logger.println("maxNumberOfViolations:" + config.getMaxNumberOfViolations()); 311 | logger.println(FIELD_MINSEVERITY + ": " + config.getMinSeverity()); 312 | logger.println(FIELD_KEEP_OLD_COMMENTS + ": " + config.getKeepOldComments()); 313 | logger.println(FIELD_SHOULD_SET_WIP + ": " + config.getShouldSetWip()); 314 | logger.println("commentTemplate: " + config.getCommentTemplate()); 315 | logger.println("proxyUri: " + config.getProxyUri()); 316 | logger.println( 317 | "proxyCredentialsId: " 318 | + (nullToEmpty(config.getProxyCredentialsId()).isEmpty() ? "no" : "yes")); 319 | 320 | for (final ViolationConfig violationConfig : config.getViolationConfigs()) { 321 | logger.println(violationConfig.getParser() + " with pattern " + violationConfig.getPattern()); 322 | } 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | Finds violations reported by code analyzers and comments GitLab merge requests with them. 4 |
5 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctgl/ViolationsToGitLabGlobalConfiguration/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 14 | 15 | A secret text credential. 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctgl/ViolationsToGitLabGlobalConfiguration/help.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | See Violation Comments to GitLab Plugin for details on how to configure and use this plugin. 4 |

5 |
6 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctgl/ViolationsToGitLabRecorder/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctgl/ViolationsToGitLabRecorder/help.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | See Violation Comments to GitLab Plugin for details on how to configure and use this plugin. 4 |

5 | 6 |

7 | Pattern is a regular expression for matching report files. For example .*/findbugs/.*\.xml$ matches xml-files, in a folder named findbugs, anywhere in workspace. 8 |

9 |
10 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctgl/config/ViolationConfig/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctgl/config/ViolationsToGitLabConfig/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 14 | A secret text credential. Will default to global config. 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | A username/password credential. 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | You may want to use one of these to get the values: 36 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | If there are more violations than this, they will be ignored. Leave empty to include all violations. 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | This is the number of context lines around the changes that you want to comment on. 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | Optional, leave empty for default template. It is documented here. 112 | 113 | 114 | 115 | 116 | 117 | 118 | 132 | 133 |
119 | Violations configuration 120 |
    121 |
  • 122 | The pattern may be, for example, .*/findbugs/.*\.xml$ to match xml-files, in a folder named findbugs, anywhere in workspace. You may try Regulex for creating your regexp.
    123 |
    124 | Some parsers can parse output from several reporters, it is documented here. Missing a parser? Open an issue here.
    125 |
    126 |
  • 127 |
  • 128 | The reporter is optional. The parser name will be used if no reporter specified. It is intended to be the name of the tool reporting the violations. For example if Detekt is used to produce a checkstyle-report, then you may specify Detekt in the reporter field.
    129 |
  • 130 |
131 |
134 |
135 | 136 | 137 | 138 | 139 |
140 | 141 |
142 |
143 |
144 |
145 | 146 |
147 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/jvctgl/config/ViolationsToGitLabConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl.config; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | import uk.co.jemos.podam.api.PodamFactoryImpl; 7 | 8 | public class ViolationsToGitLabConfigTest { 9 | 10 | @Test 11 | public void testThatCopyConstructorCopiesEverything() { 12 | ViolationsToGitLabConfig original = 13 | new PodamFactoryImpl().manufacturePojo(ViolationsToGitLabConfig.class); 14 | ViolationsToGitLabConfig actual = new ViolationsToGitLabConfig(original); 15 | String message = "All config should be copied."; 16 | assertEquals(message, original, actual); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/jvctgl/perform/JvctglPerformerTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctgl.perform; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import hudson.EnvVars; 6 | import org.jenkinsci.plugins.jvctgl.config.ViolationsToGitLabConfig; 7 | import org.junit.Test; 8 | import uk.co.jemos.podam.api.PodamFactoryImpl; 9 | 10 | public class JvctglPerformerTest { 11 | 12 | @Test 13 | public void testThatAllVariablesAreExpanded() { 14 | ViolationsToGitLabConfig original = 15 | new PodamFactoryImpl().manufacturePojo(ViolationsToGitLabConfig.class); 16 | 17 | ViolationsToGitLabConfig expanded = 18 | JvctglPerformer.expand( 19 | original, 20 | new EnvVars() { 21 | private static final long serialVersionUID = 3950742092801432326L; 22 | 23 | @Override 24 | public String expand(String s) { 25 | return s; 26 | } 27 | }); 28 | 29 | String message = "All variables should be expanded"; 30 | assertEquals(message, original.toString(), expanded.toString()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/se/bjurr/violations/UpdateReadmeTest.java: -------------------------------------------------------------------------------- 1 | package se.bjurr.violations; 2 | 3 | import java.io.IOException; 4 | import org.junit.Test; 5 | import se.bjurr.violations.lib.util.Utils; 6 | 7 | public class UpdateReadmeTest { 8 | 9 | @Test 10 | public void doUpdateReadmeWithReporters() throws IOException { 11 | Utils.updateReadmeWithReporters(); 12 | } 13 | } 14 | --------------------------------------------------------------------------------