├── .gitattributes ├── .github └── FUNDING.yml ├── src ├── main │ ├── webapp │ │ └── help │ │ │ ├── credentials.html │ │ │ └── oauth.html │ ├── resources │ │ └── org │ │ │ └── jenkinsci │ │ │ └── plugins │ │ │ └── jvctg │ │ │ ├── ViolationsToGitHubConfiguration │ │ │ ├── help.html │ │ │ └── config.jelly │ │ │ ├── ViolationsToGitHubRecorder │ │ │ ├── config.jelly │ │ │ └── help.html │ │ │ └── config │ │ │ ├── ViolationConfig │ │ │ └── config.jelly │ │ │ └── ViolationsToGitHubConfig │ │ │ └── config.jelly │ └── java │ │ └── org │ │ └── jenkinsci │ │ └── plugins │ │ └── jvctg │ │ ├── config │ │ ├── ViolationsToGitHubConfigHelper.java │ │ ├── ViolationConfig.java │ │ ├── CredentialsHelper.java │ │ └── ViolationsToGitHubConfig.java │ │ ├── ViolationsToGitHubDescriptor.java │ │ ├── ViolationsToGitHubRecorder.java │ │ ├── ViolationsToGitHubConfiguration.java │ │ └── perform │ │ └── JvctgPerformer.java └── test │ └── java │ ├── se │ └── bjurr │ │ └── violations │ │ └── UpdateReadmeTest.java │ └── org │ └── jenkinsci │ └── plugins │ └── jvctg │ ├── config │ └── ViolationsToGitHubConfigTest.java │ └── perform │ └── JvctgPerformerTest.java ├── Jenkinsfile ├── sandbox ├── jenkins-postbuildmenu.png ├── github-pr-diff-comment.png ├── jenkins-postbuildaction.png ├── findbugs-github-pr-file-comment.png └── violations-test.jenkinsfile ├── run.sh ├── release.sh ├── debug.sh ├── logging.properties ├── .gitignore ├── .travis.yml ├── changelog.mustache ├── ISSUE_TEMPLATE ├── LICENSE ├── pom.xml ├── README.md └── CHANGELOG.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.java text eol=lf 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [tomasbjerre] 2 | -------------------------------------------------------------------------------- /src/main/webapp/help/credentials.html: -------------------------------------------------------------------------------- 1 |

Supports Secret Text for OAuth Token and Username Password credentials

2 | -------------------------------------------------------------------------------- /src/main/webapp/help/oauth.html: -------------------------------------------------------------------------------- 1 |

Recommended to use credentials instead you can use Secret Text credential for OAuth2 Token

2 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | /* `buildPlugin` step provided by: https://github.com/jenkins-infra/pipeline-library */ 4 | 5 | buildPlugin() 6 | -------------------------------------------------------------------------------- /sandbox/jenkins-postbuildmenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/violation-comments-to-github-plugin/HEAD/sandbox/jenkins-postbuildmenu.png -------------------------------------------------------------------------------- /sandbox/github-pr-diff-comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/violation-comments-to-github-plugin/HEAD/sandbox/github-pr-diff-comment.png -------------------------------------------------------------------------------- /sandbox/jenkins-postbuildaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/violation-comments-to-github-plugin/HEAD/sandbox/jenkins-postbuildaction.png -------------------------------------------------------------------------------- /sandbox/findbugs-github-pr-file-comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/violation-comments-to-github-plugin/HEAD/sandbox/findbugs-github-pr-file-comment.png -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mvn versions:update-properties 3 | mvn -q hpi:run -Djava.util.logging.config.file=logging.properties -Djenkins.version=2.263.2 -Denforcer.skip=true 4 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mvn versions:update-properties 3 | mvn release:prepare release:perform -B || exit 1 4 | mvn package 5 | git commit -a --amend --no-edit 6 | git push -f 7 | -------------------------------------------------------------------------------- /debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mvn versions:update-properties 3 | mvnDebug -q hpi:run -Djava.util.logging.config.file=logging.properties -Djenkins.version=2.121.3 -Denforcer.skip=true 4 | 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.versionsBackup 2 | .factorypath 3 | target 4 | .project 5 | .settings 6 | .classpath 7 | *.class 8 | *.log 9 | *.bak 10 | *~ 11 | work* 12 | bin 13 | gradle 14 | gradlew 15 | .gradle 16 | build 17 | .okhttpcache 18 | .idea/ 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk7 4 | - oraclejdk7 5 | - oraclejdk8 6 | before_script: 7 | - mkdir -p ~/.m2 8 | - cp sandbox/settings.xml ~/.m2/settings.xml 9 | script: 10 | - ./build.sh 11 | notifications: 12 | email: false 13 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctg/ViolationsToGitHubConfiguration/help.html: -------------------------------------------------------------------------------- 1 |
2 |

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

5 |
6 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctg/ViolationsToGitHubRecorder/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctg/ViolationsToGitHubRecorder/help.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | See Violation Comments to GitHub 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/jvctg/config/ViolationConfig/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/jvctg/config/ViolationsToGitHubConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg.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 ViolationsToGitHubConfigTest { 9 | 10 | @Test 11 | public void testThatCopyConstructorCopiesEverything() { 12 | ViolationsToGitHubConfig original = 13 | new PodamFactoryImpl().manufacturePojo(ViolationsToGitHubConfig.class); 14 | ViolationsToGitHubConfig actual = new ViolationsToGitHubConfig(original); 15 | assertEquals(original, actual); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /changelog.mustache: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | {{#tags}} 4 | ## {{name}} 5 | {{#issues}} 6 | {{#hasIssue}} 7 | {{#hasLink}} 8 | ### {{name}} [{{issue}}]({{link}}) {{title}} 9 | {{/hasLink}} 10 | {{^hasLink}} 11 | ### {{name}} {{issue}} {{title}} 12 | {{/hasLink}} 13 | {{/hasIssue}} 14 | {{^hasIssue}} 15 | ### {{name}} 16 | {{/hasIssue}} 17 | 18 | {{#commits}} 19 | **{{{messageTitle}}}** 20 | 21 | {{#messageBodyItems}} 22 | * {{.}} 23 | {{/messageBodyItems}} 24 | 25 | [{{hash}}](https://github.com/tomasbjerre/violation-comments-to-github-jenkins-plugin/commit/{{hash}}) {{authorName}} *{{commitTime}}* 26 | 27 | {{/commits}} 28 | 29 | {{/issues}} 30 | {{/tags}} 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/test/java/org/jenkinsci/plugins/jvctg/perform/JvctgPerformerTest.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg.perform; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import hudson.EnvVars; 6 | import org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfig; 7 | import org.junit.Test; 8 | import uk.co.jemos.podam.api.PodamFactoryImpl; 9 | 10 | public class JvctgPerformerTest { 11 | 12 | @Test 13 | public void testThatAllVariablesAreExpanded() { 14 | ViolationsToGitHubConfig original = 15 | new PodamFactoryImpl().manufacturePojo(ViolationsToGitHubConfig.class); 16 | 17 | ViolationsToGitHubConfig expanded = 18 | JvctgPerformer.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 | assertEquals(original.toString(), expanded.toString()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /sandbox/violations-test.jenkinsfile: -------------------------------------------------------------------------------- 1 | node { 2 | deleteDir() 3 | 4 | stage('Merge') { 5 | sh "git init" 6 | sh "git fetch --no-tags --progress https://github.com/tomasbjerre/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: 'ViolationsToGitHubRecorder', 21 | config: [ 22 | gitHubUrl: 'https://api.github.com/', 23 | repositoryOwner: 'tomasbjerre', 24 | repositoryName: 'violations-test', 25 | pullRequestId: '2', 26 | 27 | oAuth2Token: 'asdasdasd', 28 | credentialsId: 'githubtoken', 29 | 30 | createCommentWithAllSingleFileComments: true, 31 | createSingleFileComments: true, 32 | commentOnlyChangedContent: true, 33 | minSeverity: 'INFO', 34 | keepOldComments: false, 35 | violationConfigs: [ 36 | [ pattern: '.*/checkstyle/.*\\.xml$', parser: 'CHECKSTYLE', reporter: 'Checkstyle' ], 37 | [ pattern: '.*/findbugs/.*\\.xml$', parser: 'FINDBUGS', reporter: 'Findbugs' ], 38 | [ pattern: '.*/pmd/.*\\.xml$', parser: 'PMD', reporter: 'PMD' ], 39 | ] 40 | ] 41 | ]) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctg/ViolationsToGitHubConfiguration/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/config/ViolationsToGitHubConfigHelper.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg.config; 2 | 3 | import static com.google.common.collect.Lists.newArrayList; 4 | 5 | import java.util.List; 6 | import se.bjurr.violations.lib.reports.Parser; 7 | 8 | public class ViolationsToGitHubConfigHelper { 9 | public static final String FIELD_COMMENTONLYCHANGEDCONTENT = "commentOnlyChangedContent"; 10 | public static final String FIELD_CREATECOMMENTWITHALLSINGLEFILECOMMENTS = 11 | "createCommentWithAllSingleFileComments"; 12 | public static final String FIELD_CREATESINGLEFILECOMMENTS = "createSingleFileComments"; 13 | public static final String FIELD_GITHUBURL = "gitHubUrl"; 14 | public static final String FIELD_OAUTH2TOKEN = "oAuth2Token"; 15 | public static final String FIELD_PULLREQUESTID = "pullRequestId"; 16 | public static final String FIELD_REPOSITORYNAME = "repositoryName"; 17 | public static final String FIELD_REPOSITORYOWNER = "repositoryOwner"; 18 | public static final String FIELD_CREDENTIALSID = "credentialsId"; 19 | public static final String FIELD_MINSEVERITY = "minSeverity"; 20 | public static final String FIELD_KEEP_OLD_COMMENTS = "keepOldComments"; 21 | 22 | public static ViolationsToGitHubConfig createNewConfig() { 23 | final ViolationsToGitHubConfig config = new ViolationsToGitHubConfig(); 24 | final List violationConfigs = getAllViolationConfigs(); 25 | config.setViolationConfigs(violationConfigs); 26 | return config; 27 | } 28 | 29 | public static List getAllViolationConfigs() { 30 | final List violationConfigs = newArrayList(); 31 | for (final Parser parser : Parser.values()) { 32 | final ViolationConfig violationConfig = new ViolationConfig(); 33 | violationConfig.setParser(parser); 34 | violationConfigs.add(violationConfig); 35 | } 36 | return violationConfigs; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/ViolationsToGitHubDescriptor.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg; 2 | 3 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.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.jvctg.config.ViolationsToGitHubConfig; 14 | import org.kohsuke.stapler.StaplerRequest; 15 | 16 | @Extension 17 | @Symbol("ViolationsToGitHub") 18 | public final class ViolationsToGitHubDescriptor extends BuildStepDescriptor { 19 | private ViolationsToGitHubConfig config; 20 | 21 | public ViolationsToGitHubDescriptor() { 22 | super(ViolationsToGitHubRecorder.class); 23 | load(); 24 | if (this.config == null) { 25 | this.config = new ViolationsToGitHubConfig(); 26 | } 27 | } 28 | 29 | @Override 30 | public String getDisplayName() { 31 | return "Report Violations to GitHub"; 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(ViolationsToGitHubRecorder.class, formData); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/ViolationsToGitHubRecorder.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg; 2 | 3 | import static hudson.tasks.BuildStepMonitor.NONE; 4 | import static org.jenkinsci.plugins.jvctg.perform.JvctgPerformer.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.jvctg.config.ViolationsToGitHubConfig; 18 | import org.kohsuke.stapler.DataBoundConstructor; 19 | 20 | public class ViolationsToGitHubRecorder extends Recorder implements SimpleBuildStep { 21 | 22 | public static final BuildStepDescriptor DESCRIPTOR = 23 | new ViolationsToGitHubDescriptor(); 24 | 25 | private ViolationsToGitHubConfig config; 26 | 27 | public ViolationsToGitHubRecorder() {} 28 | 29 | @DataBoundConstructor 30 | public ViolationsToGitHubRecorder(final ViolationsToGitHubConfig config) { 31 | this.config = config; 32 | } 33 | 34 | public ViolationsToGitHubConfig 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 ViolationsToGitHubConfig combinedConfig = new ViolationsToGitHubConfig(this.config); 57 | final ViolationsToGitHubConfiguration defaults = ViolationsToGitHubConfiguration.get(); 58 | 59 | combinedConfig.applyDefaults(defaults); 60 | 61 | jvctsPerform(combinedConfig, filePath, build, listener); 62 | } 63 | 64 | public void setConfig(final ViolationsToGitHubConfig config) { 65 | this.config = config; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/config/ViolationConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg.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 = 6664329842273455651L; 17 | private String pattern; 18 | private String reporter; 19 | private Parser parser; 20 | 21 | public ViolationConfig() {} 22 | 23 | @DataBoundConstructor 24 | public ViolationConfig(final String reporter, final String pattern, final Parser parser) { 25 | this.reporter = reporter; 26 | this.pattern = pattern; 27 | this.parser = parser; 28 | } 29 | 30 | @Override 31 | public boolean equals(final Object obj) { 32 | if (this == obj) { 33 | return true; 34 | } 35 | if (obj == null) { 36 | return false; 37 | } 38 | if (getClass() != obj.getClass()) { 39 | return false; 40 | } 41 | final ViolationConfig other = (ViolationConfig) obj; 42 | if (parser != other.parser) { 43 | return false; 44 | } 45 | if (pattern == null) { 46 | if (other.pattern != null) { 47 | return false; 48 | } 49 | } else if (!pattern.equals(other.pattern)) { 50 | return false; 51 | } 52 | if (reporter == null) { 53 | if (other.reporter != null) { 54 | return false; 55 | } 56 | } else if (!reporter.equals(other.reporter)) { 57 | return false; 58 | } 59 | return true; 60 | } 61 | 62 | public String getPattern() { 63 | return this.pattern; 64 | } 65 | 66 | public String getReporter() { 67 | if (this.reporter == null) { 68 | return this.parser.name(); 69 | } 70 | return this.reporter; 71 | } 72 | 73 | @Override 74 | public int hashCode() { 75 | final int prime = 31; 76 | int result = 1; 77 | result = prime * result + (parser == null ? 0 : parser.hashCode()); 78 | result = prime * result + (pattern == null ? 0 : pattern.hashCode()); 79 | result = prime * result + (reporter == null ? 0 : reporter.hashCode()); 80 | return result; 81 | } 82 | 83 | public void setPattern(final String pattern) { 84 | this.pattern = pattern; 85 | } 86 | 87 | public void setParser(final Parser parser) { 88 | this.parser = parser; 89 | } 90 | 91 | public Parser getParser() { 92 | return parser; 93 | } 94 | 95 | public void setReporter(final String reporter) { 96 | this.reporter = reporter; 97 | } 98 | 99 | @Override 100 | public String toString() { 101 | return "ViolationConfig [pattern=" 102 | + pattern 103 | + ", reporter=" 104 | + reporter 105 | + ", parser=" 106 | + parser 107 | + "]"; 108 | } 109 | 110 | @Extension 111 | public static class DescriptorImpl extends Descriptor { 112 | @NonNull 113 | @Override 114 | public String getDisplayName() { 115 | return "Violations Parser Config"; 116 | } 117 | 118 | @Restricted(NoExternalUse.class) 119 | public ListBoxModel doFillParserItems() { 120 | final ListBoxModel items = new ListBoxModel(); 121 | for (final Parser parser : Parser.values()) { 122 | items.add(parser.name()); 123 | } 124 | return items; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/resources/org/jenkinsci/plugins/jvctg/config/ViolationsToGitHubConfig/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | You may want to use one of these to get the values: 27 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | If there are more violations than this, they will be ignored. Leave empty to include all violations. 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | Optional, leave empty for default template. It is documented here. 85 | 86 | 87 | 88 | 89 | 90 | 91 | 105 | 106 |
92 | Violations configuration 93 |
    94 |
  • 95 | 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.
    96 |
    97 | Some parsers can parse output from several reporters, it is documented here. Missing a parser? Open an issue here.
    98 |
    99 |
  • 100 |
  • 101 | 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.
    102 |
  • 103 |
104 |
107 |
108 | 109 | 110 | 111 | 112 |
113 | 114 |
115 |
116 |
117 |
118 | 119 |
120 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/ViolationsToGitHubConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg; 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.jvctg.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 ViolationsToGitHubConfiguration extends GlobalConfiguration implements Serializable { 21 | 22 | private static final long serialVersionUID = -2832851253933848205L; 23 | 24 | /** 25 | * Returns this singleton instance. 26 | * 27 | * @return the singleton. 28 | */ 29 | public static ViolationsToGitHubConfiguration get() { 30 | return GlobalConfiguration.all().get(ViolationsToGitHubConfiguration.class); 31 | } 32 | 33 | private String gitHubUrl; 34 | private String oAuth2Token; 35 | private String credentialsId; 36 | private String repositoryOwner; 37 | @Deprecated private transient String username; 38 | @Deprecated private transient String password; 39 | @Deprecated private transient String oAuth2TokenCredentialsId; 40 | @Deprecated private transient String usernamePasswordCredentialsId; 41 | private SEVERITY minSeverity = SEVERITY.INFO; 42 | 43 | public ViolationsToGitHubConfiguration() { 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 doFillCredentialsIdItems( 65 | @AncestorInPath final Item item, 66 | @QueryParameter final String credentialsId, 67 | @QueryParameter final String gitHubUrl) { 68 | return CredentialsHelper.doFillCredentialsIdItems(item, credentialsId, gitHubUrl); 69 | } 70 | 71 | @SuppressWarnings("unused") // Used by stapler 72 | public FormValidation doCheckCredentialsId( 73 | @AncestorInPath final Item item, 74 | @QueryParameter final String value, 75 | @QueryParameter final String gitHubUrl) { 76 | return CredentialsHelper.doCheckFillCredentialsId(item, value, gitHubUrl); 77 | } 78 | 79 | public String getGitHubUrl() { 80 | return this.gitHubUrl; 81 | } 82 | 83 | public String getoAuth2Token() { 84 | return this.oAuth2Token; 85 | } 86 | 87 | public String getOAuth2Token() { 88 | return oAuth2Token; 89 | } 90 | 91 | public String getRepositoryOwner() { 92 | return this.repositoryOwner; 93 | } 94 | 95 | public String getCredentialsId() { 96 | return this.credentialsId; 97 | } 98 | 99 | public SEVERITY getMinSeverity() { 100 | return minSeverity; 101 | } 102 | 103 | @DataBoundSetter 104 | public void setMinSeverity(final SEVERITY minSeverity) { 105 | this.minSeverity = minSeverity; 106 | } 107 | 108 | @DataBoundSetter 109 | public void setGitHubUrl(final String gitHubUrl) { 110 | this.gitHubUrl = gitHubUrl; 111 | } 112 | 113 | @DataBoundSetter 114 | public void setoAuth2Token(final String oAuth2Token) { 115 | this.oAuth2Token = oAuth2Token; 116 | } 117 | 118 | @DataBoundSetter 119 | public void setRepositoryOwner(final String repositoryOwner) { 120 | this.repositoryOwner = repositoryOwner; 121 | } 122 | 123 | @DataBoundSetter 124 | public void setCredentialsId(final String credentialsId) { 125 | this.credentialsId = credentialsId; 126 | } 127 | 128 | private Object readResolve() { 129 | credentialsId = 130 | CredentialsHelper.checkCredentials( 131 | credentialsId, 132 | oAuth2TokenCredentialsId, 133 | usernamePasswordCredentialsId, 134 | username, 135 | password); 136 | return this; 137 | } 138 | 139 | @Override 140 | public int hashCode() { 141 | final int prime = 31; 142 | int result = 1; 143 | result = prime * result + (gitHubUrl == null ? 0 : gitHubUrl.hashCode()); 144 | result = prime * result + (minSeverity == null ? 0 : minSeverity.hashCode()); 145 | result = prime * result + (oAuth2Token == null ? 0 : oAuth2Token.hashCode()); 146 | result = prime * result + (repositoryOwner == null ? 0 : repositoryOwner.hashCode()); 147 | result = prime * result + (credentialsId == null ? 0 : credentialsId.hashCode()); 148 | return result; 149 | } 150 | 151 | @Override 152 | public boolean equals(final Object obj) { 153 | if (this == obj) { 154 | return true; 155 | } 156 | if (obj == null) { 157 | return false; 158 | } 159 | if (getClass() != obj.getClass()) { 160 | return false; 161 | } 162 | final ViolationsToGitHubConfiguration other = (ViolationsToGitHubConfiguration) obj; 163 | if (gitHubUrl == null) { 164 | if (other.gitHubUrl != null) { 165 | return false; 166 | } 167 | } else if (!gitHubUrl.equals(other.gitHubUrl)) { 168 | return false; 169 | } 170 | if (minSeverity != other.minSeverity) { 171 | return false; 172 | } 173 | if (oAuth2Token == null) { 174 | if (other.oAuth2Token != null) { 175 | return false; 176 | } 177 | } else if (!oAuth2Token.equals(other.oAuth2Token)) { 178 | return false; 179 | } 180 | if (repositoryOwner == null) { 181 | if (other.repositoryOwner != null) { 182 | return false; 183 | } 184 | } else if (!repositoryOwner.equals(other.repositoryOwner)) { 185 | return false; 186 | } 187 | if (credentialsId == null) { 188 | if (other.credentialsId != null) { 189 | return false; 190 | } 191 | } else if (!credentialsId.equals(other.credentialsId)) { 192 | return false; 193 | } 194 | return true; 195 | } 196 | 197 | @Override 198 | public String toString() { 199 | return "ViolationsToGitHubConfiguration [gitHubUrl=" 200 | + gitHubUrl 201 | + ", oAuth2Token=" 202 | + oAuth2Token 203 | + ", repositoryOwner=" 204 | + repositoryOwner 205 | + ", credentialsId=" 206 | + credentialsId 207 | + ", minSeverity=" 208 | + minSeverity 209 | + "]"; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/config/CredentialsHelper.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg.config; 2 | 3 | import static com.google.common.base.Optional.absent; 4 | import static com.google.common.base.Optional.fromNullable; 5 | import static com.google.common.base.Strings.isNullOrEmpty; 6 | 7 | import com.cloudbees.plugins.credentials.CredentialsMatchers; 8 | import com.cloudbees.plugins.credentials.CredentialsProvider; 9 | import com.cloudbees.plugins.credentials.CredentialsScope; 10 | import com.cloudbees.plugins.credentials.SystemCredentialsProvider; 11 | import com.cloudbees.plugins.credentials.common.StandardCredentials; 12 | import com.cloudbees.plugins.credentials.common.StandardListBoxModel; 13 | import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; 14 | import com.cloudbees.plugins.credentials.domains.DomainRequirement; 15 | import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; 16 | import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; 17 | import com.google.common.base.Optional; 18 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 19 | import hudson.model.Item; 20 | import hudson.model.Queue; 21 | import hudson.model.queue.Tasks; 22 | import hudson.security.ACL; 23 | import hudson.util.FormValidation; 24 | import hudson.util.ListBoxModel; 25 | import hudson.util.Secret; 26 | import java.util.List; 27 | import jenkins.model.Jenkins; 28 | import org.apache.commons.lang.StringUtils; 29 | import org.jenkinsci.plugins.plaincredentials.StringCredentials; 30 | 31 | public class CredentialsHelper { 32 | 33 | @SuppressFBWarnings("NP_NULL_PARAM_DEREF") 34 | public static ListBoxModel doFillCredentialsIdItems( 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( 55 | CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class), 56 | CredentialsMatchers.instanceOf(StringCredentials.class))) 57 | .includeCurrentValue(credentialsId); 58 | } 59 | 60 | public static FormValidation doCheckFillCredentialsId( 61 | final Item item, final String credentialsId, final String uri) { 62 | if (item == null) { 63 | if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) { 64 | return FormValidation.ok(); 65 | } 66 | } else { 67 | if (!item.hasPermission(Item.EXTENDED_READ) 68 | && !item.hasPermission(CredentialsProvider.USE_ITEM)) { 69 | return FormValidation.ok(); 70 | } 71 | } 72 | if (isNullOrEmpty(credentialsId)) { 73 | return FormValidation.ok(); 74 | } 75 | if (!findCredentials(item, credentialsId, uri).isPresent()) { 76 | return FormValidation.error("Cannot find currently selected credentials"); 77 | } 78 | return FormValidation.ok(); 79 | } 80 | 81 | public static Optional findCredentials( 82 | final Item item, final String credentialsId, final String uri) { 83 | if (isNullOrEmpty(credentialsId)) { 84 | return absent(); 85 | } 86 | return fromNullable( 87 | CredentialsMatchers.firstOrNull( 88 | CredentialsProvider.lookupCredentials( 89 | StandardCredentials.class, 90 | item, 91 | item instanceof Queue.Task 92 | ? Tasks.getAuthenticationOf((Queue.Task) item) 93 | : ACL.SYSTEM, 94 | URIRequirementBuilder.fromUri(uri).build()), 95 | CredentialsMatchers.allOf( 96 | CredentialsMatchers.withId(credentialsId), 97 | CredentialsMatchers.anyOf( 98 | CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class), 99 | CredentialsMatchers.instanceOf(StringCredentials.class))))); 100 | } 101 | 102 | public static String migrateUsernamePasswordCredentials( 103 | final String username, final String password) { 104 | String credentialsId = null; 105 | final DomainRequirement domainRequirement = null; 106 | final List credentials = 107 | CredentialsMatchers.filter( 108 | CredentialsProvider.lookupCredentials( 109 | StandardUsernamePasswordCredentials.class, 110 | Jenkins.getInstance(), 111 | ACL.SYSTEM, 112 | domainRequirement), 113 | CredentialsMatchers.withUsername(username)); 114 | for (final StandardUsernamePasswordCredentials cred : credentials) { 115 | if (StringUtils.equals(password, Secret.toString(cred.getPassword()))) { 116 | // If some credentials have the same username/password, use those. 117 | credentialsId = cred.getId(); 118 | break; 119 | } 120 | } 121 | if (StringUtils.isBlank(credentialsId)) { 122 | // If we couldn't find any existing credentials, 123 | // create new credentials with the principal and secret and use it. 124 | final StandardUsernamePasswordCredentials newCredentials = 125 | new UsernamePasswordCredentialsImpl( 126 | CredentialsScope.SYSTEM, 127 | null, 128 | "Migrated by Violation comments to github", 129 | username, 130 | password); 131 | SystemCredentialsProvider.getInstance().getCredentials().add(newCredentials); 132 | credentialsId = newCredentials.getId(); 133 | } 134 | return credentialsId; 135 | } 136 | 137 | public static String checkCredentials( 138 | String credentialsId, 139 | final String oAuth2TokenCredentialsId, 140 | final String usernamePasswordCredentialsId, 141 | final String username, 142 | final String password) { 143 | if (StringUtils.isBlank(credentialsId)) { 144 | if (oAuth2TokenCredentialsId != null) { 145 | credentialsId = oAuth2TokenCredentialsId; 146 | } else if (usernamePasswordCredentialsId != null) { 147 | credentialsId = usernamePasswordCredentialsId; 148 | } else if (username != null && password != null) { 149 | credentialsId = migrateUsernamePasswordCredentials(username, password); 150 | } 151 | } 152 | return credentialsId; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.jenkins-ci.plugins 7 | plugin 8 | 3.2 9 | 10 | 11 | 12 | 8 13 | 2.7.4 14 | false 15 | true 16 | 1.96.1 17 | 1.50.7 18 | 1.156.3 19 | 1.83.1 20 | 2.9 21 | 22 | 23 | violation-comments-to-github 24 | 1.97-SNAPSHOT 25 | hpi 26 | Jenkins Violation Comments to GitHub Plugin 27 | Finds violations reported by code analyzers and comments GitHub pull requests with them. 28 | https://github.com/jenkinsci/violation-comments-to-github-plugin 29 | 30 | 31 | 32 | MIT License 33 | http://opensource.org/licenses/MIT 34 | 35 | 36 | 37 | 38 | 39 | tomasbjerre 40 | Tomas Bjerre 41 | tomas.bjerre85@gmail.com 42 | 43 | 44 | 45 | 46 | GitHub 47 | https://github.com/tomasbjerre/jenkins-violation-comments-to-github-plugin 48 | 49 | 50 | 51 | scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git 52 | scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git 53 | https://github.com/jenkinsci/${project.artifactId}-plugin 54 | HEAD 55 | 56 | 57 | 58 | 59 | repo.jenkins-ci.org 60 | https://repo.jenkins-ci.org/public/ 61 | 62 | 63 | 64 | 65 | 66 | repo.jenkins-ci.org 67 | https://repo.jenkins-ci.org/public/ 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.apache.maven.plugins 75 | maven-surefire-plugin 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-eclipse-plugin 80 | 81 | true 82 | true 83 | 84 | 85 | 86 | se.bjurr.gitchangelog 87 | git-changelog-maven-plugin 88 | ${changelog} 89 | 90 | 91 | GenerateGitChangelog 92 | generate-sources 93 | 94 | git-changelog 95 | 96 | 97 | ^\[maven-release-plugin\].* 98 | CHANGELOG.md 99 | -([^-]+?)$ 100 | https://api.github.com/repos/jenkinsci/violation-comments-to-github-plugin 101 | ${GITHUB_OAUTH2TOKEN} 102 | #([0-9]*) 103 | 104 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | com.coveo 143 | fmt-maven-plugin 144 | 2.9 145 | 146 | 147 | 148 | format 149 | 150 | 151 | 152 | 153 | 154 | se.bjurr.violations 155 | violations-maven-plugin 156 | ${violations-maven.version} 157 | 158 | INFO 159 | VERBOSE 160 | 99999999 161 | true 162 | 163 | 164 | FINDBUGS 165 | Spotbugs 166 | . 167 | .*/spotbugsXml.*\.xml$ 168 | 169 | 170 | 171 | 172 | 173 | verify 174 | 175 | violations 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | org.jenkins-ci.plugins 186 | credentials 187 | 2.1.4 188 | 189 | 190 | org.jenkins-ci.plugins 191 | plain-credentials 192 | 1.2 193 | 194 | 195 | se.bjurr.violations 196 | violation-comments-to-github-lib 197 | ${violation-comments-lib} 198 | 199 | 200 | se.bjurr.violations 201 | violations-lib 202 | ${violations-lib} 203 | 204 | 205 | org.jenkins-ci.plugins 206 | structs 207 | 1.10 208 | 209 | 210 | 211 | uk.co.jemos.podam 212 | podam 213 | 6.0.2.RELEASE 214 | test 215 | 216 | 217 | org.springframework 218 | spring-aop 219 | 4.1.6.RELEASE 220 | test 221 | 222 | 223 | junit 224 | junit 225 | 4.13.1 226 | test 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/config/ViolationsToGitHubConfig.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg.config; 2 | 3 | import static com.google.common.base.Strings.isNullOrEmpty; 4 | import static com.google.common.collect.Lists.newArrayList; 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.List; 15 | import org.jenkinsci.plugins.jvctg.ViolationsToGitHubConfiguration; 16 | import org.kohsuke.accmod.Restricted; 17 | import org.kohsuke.accmod.restrictions.NoExternalUse; 18 | import org.kohsuke.stapler.AncestorInPath; 19 | import org.kohsuke.stapler.DataBoundConstructor; 20 | import org.kohsuke.stapler.DataBoundSetter; 21 | import org.kohsuke.stapler.QueryParameter; 22 | import se.bjurr.violations.lib.model.SEVERITY; 23 | 24 | public class ViolationsToGitHubConfig extends AbstractDescribableImpl 25 | implements Serializable { 26 | private static final long serialVersionUID = 4851568645021422528L; 27 | 28 | private boolean commentOnlyChangedContent; 29 | private boolean commentOnlyChangedFiles = true; 30 | private boolean createCommentWithAllSingleFileComments; 31 | private boolean createSingleFileComments; 32 | private String gitHubUrl; 33 | private String oAuth2Token; 34 | private String pullRequestId; 35 | private String repositoryName; 36 | private String repositoryOwner; 37 | private String credentialsId; 38 | private List violationConfigs = newArrayList(); 39 | private SEVERITY minSeverity; 40 | @Deprecated private transient String username; 41 | @Deprecated private transient String password; 42 | @Deprecated private transient String usernamePasswordCredentialsId; 43 | @Deprecated private transient String oAuth2TokenCredentialsId; 44 | 45 | private boolean keepOldComments; 46 | private String commentTemplate; 47 | 48 | private Integer maxNumberOfViolations; 49 | 50 | public ViolationsToGitHubConfig() {} 51 | 52 | @DataBoundConstructor 53 | public ViolationsToGitHubConfig( 54 | final String repositoryName, 55 | final String repositoryOwner, 56 | final String pullRequestId, 57 | final String gitHubUrl) { 58 | this.repositoryName = repositoryName; 59 | this.repositoryOwner = repositoryOwner; 60 | this.pullRequestId = pullRequestId; 61 | this.gitHubUrl = gitHubUrl; 62 | } 63 | 64 | public ViolationsToGitHubConfig(final ViolationsToGitHubConfig rhs) { 65 | this.violationConfigs = rhs.violationConfigs; 66 | this.createSingleFileComments = rhs.createSingleFileComments; 67 | this.createCommentWithAllSingleFileComments = rhs.createCommentWithAllSingleFileComments; 68 | this.repositoryName = rhs.repositoryName; 69 | this.repositoryOwner = rhs.repositoryOwner; 70 | this.oAuth2Token = rhs.oAuth2Token; 71 | this.pullRequestId = rhs.pullRequestId; 72 | this.gitHubUrl = rhs.gitHubUrl; 73 | this.commentOnlyChangedContent = rhs.commentOnlyChangedContent; 74 | this.credentialsId = rhs.credentialsId; 75 | this.minSeverity = rhs.minSeverity; 76 | this.keepOldComments = rhs.keepOldComments; 77 | this.commentTemplate = rhs.commentTemplate; 78 | this.maxNumberOfViolations = rhs.maxNumberOfViolations; 79 | this.commentOnlyChangedFiles = rhs.commentOnlyChangedFiles; 80 | } 81 | 82 | public void applyDefaults(final ViolationsToGitHubConfiguration defaults) { 83 | if (isNullOrEmpty(this.gitHubUrl)) { 84 | this.gitHubUrl = defaults.getGitHubUrl(); 85 | } 86 | 87 | if (isNullOrEmpty(this.credentialsId)) { 88 | this.credentialsId = defaults.getCredentialsId(); 89 | } 90 | 91 | if (isNullOrEmpty(this.oAuth2Token)) { 92 | this.oAuth2Token = defaults.getoAuth2Token(); 93 | } 94 | 95 | if (isNullOrEmpty(this.repositoryOwner)) { 96 | this.repositoryOwner = defaults.getRepositoryOwner(); 97 | } 98 | if (this.minSeverity == null) { 99 | this.minSeverity = defaults.getMinSeverity(); 100 | } 101 | } 102 | 103 | public boolean getCommentOnlyChangedContent() { 104 | return this.commentOnlyChangedContent; 105 | } 106 | 107 | public boolean getCreateCommentWithAllSingleFileComments() { 108 | return this.createCommentWithAllSingleFileComments; 109 | } 110 | 111 | public boolean getCreateSingleFileComments() { 112 | return this.createSingleFileComments; 113 | } 114 | 115 | public String getGitHubUrl() { 116 | return this.gitHubUrl; 117 | } 118 | 119 | public String getoAuth2Token() { 120 | return this.oAuth2Token; 121 | } 122 | 123 | public String getOAuth2Token() { 124 | return oAuth2Token; 125 | } 126 | 127 | public String getPullRequestId() { 128 | return this.pullRequestId; 129 | } 130 | 131 | public String getRepositoryName() { 132 | return this.repositoryName; 133 | } 134 | 135 | public String getRepositoryOwner() { 136 | return this.repositoryOwner; 137 | } 138 | 139 | public String getCredentialsId() { 140 | return this.credentialsId; 141 | } 142 | 143 | public SEVERITY getMinSeverity() { 144 | return minSeverity; 145 | } 146 | 147 | @DataBoundSetter 148 | public void setMinSeverity(final SEVERITY minSeverity) { 149 | this.minSeverity = minSeverity; 150 | } 151 | 152 | public List getViolationConfigs() { 153 | return this.violationConfigs; 154 | } 155 | 156 | @DataBoundSetter 157 | public void setCommentOnlyChangedContent(final boolean commentOnlyChangedContent) { 158 | this.commentOnlyChangedContent = commentOnlyChangedContent; 159 | } 160 | 161 | @DataBoundSetter 162 | public void setCreateCommentWithAllSingleFileComments( 163 | final boolean createCommentWithAllSingleFileComments) { 164 | this.createCommentWithAllSingleFileComments = createCommentWithAllSingleFileComments; 165 | } 166 | 167 | @DataBoundSetter 168 | public void setCreateSingleFileComments(final boolean createSingleFileComments) { 169 | this.createSingleFileComments = createSingleFileComments; 170 | } 171 | 172 | public void setGitHubUrl(final String gitHubUrl) { 173 | this.gitHubUrl = gitHubUrl; 174 | } 175 | 176 | @DataBoundSetter 177 | public void setoAuth2Token(final String oAuth2Token) { 178 | this.oAuth2Token = oAuth2Token; 179 | } 180 | 181 | public void setPullRequestId(final String string) { 182 | this.pullRequestId = string; 183 | } 184 | 185 | public void setRepositoryName(final String repositoryName) { 186 | this.repositoryName = repositoryName; 187 | } 188 | 189 | public void setRepositoryOwner(final String repositoryOwner) { 190 | this.repositoryOwner = repositoryOwner; 191 | } 192 | 193 | @DataBoundSetter 194 | public void setCredentialsId(final String credentialsId) { 195 | this.credentialsId = credentialsId; 196 | } 197 | 198 | @DataBoundSetter 199 | public void setViolationConfigs(final List parsers) { 200 | this.violationConfigs = parsers; 201 | } 202 | 203 | public String getCommentTemplate() { 204 | return commentTemplate; 205 | } 206 | 207 | @DataBoundSetter 208 | public void setCommentTemplate(final String commentTemplate) { 209 | this.commentTemplate = commentTemplate; 210 | } 211 | 212 | @DataBoundSetter 213 | public void setMaxNumberOfViolations(final Integer maxNumberOfViolations) { 214 | this.maxNumberOfViolations = maxNumberOfViolations; 215 | } 216 | 217 | public Integer getMaxNumberOfViolations() { 218 | return maxNumberOfViolations; 219 | } 220 | 221 | private Object readResolve() { 222 | credentialsId = 223 | CredentialsHelper.checkCredentials( 224 | credentialsId, 225 | oAuth2TokenCredentialsId, 226 | usernamePasswordCredentialsId, 227 | username, 228 | password); 229 | return this; 230 | } 231 | 232 | @Override 233 | public String toString() { 234 | return "ViolationsToGitHubConfig [commentOnlyChangedContent=" 235 | + commentOnlyChangedContent 236 | + "commentOnlyChangedFiles=" 237 | + commentOnlyChangedFiles 238 | + ", createCommentWithAllSingleFileComments=" 239 | + createCommentWithAllSingleFileComments 240 | + ", createSingleFileComments=" 241 | + createSingleFileComments 242 | + ", gitHubUrl=" 243 | + gitHubUrl 244 | + ", oAuth2Token=" 245 | + oAuth2Token 246 | + ", pullRequestId=" 247 | + pullRequestId 248 | + ", repositoryName=" 249 | + repositoryName 250 | + ", repositoryOwner=" 251 | + repositoryOwner 252 | + ", credentialsId=" 253 | + credentialsId 254 | + ", violationConfigs=" 255 | + violationConfigs 256 | + ", minSeverity=" 257 | + minSeverity 258 | + ", keepOldComments=" 259 | + keepOldComments 260 | + "]"; 261 | } 262 | 263 | @Override 264 | public int hashCode() { 265 | final int prime = 31; 266 | int result = 1; 267 | result = prime * result + (commentOnlyChangedContent ? 1231 : 1237); 268 | result = prime * result + (commentOnlyChangedFiles ? 1231 : 1237); 269 | result = prime * result + (createCommentWithAllSingleFileComments ? 1231 : 1237); 270 | result = prime * result + (createSingleFileComments ? 1231 : 1237); 271 | result = prime * result + (gitHubUrl == null ? 0 : gitHubUrl.hashCode()); 272 | result = prime * result + (keepOldComments ? 1231 : 1237); 273 | result = prime * result + (minSeverity == null ? 0 : minSeverity.hashCode()); 274 | result = prime * result + (oAuth2Token == null ? 0 : oAuth2Token.hashCode()); 275 | result = prime * result + (pullRequestId == null ? 0 : pullRequestId.hashCode()); 276 | result = prime * result + (repositoryName == null ? 0 : repositoryName.hashCode()); 277 | result = prime * result + (repositoryOwner == null ? 0 : repositoryOwner.hashCode()); 278 | result = prime * result + (credentialsId == null ? 0 : credentialsId.hashCode()); 279 | result = prime * result + (violationConfigs == null ? 0 : violationConfigs.hashCode()); 280 | return result; 281 | } 282 | 283 | @Override 284 | public boolean equals(final Object obj) { 285 | if (this == obj) { 286 | return true; 287 | } 288 | if (obj == null) { 289 | return false; 290 | } 291 | if (getClass() != obj.getClass()) { 292 | return false; 293 | } 294 | final ViolationsToGitHubConfig other = (ViolationsToGitHubConfig) obj; 295 | if (commentOnlyChangedContent != other.commentOnlyChangedContent) { 296 | return false; 297 | } 298 | if (commentOnlyChangedFiles != other.commentOnlyChangedFiles) { 299 | return false; 300 | } 301 | if (createCommentWithAllSingleFileComments != other.createCommentWithAllSingleFileComments) { 302 | return false; 303 | } 304 | if (createSingleFileComments != other.createSingleFileComments) { 305 | return false; 306 | } 307 | if (gitHubUrl == null) { 308 | if (other.gitHubUrl != null) { 309 | return false; 310 | } 311 | } else if (!gitHubUrl.equals(other.gitHubUrl)) { 312 | return false; 313 | } 314 | if (keepOldComments != other.keepOldComments) { 315 | return false; 316 | } 317 | if (minSeverity != other.minSeverity) { 318 | return false; 319 | } 320 | if (oAuth2Token == null) { 321 | if (other.oAuth2Token != null) { 322 | return false; 323 | } 324 | } else if (!oAuth2Token.equals(other.oAuth2Token)) { 325 | return false; 326 | } 327 | if (pullRequestId == null) { 328 | if (other.pullRequestId != null) { 329 | return false; 330 | } 331 | } else if (!pullRequestId.equals(other.pullRequestId)) { 332 | return false; 333 | } 334 | if (repositoryName == null) { 335 | if (other.repositoryName != null) { 336 | return false; 337 | } 338 | } else if (!repositoryName.equals(other.repositoryName)) { 339 | return false; 340 | } 341 | if (repositoryOwner == null) { 342 | if (other.repositoryOwner != null) { 343 | return false; 344 | } 345 | } else if (!repositoryOwner.equals(other.repositoryOwner)) { 346 | return false; 347 | } 348 | if (credentialsId == null) { 349 | if (other.credentialsId != null) { 350 | return false; 351 | } 352 | } else if (!credentialsId.equals(other.credentialsId)) { 353 | return false; 354 | } 355 | if (violationConfigs == null) { 356 | if (other.violationConfigs != null) { 357 | return false; 358 | } 359 | } else if (!violationConfigs.equals(other.violationConfigs)) { 360 | return false; 361 | } 362 | return true; 363 | } 364 | 365 | public boolean isKeepOldComments() { 366 | return keepOldComments; 367 | } 368 | 369 | @DataBoundSetter 370 | public void setKeepOldComments(final boolean keepOldComments) { 371 | this.keepOldComments = keepOldComments; 372 | } 373 | 374 | @Extension 375 | public static class DescriptorImpl extends Descriptor { 376 | @NonNull 377 | @Override 378 | public String getDisplayName() { 379 | return "Violations To GitHub Server Config"; 380 | } 381 | 382 | @Restricted(NoExternalUse.class) 383 | public ListBoxModel doFillMinSeverityItems() { 384 | final ListBoxModel items = new ListBoxModel(); 385 | items.add("Default, Global Config or Info", ""); 386 | for (final SEVERITY severity : SEVERITY.values()) { 387 | items.add(severity.name()); 388 | } 389 | return items; 390 | } 391 | 392 | @SuppressWarnings("unused") // Used by stapler 393 | public ListBoxModel doFillCredentialsIdItems( 394 | @AncestorInPath final Item item, 395 | @QueryParameter final String credentialsId, 396 | @QueryParameter final String gitHubUrl) { 397 | return CredentialsHelper.doFillCredentialsIdItems(item, credentialsId, gitHubUrl); 398 | } 399 | 400 | @SuppressWarnings("unused") // Used by stapler 401 | public FormValidation doCheckCredentialsId( 402 | @AncestorInPath final Item item, 403 | @QueryParameter final String value, 404 | @QueryParameter final String gitHubUrl) { 405 | return CredentialsHelper.doCheckFillCredentialsId(item, value, gitHubUrl); 406 | } 407 | } 408 | 409 | public boolean getCommentOnlyChangedFiles() { 410 | return commentOnlyChangedFiles; 411 | } 412 | 413 | @DataBoundSetter 414 | public void setCommentOnlyChangedFiles(final boolean commentOnlyChangedFiles) { 415 | this.commentOnlyChangedFiles = commentOnlyChangedFiles; 416 | } 417 | } 418 | -------------------------------------------------------------------------------- /src/main/java/org/jenkinsci/plugins/jvctg/perform/JvctgPerformer.java: -------------------------------------------------------------------------------- 1 | package org.jenkinsci.plugins.jvctg.perform; 2 | 3 | import static com.google.common.base.Strings.isNullOrEmpty; 4 | import static java.util.logging.Level.SEVERE; 5 | import static org.jenkinsci.plugins.jvctg.config.CredentialsHelper.findCredentials; 6 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_COMMENTONLYCHANGEDCONTENT; 7 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_CREATECOMMENTWITHALLSINGLEFILECOMMENTS; 8 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_CREATESINGLEFILECOMMENTS; 9 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_CREDENTIALSID; 10 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_GITHUBURL; 11 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_KEEP_OLD_COMMENTS; 12 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_MINSEVERITY; 13 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_OAUTH2TOKEN; 14 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_PULLREQUESTID; 15 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_REPOSITORYNAME; 16 | import static org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfigHelper.FIELD_REPOSITORYOWNER; 17 | import static se.bjurr.violations.comments.github.lib.ViolationCommentsToGitHubApi.violationCommentsToGitHubApi; 18 | import static se.bjurr.violations.lib.ViolationsApi.violationsApi; 19 | 20 | import com.cloudbees.plugins.credentials.common.StandardCredentials; 21 | import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; 22 | import com.google.common.annotations.VisibleForTesting; 23 | import com.google.common.base.Optional; 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 hudson.util.Secret; 31 | import java.io.File; 32 | import java.io.IOException; 33 | import java.io.PrintStream; 34 | import java.io.PrintWriter; 35 | import java.io.StringWriter; 36 | import java.net.MalformedURLException; 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.jenkinsci.plugins.jvctg.config.ViolationConfig; 42 | import org.jenkinsci.plugins.jvctg.config.ViolationsToGitHubConfig; 43 | import org.jenkinsci.plugins.plaincredentials.StringCredentials; 44 | import org.jenkinsci.remoting.RoleChecker; 45 | import se.bjurr.violations.comments.github.lib.ViolationCommentsToGitHubApi; 46 | import se.bjurr.violations.lib.ViolationsLogger; 47 | import se.bjurr.violations.lib.model.SEVERITY; 48 | import se.bjurr.violations.lib.model.Violation; 49 | import se.bjurr.violations.lib.reports.Parser; 50 | import se.bjurr.violations.lib.util.Filtering; 51 | 52 | public class JvctgPerformer { 53 | private static Logger LOG = Logger.getLogger(JvctgPerformer.class.getSimpleName()); 54 | 55 | @VisibleForTesting 56 | public static void doPerform( 57 | final ViolationsToGitHubConfig config, 58 | final File workspace, 59 | final StandardCredentials credentials, 60 | final TaskListener listener) 61 | throws MalformedURLException { 62 | if (isNullOrEmpty(config.getPullRequestId())) { 63 | listener 64 | .getLogger() 65 | .println("No pull request id defined, will not send violation comments to GitHub."); 66 | return; 67 | } 68 | final Integer pullRequestIdInt = Integer.valueOf(config.getPullRequestId()); 69 | 70 | final ViolationsLogger violationsLogger = 71 | new ViolationsLogger() { 72 | @Override 73 | public void log(final Level level, final String string, final Throwable e) { 74 | Logger.getLogger(JvctgPerformer.class.getName()).log(level, string, e); 75 | final StringWriter sw = new StringWriter(); 76 | e.printStackTrace(new PrintWriter(sw)); 77 | listener.getLogger().println(string + "\n" + sw.toString()); 78 | } 79 | 80 | @Override 81 | public void log(final Level level, final String string) { 82 | Logger.getLogger(JvctgPerformer.class.getName()).log(level, string); 83 | if (level != Level.FINE) { 84 | listener.getLogger().println(string); 85 | } 86 | } 87 | }; 88 | 89 | final Set allParsedViolations = new TreeSet<>(); 90 | for (final ViolationConfig violationConfig : config.getViolationConfigs()) { 91 | if (!isNullOrEmpty(violationConfig.getPattern())) { 92 | Set parsedViolations = 93 | violationsApi() 94 | .withViolationsLogger(violationsLogger) 95 | .findAll(violationConfig.getParser()) // 96 | .withReporter(violationConfig.getReporter()) // 97 | .inFolder(workspace.getAbsolutePath()) // 98 | .withPattern(violationConfig.getPattern()) // 99 | .violations(); 100 | final SEVERITY minSeverity = config.getMinSeverity(); 101 | if (minSeverity != null) { 102 | parsedViolations = Filtering.withAtLEastSeverity(parsedViolations, minSeverity); 103 | } 104 | allParsedViolations.addAll(parsedViolations); 105 | listener 106 | .getLogger() 107 | .println( 108 | "Found " + parsedViolations.size() + " violations from " + violationConfig + "."); 109 | } 110 | } 111 | 112 | listener 113 | .getLogger() 114 | .println( 115 | "PR: " 116 | + config.getRepositoryOwner() 117 | + "/" 118 | + config.getRepositoryName() 119 | + "/" 120 | + config.getPullRequestId() 121 | + (isNullOrEmpty(config.getGitHubUrl()) ? "" : " on " + config.getGitHubUrl())); 122 | 123 | try { 124 | final ViolationCommentsToGitHubApi g = violationCommentsToGitHubApi(); 125 | 126 | if (!isNullOrEmpty(config.getoAuth2Token())) { 127 | g // 128 | .withoAuth2Token(config.getoAuth2Token()); 129 | } else if (credentials instanceof StringCredentials) { 130 | final StringCredentials token = (StringCredentials) credentials; 131 | g // 132 | .withoAuth2Token(Secret.toString(token.getSecret())); 133 | } else if (credentials instanceof StandardUsernamePasswordCredentials) { 134 | final StandardUsernamePasswordCredentials usernamePassword = 135 | (StandardUsernamePasswordCredentials) credentials; 136 | g // 137 | .withUsername(usernamePassword.getUsername()) // 138 | .withPassword(Secret.toString(usernamePassword.getPassword())); 139 | } 140 | final String commentTemplate = config.getCommentTemplate(); 141 | g // 142 | .withViolationsLogger(violationsLogger) 143 | .withGitHubUrl(config.getGitHubUrl()) // 144 | .withPullRequestId(pullRequestIdInt) // 145 | .withRepositoryName(config.getRepositoryName()) // 146 | .withRepositoryOwner(config.getRepositoryOwner()) // 147 | .withViolations(allParsedViolations) // 148 | .withCreateCommentWithAllSingleFileComments( 149 | config.getCreateCommentWithAllSingleFileComments()) // 150 | .withCreateSingleFileComments(config.getCreateSingleFileComments()) // 151 | .withCommentOnlyChangedContent(config.getCommentOnlyChangedContent()) // 152 | .withCommentOnlyChangedFiles(config.getCommentOnlyChangedFiles()) // 153 | .withKeepOldComments(config.isKeepOldComments()) // 154 | .withCommentTemplate(commentTemplate) // 155 | .withMaxNumberOfViolations(config.getMaxNumberOfViolations()) // 156 | .withViolationsLogger( 157 | new ViolationsLogger() { 158 | @Override 159 | public void log(final Level level, final String string) { 160 | listener.getLogger().println(level + " " + string); 161 | } 162 | 163 | @Override 164 | public void log(final Level level, final String string, final Throwable t) { 165 | final StringWriter sw = new StringWriter(); 166 | t.printStackTrace(new PrintWriter(sw)); 167 | listener.getLogger().println(level + " " + string + "\n" + sw.toString()); 168 | } 169 | }) // 170 | .toPullRequest(); 171 | } catch (final Exception e) { 172 | Logger.getLogger(JvctgPerformer.class.getName()).log(SEVERE, "", e); 173 | final StringWriter sw = new StringWriter(); 174 | e.printStackTrace(new PrintWriter(sw)); 175 | listener.getLogger().println(sw.toString()); 176 | } 177 | } 178 | 179 | /** Makes sure any Jenkins variable, used in the configuration fields, are evaluated. */ 180 | @VisibleForTesting 181 | static ViolationsToGitHubConfig expand( 182 | final ViolationsToGitHubConfig config, final EnvVars environment) { 183 | final ViolationsToGitHubConfig expanded = new ViolationsToGitHubConfig(); 184 | expanded.setGitHubUrl(environment.expand(config.getGitHubUrl())); 185 | expanded.setPullRequestId(environment.expand(config.getPullRequestId())); 186 | expanded.setRepositoryName(environment.expand(config.getRepositoryName())); 187 | expanded.setRepositoryOwner(environment.expand(config.getRepositoryOwner())); 188 | 189 | expanded.setCreateCommentWithAllSingleFileComments( 190 | config.getCreateCommentWithAllSingleFileComments()); 191 | expanded.setCreateSingleFileComments(config.getCreateSingleFileComments()); 192 | expanded.setCommentOnlyChangedContent(config.getCommentOnlyChangedContent()); 193 | expanded.setCommentOnlyChangedFiles(config.getCommentOnlyChangedFiles()); 194 | 195 | expanded.setMinSeverity(config.getMinSeverity()); 196 | 197 | expanded.setCredentialsId(config.getCredentialsId()); 198 | expanded.setoAuth2Token(environment.expand(config.getoAuth2Token())); 199 | expanded.setKeepOldComments(config.isKeepOldComments()); 200 | expanded.setCommentTemplate(config.getCommentTemplate()); 201 | expanded.setMaxNumberOfViolations(config.getMaxNumberOfViolations()); 202 | for (final ViolationConfig violationConfig : config.getViolationConfigs()) { 203 | final String pattern = environment.expand(violationConfig.getPattern()); 204 | final String reporter = violationConfig.getReporter(); 205 | final Parser parser = violationConfig.getParser(); 206 | if (isNullOrEmpty(pattern) || parser == null) { 207 | LOG.fine("Ignoring violationConfig because of null/empty -values: " + violationConfig); 208 | continue; 209 | } 210 | final ViolationConfig p = new ViolationConfig(); 211 | p.setPattern(pattern); 212 | p.setReporter(reporter); 213 | p.setParser(parser); 214 | expanded.getViolationConfigs().add(p); 215 | } 216 | return expanded; 217 | } 218 | 219 | public static void jvctsPerform( 220 | final ViolationsToGitHubConfig configUnexpanded, 221 | final FilePath fp, 222 | final Run build, 223 | final TaskListener listener) { 224 | final PrintStream logger = listener.getLogger(); 225 | try { 226 | final EnvVars env = build.getEnvironment(listener); 227 | final ViolationsToGitHubConfig configExpanded = expand(configUnexpanded, env); 228 | logger.println("---"); 229 | logger.println("--- Jenkins Violation Comments to GitHub ---"); 230 | logger.println("---"); 231 | logConfiguration(configExpanded, build, listener); 232 | 233 | final Optional credentials = 234 | findCredentials( 235 | build.getParent(), configExpanded.getCredentialsId(), configExpanded.getGitHubUrl()); 236 | 237 | if (!isNullOrEmpty(configExpanded.getoAuth2Token())) { 238 | logger.println("Using OAuth2Token"); 239 | } else if (credentials.isPresent()) { 240 | final StandardCredentials standardCredentials = credentials.get(); 241 | if (standardCredentials instanceof StandardUsernamePasswordCredentials) { 242 | logger.println("Using username / password"); 243 | } else if (standardCredentials instanceof StringCredentials) { 244 | logger.println("Using OAuth2Token credential style"); 245 | } 246 | } else { 247 | throw new IllegalStateException("No credentials found!"); 248 | } 249 | 250 | logger.println("Running Jenkins Violation Comments To GitHub"); 251 | logger.println("PR " + configExpanded.getPullRequestId()); 252 | 253 | fp.act( 254 | new FileCallable() { 255 | 256 | private static final long serialVersionUID = 6166111757469534436L; 257 | 258 | @Override 259 | public void checkRoles(final RoleChecker checker) throws SecurityException {} 260 | 261 | @Override 262 | public Void invoke(final File workspace, final VirtualChannel channel) 263 | throws IOException, InterruptedException { 264 | listener.getLogger().println("Workspace: " + workspace.getAbsolutePath()); 265 | doPerform(configExpanded, workspace, credentials.orNull(), listener); 266 | return null; 267 | } 268 | }); 269 | } catch (final Exception e) { 270 | Logger.getLogger(JvctgPerformer.class.getName()).log(SEVERE, "", e); 271 | final StringWriter sw = new StringWriter(); 272 | e.printStackTrace(new PrintWriter(sw)); 273 | logger.println(sw.toString()); 274 | return; 275 | } 276 | } 277 | 278 | private static void logConfiguration( 279 | final ViolationsToGitHubConfig config, final Run build, final TaskListener listener) { 280 | final PrintStream logger = listener.getLogger(); 281 | logger.println(FIELD_GITHUBURL + ": " + config.getGitHubUrl()); 282 | logger.println(FIELD_REPOSITORYOWNER + ": " + config.getRepositoryOwner()); 283 | logger.println(FIELD_REPOSITORYNAME + ": " + config.getRepositoryName()); 284 | logger.println(FIELD_PULLREQUESTID + ": " + config.getPullRequestId()); 285 | 286 | logger.println(FIELD_CREDENTIALSID + ": " + !isNullOrEmpty(config.getCredentialsId())); 287 | logger.println(FIELD_OAUTH2TOKEN + ": " + !isNullOrEmpty(config.getoAuth2Token())); 288 | 289 | logger.println(FIELD_CREATESINGLEFILECOMMENTS + ": " + config.getCreateSingleFileComments()); 290 | logger.println( 291 | FIELD_CREATECOMMENTWITHALLSINGLEFILECOMMENTS 292 | + ": " 293 | + config.getCreateCommentWithAllSingleFileComments()); 294 | logger.println(FIELD_COMMENTONLYCHANGEDCONTENT + ": " + config.getCommentOnlyChangedContent()); 295 | logger.println("commentOnlyChangedFiles: " + config.getCommentOnlyChangedFiles()); 296 | 297 | logger.println(FIELD_MINSEVERITY + ": " + config.getMinSeverity()); 298 | 299 | logger.println(FIELD_KEEP_OLD_COMMENTS + ": " + config.isKeepOldComments()); 300 | 301 | logger.println("commentTemplate: " + config.getCommentTemplate()); 302 | logger.println("maxNumberOfViolations: " + config.getMaxNumberOfViolations()); 303 | 304 | for (final ViolationConfig violationConfig : config.getViolationConfigs()) { 305 | logger.println( 306 | violationConfig.getReporter() + " with pattern " + violationConfig.getPattern()); 307 | } 308 | } 309 | } 310 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Violation Comments to GitHub Jenkins Plugin 2 | 3 | 4 | This is a Jenkins plugin for [Violation Comments to GitHub Lib](https://github.com/tomasbjerre/violation-comments-to-github-lib). This plugin will find report files from static code analysis and comment GitHub pull requests with the content. 5 | 6 | It uses [Violation Comments to GitHub Lib](https://github.com/tomasbjerre/violation-comments-to-github-lib) and supports the same formats as [Violations Lib](https://github.com/tomasbjerre/violations-lib). 7 | 8 | Example of supported reports are available [here](https://github.com/tomasbjerre/violations-lib/tree/master/src/test/resources). 9 | 10 | You can also do this with a [command line tool](https://www.npmjs.com/package/violation-comments-to-github-command-line). 11 | 12 | A number of **parsers** have been implemented. Some **parsers** can parse output from several **reporters**. 13 | 14 | | Reporter | Parser | Notes 15 | | --- | --- | --- 16 | | [_ARM-GCC_](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm) | `CLANG` | 17 | | [_AndroidLint_](http://developer.android.com/tools/help/lint.html) | `ANDROIDLINT` | 18 | | [_AnsibleLint_](https://github.com/willthames/ansible-lint) | `FLAKE8` | With `-p` 19 | | [_Bandit_](https://github.com/PyCQA/bandit) | `CLANG` | With `bandit -r examples/ -f custom -o bandit.out --msg-template "{abspath}:{line}: {severity}: {test_id}: {msg}"` 20 | | [_CLang_](https://clang-analyzer.llvm.org/) | `CLANG` | 21 | | [_CPD_](http://pmd.sourceforge.net/pmd-4.3.0/cpd.html) | `CPD` | 22 | | [_CPPCheck_](http://cppcheck.sourceforge.net/) | `CPPCHECK` | With `cppcheck test.cpp --output-file=cppcheck.xml --xml` 23 | | [_CPPLint_](https://github.com/theandrewdavis/cpplint) | `CPPLINT` | 24 | | [_CSSLint_](https://github.com/CSSLint/csslint) | `CSSLINT` | 25 | | [_Checkstyle_](http://checkstyle.sourceforge.net/) | `CHECKSTYLE` | 26 | | [_CloudFormation Linter_](https://github.com/aws-cloudformation/cfn-lint) | `JUNIT` | `cfn-lint . -f junit --output-file report-junit.xml` 27 | | [_CodeClimate_](https://codeclimate.com/) | `CODECLIMATE` | 28 | | [_CodeNarc_](http://codenarc.sourceforge.net/) | `CODENARC` | 29 | | [_Dart_](https://dart.dev/) | `MACHINE` | With `dart analyze --format=machine` 30 | | [_Detekt_](https://github.com/arturbosch/detekt) | `CHECKSTYLE` | With `--output-format xml`. 31 | | [_DocFX_](http://dotnet.github.io/docfx/) | `DOCFX` | 32 | | [_Doxygen_](https://www.stack.nl/~dimitri/doxygen/) | `CLANG` | 33 | | [_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`. 34 | | [_ESLint_](https://github.com/sindresorhus/grunt-eslint) | `CHECKSTYLE` | With `format: 'checkstyle'`. 35 | | [_Findbugs_](http://findbugs.sourceforge.net/) | `FINDBUGS` | 36 | | [_Flake8_](http://flake8.readthedocs.org/en/latest/) | `FLAKE8` | 37 | | [_FxCop_](https://en.wikipedia.org/wiki/FxCop) | `FXCOP` | 38 | | [_GCC_](https://gcc.gnu.org/) | `CLANG` | 39 | | [_Gendarme_](http://www.mono-project.com/docs/tools+libraries/tools/gendarme/) | `GENDARME` | 40 | | [_Generic reporter_]() | `GENERIC` | Will create one single violation with all the content as message. 41 | | [_GoLint_](https://github.com/golang/lint) | `GOLINT` | 42 | | [_GoVet_](https://golang.org/cmd/vet/) | `GOLINT` | Same format as GoLint. 43 | | [_GolangCI-Lint_](https://github.com/golangci/golangci-lint/) | `CHECKSTYLE` | With `--out-format=checkstyle`. 44 | | [_GoogleErrorProne_](https://github.com/google/error-prone) | `GOOGLEERRORPRONE` | 45 | | [_HadoLint_](https://github.com/hadolint/hadolint/) | `CHECKSTYLE` | With `-f checkstyle` 46 | | [_IAR_](https://www.iar.com/iar-embedded-workbench/) | `IAR` | With `--no_wrap_diagnostics` 47 | | [_Infer_](http://fbinfer.com/) | `PMD` | Facebook Infer. With `--pmd-xml`. 48 | | [_JACOCO_](https://www.jacoco.org/) | `JACOCO` | 49 | | [_JCReport_](https://github.com/jCoderZ/fawkez/wiki/JcReport) | `JCREPORT` | 50 | | [_JSHint_](http://jshint.com/) | `JSLINT` | With `--reporter=jslint` or the CHECKSTYLE parser with `--reporter=checkstyle` 51 | | [_JUnit_](https://junit.org/junit4/) | `JUNIT` | It only contains the failures. 52 | | [_KTLint_](https://github.com/shyiko/ktlint) | `CHECKSTYLE` | 53 | | [_Klocwork_](http://www.klocwork.com/products-services/klocwork/static-code-analysis) | `KLOCWORK` | 54 | | [_KotlinGradle_](https://github.com/JetBrains/kotlin) | `KOTLINGRADLE` | Output from Kotlin Gradle Plugin. 55 | | [_KotlinMaven_](https://github.com/JetBrains/kotlin) | `KOTLINMAVEN` | Output from Kotlin Maven Plugin. 56 | | [_Lint_]() | `LINT` | A common XML format, used by different linters. 57 | | [_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 58 | | [_MSCpp_](https://visualstudio.microsoft.com/vs/features/cplusplus/) | `MSCPP` | 59 | | [_Mccabe_](https://pypi.python.org/pypi/mccabe) | `FLAKE8` | 60 | | [_MyPy_](https://pypi.python.org/pypi/mypy-lang) | `MYPY` | 61 | | [_NullAway_](https://github.com/uber/NullAway) | `GOOGLEERRORPRONE` | Same format as Google Error Prone. 62 | | [_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) 63 | | [_PHPCS_](https://github.com/squizlabs/PHP_CodeSniffer) | `CHECKSTYLE` | With `phpcs api.php --report=checkstyle`. 64 | | [_PHPPMD_](https://phpmd.org/) | `PMD` | With `phpmd api.php xml ruleset.xml`. 65 | | [_PMD_](https://pmd.github.io/) | `PMD` | 66 | | [_Pep8_](https://github.com/PyCQA/pycodestyle) | `FLAKE8` | 67 | | [_PerlCritic_](https://github.com/Perl-Critic) | `PERLCRITIC` | 68 | | [_PiTest_](http://pitest.org/) | `PITEST` | 69 | | [_ProtoLint_](https://github.com/yoheimuta/protolint) | `PROTOLINT` | 70 | | [_Puppet-Lint_](http://puppet-lint.com/) | `CLANG` | With `-log-format %{fullpath}:%{line}:%{column}: %{kind}: %{message}` 71 | | [_PyDocStyle_](https://pypi.python.org/pypi/pydocstyle) | `PYDOCSTYLE` | 72 | | [_PyFlakes_](https://pypi.python.org/pypi/pyflakes) | `FLAKE8` | 73 | | [_PyLint_](https://www.pylint.org/) | `PYLINT` | With `pylint --output-format=parseable`. 74 | | [_ReSharper_](https://www.jetbrains.com/resharper/) | `RESHARPER` | 75 | | [_RubyCop_](http://rubocop.readthedocs.io/en/latest/formatters/) | `CLANG` | With `rubycop -f clang file.rb` 76 | | [_SARIF_](https://github.com/oasis-tcs/sarif-spec) | `SARIF` | 77 | | [_SbtScalac_](http://www.scala-sbt.org/) | `SBTSCALAC` | 78 | | [_Scalastyle_](http://www.scalastyle.org/) | `CHECKSTYLE` | 79 | | [_Simian_](http://www.harukizaemon.com/simian/) | `SIMIAN` | 80 | | [_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`. 81 | | [_Spotbugs_](https://spotbugs.github.io/) | `FINDBUGS` | 82 | | [_StyleCop_](https://stylecop.codeplex.com/) | `STYLECOP` | 83 | | [_SwiftLint_](https://github.com/realm/SwiftLint) | `CHECKSTYLE` | With `--reporter checkstyle`. 84 | | [_TSLint_](https://palantir.github.io/tslint/usage/cli/) | `CHECKSTYLE` | With `-t checkstyle` 85 | | [_Valgrind_](https://valgrind.org/) | `VALGRIND` | With `--xml=yes`. 86 | | [_XMLLint_](http://xmlsoft.org/xmllint.html) | `XMLLINT` | 87 | | [_XUnit_](https://xunit.net/) | `XUNIT` | It only contains the failures. 88 | | [_YAMLLint_](https://yamllint.readthedocs.io/en/stable/index.html) | `YAMLLINT` | With `-f parsable` 89 | | [_ZPTLint_](https://pypi.python.org/pypi/zptlint) | `ZPTLINT` | 90 | 91 | 48 parsers and 74 reporters. 92 | 93 | Missing a format? Open an issue [here](https://github.com/tomasbjerre/violations-lib/issues)! 94 | 95 | There is also: 96 | * A [Gradle plugin](https://github.com/tomasbjerre/violation-comments-to-github-gradle-plugin). 97 | * A [Maven plugin](https://github.com/tomasbjerre/violation-comments-to-github-maven-plugin). 98 | 99 | Available in Jenkins [here](https://wiki.jenkins-ci.org/display/JENKINS/Violation+Comments+to+GitHub+Plugin). 100 | 101 | 102 | ## Notify Jenkins from GitHub 103 | 104 | You will need to the **pull request id** for the pull request that was built. 105 | 106 | * You may trigger with a [webhook](https://developer.github.com/v3/activity/events/types/#pullrequestevent) in GitHub. And consume it with [Generic Webhook Trigger plugin](https://github.com/jenkinsci/generic-webhook-trigger-plugin) to get the variables you need. 107 | 108 | * Or, trigger with [GitHub Pull Request Builder Plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin), it provides the environment variable `ghprbPullId`. 109 | 110 | ## Merge 111 | 112 | **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. 113 | 114 | ``` 115 | echo --- 116 | echo --- Merging from $FROM in $FROMREPO to $TO in $TOREPO 117 | echo --- 118 | git clone $TOREPO 119 | cd * 120 | git reset --hard $TO 121 | git status 122 | git remote add from $FROMREPO 123 | git fetch from 124 | git merge $FROM 125 | git --no-pager log --max-count=10 --graph --abbrev-commit 126 | 127 | Your build command here! 128 | ``` 129 | 130 | # Screenshots 131 | 132 | When installed, a post build action will be available. 133 | 134 | ![Post build action menu](https://github.com/jenkinsci/violation-comments-to-github-jenkins-plugin/blob/master/sandbox/jenkins-postbuildmenu.png) 135 | 136 | The pull request will be commented like this. 137 | 138 | ![Pull request comment](https://github.com/jenkinsci/violation-comments-to-github-jenkins-plugin/blob/master/sandbox/github-pr-diff-comment.png) 139 | 140 | ## Job DSL Plugin 141 | 142 | This plugin can be used with the Job DSL Plugin. In this example the [GitHub Pull Request Builder Plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin) is used to trigger, merge and provide environment variables needed. 143 | 144 | ```groovy 145 | job('GitHub_PR_Builder') { 146 | concurrentBuild() 147 | quietPeriod(0) 148 | scm { 149 | git { 150 | remote { 151 | github('tomasbjerre/violations-test') 152 | refspec('+refs/pull/*:refs/remotes/origin/pr/*') 153 | } 154 | branch('${sha1}') 155 | } 156 | } 157 | 158 | triggers { 159 | githubPullRequest { 160 | cron('* * * * *') 161 | permitAll() 162 | extensions { 163 | buildStatus { 164 | completedStatus('SUCCESS', 'There were no errors, go have a cup of coffee...') 165 | completedStatus('FAILURE', 'There were errors, for info, please see...') 166 | completedStatus('ERROR', 'There was an error in the infrastructure, please contact...') 167 | } 168 | } 169 | } 170 | } 171 | 172 | steps { 173 | shell(''' 174 | ./gradlew build 175 | ''') 176 | } 177 | 178 | publishers { 179 | violationsToGitHubRecorder { 180 | config { 181 | gitHubUrl("https://api.github.com/") 182 | repositoryOwner("tomasbjerre") 183 | repositoryName("violations-test") 184 | pullRequestId("\$ghprbPullId") 185 | 186 | // Only specify one of these! 187 | oAuth2Token("") 188 | credentialsId("githubtoken") 189 | 190 | createSingleFileComments(true) 191 | createCommentWithAllSingleFileComments(true) 192 | commentOnlyChangedContent(true) 193 | commentOnlyChangedFiles(true) 194 | minSeverity('INFO') 195 | maxNumberOfViolations(99999) 196 | keepOldComments(false) 197 | 198 | commentTemplate(""" 199 | **Reporter**: {{violation.reporter}}{{#violation.rule}} 200 | 201 | **Rule**: {{violation.rule}}{{/violation.rule}} 202 | **Severity**: {{violation.severity}} 203 | **File**: {{violation.file}} L{{violation.startLine}}{{#violation.source}} 204 | 205 | **Source**: {{violation.source}}{{/violation.source}} 206 | 207 | {{violation.message}} 208 | """) 209 | 210 | violationConfigs { 211 | violationConfig { 212 | parser("FINDBUGS") 213 | reporter("Findbugs") 214 | pattern(".*/findbugs/.*\\.xml\$") 215 | } 216 | violationConfig { 217 | parser("CHECKSTYLE") 218 | reporter("Checkstyle") 219 | pattern(".*/checkstyle/.*\\.xml\$") 220 | } 221 | } 222 | } 223 | } 224 | } 225 | } 226 | ``` 227 | 228 | Here is another example using [Generic Webhook Trigger plugin](https://github.com/jenkinsci/generic-webhook-trigger-plugin). You will need to add a webhook in GitHub and point it to `http://JENKINS_URL/generic-webhook-trigger/invoke`. You may want to combine this with [HTTP Request Plugin](https://wiki.jenkins-ci.org/display/JENKINS/HTTP+Request+Plugin) to comment the pull requests with a link to the job. And also [Conditional BuildStep Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Conditional+BuildStep+Plugin) to have different comments depending on build status. 229 | 230 | ```groovy 231 | job('GitHub_PR_Builder Generic') { 232 | concurrentBuild() 233 | quietPeriod(0) 234 | parameters { 235 | stringParam('PULL_REQUEST_HEAD_URL', '') 236 | stringParam('PULL_REQUEST_BASE_URL', '') 237 | stringParam('PULL_REQUEST_HEAD_REF', '') 238 | stringParam('PULL_REQUEST_BASE_REF', '') 239 | } 240 | scm { 241 | git { 242 | remote { 243 | name('origin') 244 | url('$PULL_REQUEST_BASE_URL') 245 | } 246 | remote { 247 | name('upstream') 248 | url('$PULL_REQUEST_HEAD_URL') 249 | } 250 | branch('$PULL_REQUEST_HEAD_REF') 251 | extensions { 252 | mergeOptions { 253 | remote('upstream') 254 | branch('$PULL_REQUEST_BASE_REF') 255 | } 256 | } 257 | } 258 | } 259 | triggers { 260 | genericTrigger { 261 | genericVariables { 262 | genericVariable { 263 | key("PULL_REQUEST_HEAD_URL") 264 | value("\$.pull_request.head.repo.clone_url") 265 | expressionType("JSONPath") 266 | regexpFilter("") 267 | } 268 | genericVariable { 269 | key("PULL_REQUEST_HEAD_REF") 270 | value("\$.pull_request.head.ref") 271 | expressionType("JSONPath") 272 | regexpFilter("") 273 | } 274 | genericVariable { 275 | key("PULL_REQUEST_BASE_URL") 276 | value("\$.pull_request.base.repo.clone_url") 277 | expressionType("JSONPath") 278 | regexpFilter("") 279 | } 280 | genericVariable { 281 | key("PULL_REQUEST_BASE_REF") 282 | value("\$.pull_request.base.ref") 283 | expressionType("JSONPath") 284 | regexpFilter("") 285 | } 286 | genericVariable { 287 | key("PULL_REQUEST_BASE_OWNER") 288 | value("\$.pull_request.base.repo.owner.login") 289 | expressionType("JSONPath") 290 | regexpFilter("") 291 | } 292 | genericVariable { 293 | key("PULL_REQUEST_BASE_REPO") 294 | value("\$.pull_request.base.repo.name") 295 | expressionType("JSONPath") 296 | regexpFilter("") 297 | } 298 | genericVariable { 299 | key("PULL_REQUEST_ID") 300 | value("\$.number") 301 | expressionType("JSONPath") 302 | regexpFilter("") 303 | } 304 | genericVariable { 305 | key("ACTION") 306 | value("\$.action") 307 | expressionType("JSONPath") 308 | regexpFilter("") 309 | } 310 | } 311 | regexpFilterText("\$ACTION") 312 | regexpFilterExpression("opened|reopened|synchronize") 313 | } 314 | } 315 | 316 | steps { 317 | shell('./gradlew build') 318 | } 319 | 320 | publishers { 321 | violationsToGitHubRecorder { 322 | config { 323 | gitHubUrl("https://api.github.com/") 324 | repositoryOwner("\$PULL_REQUEST_BASE_OWNER") 325 | repositoryName("\$PULL_REQUEST_BASE_REPO") 326 | pullRequestId("\$PULL_REQUEST_ID") 327 | 328 | // Only specify one of these! 329 | oAuth2Token("oh no!") 330 | credentialsId("githubtoken") 331 | 332 | createSingleFileComments(true) 333 | createCommentWithAllSingleFileComments(true) 334 | commentOnlyChangedContent(true) 335 | commentOnlyChangedFiles(true) 336 | minSeverity('INFO') 337 | maxNumberOfViolations(99999) 338 | keepOldComments(false) 339 | 340 | commentTemplate(""" 341 | **Reporter**: {{violation.reporter}}{{#violation.rule}} 342 | 343 | **Rule**: {{violation.rule}}{{/violation.rule}} 344 | **Severity**: {{violation.severity}} 345 | **File**: {{violation.file}} L{{violation.startLine}}{{#violation.source}} 346 | 347 | **Source**: {{violation.source}}{{/violation.source}} 348 | 349 | {{violation.message}} 350 | """) 351 | 352 | violationConfigs { 353 | violationConfig { 354 | parser("FINDBUGS") 355 | reporter("Findbugs") 356 | pattern(".*/findbugs/.*\\.xml\$") 357 | } 358 | violationConfig { 359 | parser("CHECKSTYLE") 360 | reporter("Checkstyle") 361 | pattern(".*/checkstyle/.*\\.xml\$") 362 | } 363 | } 364 | } 365 | } 366 | } 367 | } 368 | ``` 369 | 370 | ## Pipeline Plugin 371 | 372 | This plugin can be used with the Pipeline Plugin: 373 | 374 | ```groovy 375 | node { 376 | def mvnHome = tool 'Maven 3.3.9' 377 | deleteDir() 378 | 379 | stage('Merge') { 380 | sh "git init" 381 | sh "git fetch --no-tags --progress git@git:group/reponame.git +refs/heads/*:refs/remotes/origin/* --depth=200" 382 | sh "git checkout origin/${env.targetBranch}" 383 | sh "git merge origin/${env.sourceBranch}" 384 | sh "git log --graph --abbrev-commit --max-count=10" 385 | } 386 | 387 | stage('Static code analysis') { 388 | sh "${mvnHome}/bin/mvn package -DskipTests -Dmaven.test.failure.ignore=false -Dsurefire.skip=true -Dmaven.compile.fork=true -Dmaven.javadoc.skip=true" 389 | 390 | step([ 391 | $class: 'ViolationsToGitHubRecorder', 392 | config: [ 393 | gitHubUrl: 'https://api.github.com/', 394 | repositoryOwner: 'tomasbjerre', 395 | repositoryName: 'violations-test', 396 | pullRequestId: '2', 397 | 398 | // Only specify one of these! 399 | oAuth2Token: '', 400 | credentialsId: '', 401 | 402 | createCommentWithAllSingleFileComments: true, 403 | createSingleFileComments: true, 404 | commentOnlyChangedContent: true, 405 | commentOnlyChangedFiles: true, 406 | minSeverity: 'INFO', 407 | maxNumberOfViolations: 99999, 408 | keepOldComments: false, 409 | 410 | commentTemplate: """ 411 | **Reporter**: {{violation.reporter}}{{#violation.rule}} 412 | 413 | **Rule**: {{violation.rule}}{{/violation.rule}} 414 | **Severity**: {{violation.severity}} 415 | **File**: {{violation.file}} L{{violation.startLine}}{{#violation.source}} 416 | 417 | **Source**: {{violation.source}}{{/violation.source}} 418 | 419 | {{violation.message}} 420 | """, 421 | 422 | violationConfigs: [ 423 | [ pattern: '.*/checkstyle-result\\.xml$', parser: 'CHECKSTYLE', reporter: 'Checkstyle' ], 424 | [ pattern: '.*/findbugsXml\\.xml$', parser: 'FINDBUGS', reporter: 'Findbugs' ], 425 | [ pattern: '.*/pmd\\.xml$', parser: 'PMD', reporter: 'PMD' ], 426 | ] 427 | ] 428 | ]) 429 | } 430 | } 431 | ``` 432 | 433 | # Plugin development 434 | More details on Jenkins plugin development is available [here](https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial). 435 | 436 | There is a ```/build.sh``` that will perform a full build and test the plugin. 437 | 438 | If you have release-permissions this is how you do a release: 439 | 440 | ``` 441 | mvn release:prepare release:perform 442 | ``` 443 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Violation Comments to GitHub changelog 2 | Changelog of Violation Comments to GitHub plugin for Jenkins. 3 | ## 1.96 4 | ### No issue 5 | 6 | **feat: stepping lib versions** 7 | 8 | 9 | [dad8e9c11c6b07c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/dad8e9c11c6b07c) Tomas Bjerre *2022-03-27 07:14:27* 10 | 11 | 12 | ## 1.95 13 | ### No issue 14 | 15 | **feat: MSBuild parser** 16 | 17 | 18 | [992090e864605eb](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/992090e864605eb) Tomas Bjerre *2021-06-16 17:31:53* 19 | 20 | **Merge pull request #38 from jenkinsci/dependabot/maven/junit-junit-4.13.1** 21 | 22 | * Bump junit from 4.12 to 4.13.1 23 | 24 | [18a7193198e3b1e](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/18a7193198e3b1e) Tomas Bjerre *2020-10-13 03:05:03* 25 | 26 | **Bump junit from 4.12 to 4.13.1** 27 | 28 | * Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. 29 | * - [Release notes](https://github.com/junit-team/junit4/releases) 30 | * - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) 31 | * - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) 32 | * Signed-off-by: dependabot[bot] <support@github.com> 33 | 34 | [cf74b677d6b9764](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/cf74b677d6b9764) dependabot[bot] *2020-10-12 21:21:31* 35 | 36 | 37 | ## 1.94 38 | ### No issue 39 | 40 | **Find Security Bugs messages** 41 | 42 | 43 | [21876eedb522c2a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/21876eedb522c2a) Tomas Bjerre *2020-09-27 17:35:02* 44 | 45 | **Merge pull request #37 from timja/patch-1** 46 | 47 | * Remove unneeded configuration in buildPlugin 48 | 49 | [f79093989775ae7](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/f79093989775ae7) Tomas Bjerre *2020-07-26 06:27:44* 50 | 51 | **Remove unneeded configuration in buildPlugin** 52 | 53 | * 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. 54 | 55 | [5ad3af31c2a376b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5ad3af31c2a376b) Tim Jacomb *2020-07-25 14:42:19* 56 | 57 | 58 | ## 1.93 59 | ### No issue 60 | 61 | **New: custom logging in violations-lib** 62 | 63 | 64 | [9337ca5aef0f264](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/9337ca5aef0f264) Tomas Bjerre *2020-07-05 14:15:55* 65 | 66 | 67 | ## 1.92 68 | ### No issue 69 | 70 | **Fixing SECURITY-1854** 71 | 72 | 73 | [50568b543f67268](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/50568b543f67268) Tomas Bjerre *2020-05-20 14:45:39* 74 | 75 | 76 | ## 1.91 77 | ### No issue 78 | 79 | **Correcting line in single file comments tomasbjerre/violation-comments-to-github-lib#9** 80 | 81 | 82 | [65b327ee8194139](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/65b327ee8194139) Tomas Bjerre *2020-04-28 17:08:23* 83 | 84 | 85 | ## 1.90 86 | ### No issue 87 | 88 | **CPPCheckParser with auto closed tags tomasbjerre/violations-lib#82** 89 | 90 | 91 | [962d71252b0c62a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/962d71252b0c62a) Tomas Bjerre *2020-02-03 16:34:30* 92 | 93 | 94 | ## 1.89 95 | ### No issue 96 | 97 | **Add support for sonar issue report formats >= v7.5 tomasbjerre/violations-lib#80** 98 | 99 | 100 | [8741a8338df6c84](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/8741a8338df6c84) Tomas Bjerre *2020-01-03 07:36:07* 101 | 102 | 103 | ## 1.88 104 | ### No issue 105 | 106 | **Setting URL to README.md to update plugins.jenkins.io** 107 | 108 | 109 | [de2df2d627668f0](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/de2df2d627668f0) Tomas Bjerre *2019-10-24 18:40:13* 110 | 111 | 112 | ## 1.87 113 | ### No issue 114 | 115 | **Protolint tomasbjerre/violations-lib#79** 116 | 117 | 118 | [1e3eef14cba7827](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/1e3eef14cba7827) Tomas Bjerre *2019-10-22 03:32:23* 119 | 120 | 121 | ## 1.86 122 | ### No issue 123 | 124 | **Merge pull request #35 from jenkinsci/feature/hadolint** 125 | 126 | * Hadolint 127 | 128 | [104da92173d454d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/104da92173d454d) Tomas Bjerre *2019-10-14 15:37:36* 129 | 130 | **Hadolint** 131 | 132 | 133 | [36f2c6401fb8a27](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/36f2c6401fb8a27) Tomas Bjerre *2019-10-14 15:35:44* 134 | 135 | **Create FUNDING.yml** 136 | 137 | 138 | [da9e4b3338a2aa5](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/da9e4b3338a2aa5) Tomas Bjerre *2019-09-28 06:52:30* 139 | 140 | 141 | ## 1.85 142 | ### No issue 143 | 144 | **Removing newline before fingerprint** 145 | 146 | 147 | [22ef2dfe9d9a590](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/22ef2dfe9d9a590) Tomas Bjerre *2019-08-29 18:44:32* 148 | 149 | 150 | ## 1.84 151 | ### No issue 152 | 153 | **Changing name of JSHINT parser to JSLINT** 154 | 155 | 156 | [af3ca259a3ec347](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/af3ca259a3ec347) Tomas Bjerre *2019-08-03 11:25:38* 157 | 158 | 159 | ## 1.83 160 | ### No issue 161 | 162 | **Allowing HTTP and HTTPS to be used #32** 163 | 164 | * Was always using HTTPS 165 | 166 | [9a90f1ace1799d2](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/9a90f1ace1799d2) Tomas Bjerre *2019-06-25 18:06:30* 167 | 168 | 169 | ## 1.82 170 | ### No issue 171 | 172 | **junit** 173 | 174 | 175 | [d6c4d9a6f3e7670](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d6c4d9a6f3e7670) Tomas Bjerre *2019-06-16 16:38:49* 176 | 177 | 178 | ## 1.81 179 | ### No issue 180 | 181 | **commentOnlyChangedFiles** 182 | 183 | 184 | [32be8a3fbc06120](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/32be8a3fbc06120) Tomas Bjerre *2019-06-16 16:07:40* 185 | 186 | **doc** 187 | 188 | 189 | [656b4ad7a0193ec](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/656b4ad7a0193ec) Tomas Bjerre *2019-06-13 14:44:06* 190 | 191 | 192 | ## 1.80 193 | ### No issue 194 | 195 | **Cpplint correction to handle line None** 196 | 197 | 198 | [8258a5fe310898e](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/8258a5fe310898e) Tomas Bjerre *2019-04-24 16:40:39* 199 | 200 | 201 | ## 1.79 202 | ### No issue 203 | 204 | **maxNumberOfViolations** 205 | 206 | 207 | [8cf8f11eeaaf54e](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/8cf8f11eeaaf54e) Tomas Bjerre *2019-03-31 13:35:26* 208 | 209 | 210 | ## 1.78 211 | ### No issue 212 | 213 | **Sonar Report** 214 | 215 | 216 | [256cac99dbf797c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/256cac99dbf797c) Tomas Bjerre *2019-03-23 15:08:16* 217 | 218 | 219 | ## 1.77 220 | ### No issue 221 | 222 | **Klocwork line numbers** 223 | 224 | 225 | [5a5d76728d44c12](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5a5d76728d44c12) Tomas Bjerre *2019-03-13 19:23:08* 226 | 227 | 228 | ## 1.76 229 | ### No issue 230 | 231 | **golangci-lint** 232 | 233 | 234 | [7a6f016eb50bdc9](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/7a6f016eb50bdc9) Tomas Bjerre *2019-03-07 16:05:02* 235 | 236 | 237 | ## 1.75 238 | ### No issue 239 | 240 | **Fixing Flake8 parser** 241 | 242 | 243 | [1092bacf602e0c4](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/1092bacf602e0c4) Tomas Bjerre *2019-02-11 19:58:30* 244 | 245 | 246 | ## 1.74 247 | ### No issue 248 | 249 | **MSCPP and IAR** 250 | 251 | 252 | [e7246b226c2c1d8](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/e7246b226c2c1d8) Tomas Bjerre *2019-01-29 17:31:01* 253 | 254 | 255 | ## 1.73 256 | ### No issue 257 | 258 | **Avoiding faulty slash with CodeNarc** 259 | 260 | 261 | [d6eca741b971760](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d6eca741b971760) Tomas Bjerre *2019-01-14 17:56:13* 262 | 263 | 264 | ## 1.72 265 | ### No issue 266 | 267 | **Making CodeNarc respect source directory** 268 | 269 | 270 | [7c5e784a77af83b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/7c5e784a77af83b) Tomas Bjerre *2019-01-09 19:49:47* 271 | 272 | 273 | ## 1.71 274 | ### No issue 275 | 276 | **Correcting AnsibleLint parsing** 277 | 278 | 279 | [90047b3d7b9f50c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/90047b3d7b9f50c) Tomas Bjerre *2019-01-03 17:54:49* 280 | 281 | **Merge pull request #29 from recena/polished** 282 | 283 | * Repository and PluginRepository updated. And fixed SCM URL 284 | 285 | [62ddef367fe534d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/62ddef367fe534d) Tomas Bjerre *2018-11-18 19:20:49* 286 | 287 | **Repository and PluginRepository updated. And fixed SCM URL** 288 | 289 | 290 | [268bfae711c6afc](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/268bfae711c6afc) Manuel Recena *2018-11-18 19:18:58* 291 | 292 | **Stepping lib** 293 | 294 | 295 | [a5c987728092357](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/a5c987728092357) Tomas Bjerre *2018-10-08 17:04:35* 296 | 297 | 298 | ## 1.70 299 | ### No issue 300 | 301 | **Including entire rule in Flake8** 302 | 303 | 304 | [dcc2bae047cbb2d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/dcc2bae047cbb2d) Tomas Bjerre *2018-10-06 06:55:42* 305 | 306 | **Automatically stepping dependencies** 307 | 308 | 309 | [23df03e9b83ad6c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/23df03e9b83ad6c) Tomas Bjerre *2018-09-23 19:03:56* 310 | 311 | 312 | ## 1.69 313 | ### No issue 314 | 315 | **Clarifying parsers** 316 | 317 | 318 | [adcce493396bf7b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/adcce493396bf7b) Tomas Bjerre *2018-09-23 13:41:14* 319 | 320 | **Automating reporters in readme** 321 | 322 | 323 | [21f1c6f7aae332c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/21f1c6f7aae332c) Tomas Bjerre *2018-09-23 12:56:29* 324 | 325 | **Doc** 326 | 327 | 328 | [d7a466fe6492707](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d7a466fe6492707) Tomas Bjerre *2018-09-22 18:21:47* 329 | 330 | **Documenting parsers as a table** 331 | 332 | 333 | [845018cab615d99](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/845018cab615d99) Tomas Bjerre *2018-09-22 08:44:26* 334 | 335 | 336 | ## 1.68 337 | ### No issue 338 | 339 | **Correcting Kotlin parsers** 340 | 341 | 342 | [78203adf57bede9](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/78203adf57bede9) Tomas Bjerre *2018-09-21 00:03:33* 343 | 344 | 345 | ## 1.67 346 | ### No issue 347 | 348 | **Kotlin Maven and Gradle parsers** 349 | 350 | 351 | [63ca24adfb94e48](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/63ca24adfb94e48) Tomas Bjerre *2018-09-20 14:26:17* 352 | 353 | 354 | ## 1.66 355 | ### No issue 356 | 357 | **Exception logging in build job log** 358 | 359 | 360 | [ae0f528c9b5dc19](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/ae0f528c9b5dc19) Tomas Bjerre *2018-09-18 19:33:58* 361 | 362 | 363 | ## 1.65 364 | ### No issue 365 | 366 | **More information in log** 367 | 368 | 369 | [a5ec6a3acbb56fb](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/a5ec6a3acbb56fb) Tomas Bjerre *2018-09-18 10:06:50* 370 | 371 | **Issue template** 372 | 373 | 374 | [c6851b2810da707](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/c6851b2810da707) Tomas Bjerre *2018-09-17 17:01:35* 375 | 376 | 377 | ## 1.64 378 | ### No issue 379 | 380 | **Fix optional rule in YAMLLint** 381 | 382 | 383 | [5332e0245fff2b3](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5332e0245fff2b3) Tomas Bjerre *2018-09-17 13:52:49* 384 | 385 | 386 | ## 1.63 387 | ### No issue 388 | 389 | **YAMLLint** 390 | 391 | 392 | [dabeb465c1ab250](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/dabeb465c1ab250) Tomas Bjerre *2018-09-15 08:14:59* 393 | 394 | 395 | ## 1.62 396 | ### No issue 397 | 398 | **Correcting ownerName and CPD** 399 | 400 | 401 | [82f54b5cde0b0a1](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/82f54b5cde0b0a1) Tomas Bjerre *2018-09-13 05:11:51* 402 | 403 | **Updating readme with parsers** 404 | 405 | 406 | [bd08c9b40edc621](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/bd08c9b40edc621) Tomas Bjerre *2018-09-12 17:07:44* 407 | 408 | **Updating fmt-maven-plugin** 409 | 410 | 411 | [529ce56fab07a0d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/529ce56fab07a0d) Tomas Bjerre *2018-08-30 17:51:57* 412 | 413 | 414 | ## 1.61 415 | ### No issue 416 | 417 | **GCC, ARM GCC and Doxygen** 418 | 419 | 420 | [18e292e764304ec](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/18e292e764304ec) Tomas Bjerre *2018-07-04 18:40:09* 421 | 422 | **Correcting license** 423 | 424 | 425 | [e25170ed8560d3a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/e25170ed8560d3a) Tomas Bjerre *2018-06-21 17:22:17* 426 | 427 | **License #27** 428 | 429 | 430 | [aab1a1caefd2bb5](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/aab1a1caefd2bb5) Tomas Bjerre *2018-06-14 15:26:53* 431 | 432 | 433 | ## 1.60 434 | ### No issue 435 | 436 | **Custom commenting template #26** 437 | 438 | 439 | [9a58d1a059a0825](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/9a58d1a059a0825) Tomas Bjerre *2018-05-13 13:46:06* 440 | 441 | **NullAway #33** 442 | 443 | 444 | [c3cbc8af3f15c4c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/c3cbc8af3f15c4c) Tomas Bjerre *2018-04-14 05:12:30* 445 | 446 | 447 | ## 1.59 448 | ### No issue 449 | 450 | **Avoiding crash on agents #23** 451 | 452 | 453 | [2cc04c0f4742339](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/2cc04c0f4742339) Tomas Bjerre *2018-03-12 18:30:09* 454 | 455 | 456 | ## 1.58 457 | ### No issue 458 | 459 | **Updating doc on credentials** 460 | 461 | 462 | [aab7ec2890f2b3b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/aab7ec2890f2b3b) Tomas Bjerre *2018-02-27 16:18:29* 463 | 464 | **Merge pull request #21 from casz/master** 465 | 466 | * Combined credentials, Provide item context 467 | 468 | [bd79c1e850b1156](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/bd79c1e850b1156) Tomas Bjerre *2018-02-27 15:32:51* 469 | 470 | **combined credentials and provide item context which fixes #19** 471 | 472 | 473 | [ec4ca5820556f18](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/ec4ca5820556f18) Joseph Petersen *2018-02-26 14:49:37* 474 | 475 | **ignore .idea** 476 | 477 | 478 | [88a1700dbd890ba](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/88a1700dbd890ba) Joseph Petersen *2018-02-24 22:40:20* 479 | 480 | **avoid commit nightmare on windows due to formatter** 481 | 482 | 483 | [570ae4b9f79f73a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/570ae4b9f79f73a) Joseph Petersen *2018-02-24 22:40:20* 484 | 485 | **Javax Nonnull is bad for licensing** 486 | 487 | 488 | [3f966ac2a6232cf](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/3f966ac2a6232cf) Joseph Petersen *2018-02-24 22:40:20* 489 | 490 | **Merge pull request #20 from casz/patch-1** 491 | 492 | * Update Jenkinsfile 493 | 494 | [09ff6e7bbee44ba](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/09ff6e7bbee44ba) Tomas Bjerre *2018-02-24 18:19:51* 495 | 496 | **Update Jenkinsfile** 497 | 498 | 499 | [d63c4547a82ea8a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d63c4547a82ea8a) Joseph Petersen *2018-02-24 15:13:06* 500 | 501 | 502 | ## 1.57 503 | ### No issue 504 | 505 | **PCLint** 506 | 507 | 508 | [072cb29d3d08c1d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/072cb29d3d08c1d) Tomas Bjerre *2018-02-13 20:00:58* 509 | 510 | 511 | ## 1.56 512 | ### No issue 513 | 514 | **PCLint** 515 | 516 | 517 | [2698768fc4b20f1](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/2698768fc4b20f1) Tomas Bjerre *2018-02-13 19:29:30* 518 | 519 | 520 | ## 1.55 521 | ### No issue 522 | 523 | **Refactoring** 524 | 525 | * Refactoring jelly templates and code close to that. 526 | * Avoiding storing username/password in xml, as part of the job. Forcing credentials. 527 | 528 | [1027e084098bec1](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/1027e084098bec1) Tomas Bjerre *2018-01-28 12:47:29* 529 | 530 | 531 | ## 1.54 532 | ### No issue 533 | 534 | **Google error-prone** 535 | 536 | 537 | [6af5cf757ee7264](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/6af5cf757ee7264) Tomas Bjerre *2018-01-14 12:13:32* 538 | 539 | **Merge pull request #17 from Mokto/patch-1** 540 | 541 | * Update README.md 542 | 543 | [b7b2d55fc213186](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/b7b2d55fc213186) Tomas Bjerre *2018-01-12 15:53:07* 544 | 545 | **Update README.md** 546 | 547 | 548 | [f9bb014d3454cc2](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/f9bb014d3454cc2) Théo Mathieu *2018-01-12 15:41:34* 549 | 550 | 551 | ## 1.53 552 | ### No issue 553 | 554 | **Relocating to correct Java identifier** 555 | 556 | 557 | [6eb63e22ec73756](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/6eb63e22ec73756) Tomas Bjerre *2017-12-31 12:01:40* 558 | 559 | 560 | ## 1.52 561 | ### No issue 562 | 563 | **Fixing encoding issues** 564 | 565 | 566 | [15f9d221b8c4284](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/15f9d221b8c4284) Tomas Bjerre *2017-12-25 20:12:30* 567 | 568 | **Bumping version to fix faulty release** 569 | 570 | 571 | [a6d075acb73b661](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/a6d075acb73b661) Tomas Bjerre *2017-12-22 19:58:19* 572 | 573 | 574 | ## 1.51 575 | ### No issue 576 | 577 | **DocFX parsing JSON with Gson, not ScriptEngine** 578 | 579 | 580 | [4db67c4b9fe4477](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/4db67c4b9fe4477) Tomas Bjerre *2017-12-22 12:58:10* 581 | 582 | 583 | ## 1.50 584 | ### No issue 585 | 586 | **DocFX** 587 | 588 | 589 | [438aea17a1d84a7](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/438aea17a1d84a7) Tomas Bjerre *2017-12-21 14:35:58* 590 | 591 | 592 | ## 1.49 593 | ### No issue 594 | 595 | **Accepting PMD files without ruleset-tag #15** 596 | 597 | 598 | [bab0cbdb72832d8](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/bab0cbdb72832d8) Tomas Bjerre *2017-12-07 16:20:05* 599 | 600 | **Doc #12** 601 | 602 | 603 | [8b0981ad78f8f28](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/8b0981ad78f8f28) Tomas Bjerre *2017-12-07 16:19:59* 604 | 605 | 606 | ## 1.48 607 | ### No issue 608 | 609 | **Resharper WikiUrl** 610 | 611 | 612 | [d8c933355fdb03d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d8c933355fdb03d) Tomas Bjerre *2017-10-13 11:32:28* 613 | 614 | 615 | ## 1.47 616 | ### No issue 617 | 618 | **Added handling for empty IssueType Description attributes for Resharper** 619 | 620 | 621 | [bda2539ad156ddc](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/bda2539ad156ddc) Tomas Bjerre *2017-10-09 16:54:33* 622 | 623 | 624 | ## 1.46 625 | ### No issue 626 | 627 | **Allowing reporter to be unset** 628 | 629 | 630 | [bc2fba04bce49d2](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/bc2fba04bce49d2) Tomas Bjerre *2017-09-26 19:42:15* 631 | 632 | 633 | ## 1.45 634 | ### No issue 635 | 636 | **Keeping comments and adjusting checkstyle** 637 | 638 | * Checkstyle now allows empty source attribute. 639 | * Comments can optionaly be kept and not removed when new comments are added. 640 | * Will no longer re-create identical comments. 641 | 642 | [ceb659857786c57](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/ceb659857786c57) Tomas Bjerre *2017-09-02 16:07:54* 643 | 644 | **doc** 645 | 646 | 647 | [e74541eabb67f8c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/e74541eabb67f8c) Tomas Bjerre *2017-08-11 12:22:52* 648 | 649 | 650 | ## 1.44 651 | ### No issue 652 | 653 | **Ignoring violation configs with null config** 654 | 655 | 656 | [3841a5fd750f44b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/3841a5fd750f44b) Tomas Bjerre *2017-08-11 11:39:26* 657 | 658 | **Cleaning** 659 | 660 | 661 | [e8952022fd39b08](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/e8952022fd39b08) Tomas Bjerre *2017-07-16 05:11:10* 662 | 663 | **doc** 664 | 665 | 666 | [5e5b8c13bcb1358](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5e5b8c13bcb1358) Tomas Bjerre *2017-07-15 13:12:08* 667 | 668 | 669 | ## 1.43 670 | ### No issue 671 | 672 | **Violations-lib 1.29 with reporter field** 673 | 674 | 675 | [0bc098b75f17a2d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/0bc098b75f17a2d) Tomas Bjerre *2017-07-15 13:05:23* 676 | 677 | **Updating doc on Infer** 678 | 679 | 680 | [91fec5e4924011b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/91fec5e4924011b) Tomas Bjerre *2017-06-23 12:53:02* 681 | 682 | **doc** 683 | 684 | 685 | [449549b9526e599](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/449549b9526e599) Tomas Bjerre *2017-06-13 18:00:56* 686 | 687 | **doc** 688 | 689 | 690 | [09486c35ba0af9b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/09486c35ba0af9b) Tomas Bjerre *2017-04-22 04:33:06* 691 | 692 | 693 | ## 1.42 694 | ### No issue 695 | 696 | **URL in Klocwork** 697 | 698 | 699 | [c3ed28671e52de7](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/c3ed28671e52de7) Tomas Bjerre *2017-04-11 18:29:13* 700 | 701 | **doc** 702 | 703 | 704 | [09a1f863256f5a0](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/09a1f863256f5a0) Tomas Bjerre *2017-04-10 20:17:03* 705 | 706 | 707 | ## 1.41 708 | ### No issue 709 | 710 | **SbtScalac** 711 | 712 | 713 | [bbe723b0b3d4bd5](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/bbe723b0b3d4bd5) Tomas Bjerre *2017-04-10 18:39:47* 714 | 715 | **Generic example** 716 | 717 | 718 | [97f30bb5329202e](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/97f30bb5329202e) Tomas Bjerre *2017-04-09 08:20:18* 719 | 720 | 721 | ## 1.40 722 | ### No issue 723 | 724 | **Klocwork parser** 725 | 726 | 727 | [a75d54b6eab37ea](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/a75d54b6eab37ea) Tomas Bjerre *2017-03-30 17:51:52* 728 | 729 | **doc** 730 | 731 | 732 | [2906a7e367e2729](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/2906a7e367e2729) Tomas Bjerre *2017-03-18 19:08:54* 733 | 734 | 735 | ## 1.39 736 | ### No issue 737 | 738 | **Persisting severity filter on global config** 739 | 740 | 741 | [2ac73dd3215c141](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/2ac73dd3215c141) Tomas Bjerre *2017-03-17 20:57:55* 742 | 743 | 744 | ## 1.38 745 | ### No issue 746 | 747 | **Allowing filter comments on severity #10** 748 | 749 | * Also defaulting to api.github.com if field is empty. #9 750 | 751 | [5958d9a80ddf1b2](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5958d9a80ddf1b2) Tomas Bjerre *2017-03-17 18:02:47* 752 | 753 | **Jenkinsfile** 754 | 755 | 756 | [fa697debfe6d97a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/fa697debfe6d97a) Tomas Bjerre *2017-03-10 17:40:20* 757 | 758 | **doc** 759 | 760 | 761 | [1dbbacbab993d13](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/1dbbacbab993d13) Tomas Bjerre *2017-03-04 09:28:31* 762 | 763 | **Update README.md** 764 | 765 | 766 | [673234d43029dd6](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/673234d43029dd6) Tomas Bjerre *2017-02-20 15:57:27* 767 | 768 | **Update README.md** 769 | 770 | 771 | [10242d7a5de3f0e](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/10242d7a5de3f0e) Tomas Bjerre *2017-02-20 15:56:18* 772 | 773 | 774 | ## 1.37 775 | ### No issue 776 | 777 | **Commenting with file name from server** 778 | 779 | 780 | [7184df2da14c72a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/7184df2da14c72a) Tomas Bjerre *2017-02-19 21:30:36* 781 | 782 | **doc** 783 | 784 | 785 | [2429fec6fa7f0b8](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/2429fec6fa7f0b8) Tomas Bjerre *2017-02-18 22:08:49* 786 | 787 | 788 | ## 1.36 789 | ### No issue 790 | 791 | **CLang, RubyCop, GoLint, GoVet, PHPMD, PHPCS** 792 | 793 | 794 | [94a505d3a67aa6f](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/94a505d3a67aa6f) Tomas Bjerre *2017-02-18 22:05:31* 795 | 796 | 797 | ## 1.32 798 | ### No issue 799 | 800 | **Finding findbugsmessages and correcting codenarc** 801 | 802 | 803 | [e78f18d2613908a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/e78f18d2613908a) Tomas Bjerre *2017-02-16 21:16:32* 804 | 805 | 806 | ## 1.31 807 | ### No issue 808 | 809 | **Clarifying 'state' option in notification GUI #195** 810 | 811 | 812 | [047e01eae1e79db](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/047e01eae1e79db) Tomas Bjerre *2017-02-16 21:15:13* 813 | 814 | 815 | ## 1.30 816 | ### No issue 817 | 818 | **Finding findbugsmessages and correcting codenarc** 819 | 820 | 821 | [1be9a11200fd667](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/1be9a11200fd667) Tomas Bjerre *2017-02-16 21:11:56* 822 | 823 | **doc** 824 | 825 | 826 | [beb6dd2c72c8771](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/beb6dd2c72c8771) Tomas Bjerre *2017-02-06 18:44:12* 827 | 828 | 829 | ## 1.29 830 | ### No issue 831 | 832 | **Correcting distribution management repo** 833 | 834 | 835 | [162ce5134361273](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/162ce5134361273) Tomas Bjerre *2017-02-06 18:14:09* 836 | 837 | 838 | ## 1.28 839 | ### No issue 840 | 841 | **Adding MyPy and PyDocStyle parsers** 842 | 843 | 844 | [63049ee7afe212b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/63049ee7afe212b) Tomas Bjerre *2017-02-06 17:57:36* 845 | 846 | 847 | ## 1.27 848 | ### No issue 849 | 850 | **Codenarc, Cpd, Gendarme, Jcereport, Simian, ZptLint** 851 | 852 | 853 | [26ba3bf8ec325be](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/26ba3bf8ec325be) Tomas Bjerre *2016-11-06 07:11:21* 854 | 855 | 856 | ## 1.26 857 | ### No issue 858 | 859 | **Bugfix, the big comment now includes only changed parts** 860 | 861 | 862 | [69810d73a4ec3d9](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/69810d73a4ec3d9) Tomas Bjerre *2016-11-01 19:06:04* 863 | 864 | 865 | ## 1.25 866 | ### No issue 867 | 868 | **Markdown in comments and not commenting unchanged files** 869 | 870 | 871 | [c201ad1d5ef41f7](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/c201ad1d5ef41f7) Tomas Bjerre *2016-10-27 17:13:16* 872 | 873 | 874 | ## 1.24 875 | ### No issue 876 | 877 | **Handling CSS Lint reports without line or evidence** 878 | 879 | 880 | [3c0a3d980c5147a](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/3c0a3d980c5147a) Tomas Bjerre *2016-10-26 16:04:09* 881 | 882 | 883 | ## 1.23 884 | ### No issue 885 | 886 | **Changing rule format in PyLint to CODE(codeName)** 887 | 888 | 889 | [dd0a22941cfc489](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/dd0a22941cfc489) Tomas Bjerre *2016-10-25 18:33:23* 890 | 891 | **doc** 892 | 893 | 894 | [120e3dc6f693cea](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/120e3dc6f693cea) Tomas Bjerre *2016-10-24 20:27:17* 895 | 896 | 897 | ## 1.22 898 | ### No issue 899 | 900 | **Print entire stacktrace in Jenkins log** 901 | 902 | 903 | [33601b335a16a1c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/33601b335a16a1c) Tomas Bjerre *2016-10-24 20:18:41* 904 | 905 | 906 | ## 1.21 907 | ### No issue 908 | 909 | **PyLint parser** 910 | 911 | 912 | [7daa784bb27901d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/7daa784bb27901d) Tomas Bjerre *2016-10-24 19:03:08* 913 | 914 | 915 | ## 1.20 916 | ### No issue 917 | 918 | **Supporting StyleCop and fixing FxCop** 919 | 920 | 921 | [86728e21ca6007c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/86728e21ca6007c) Tomas Bjerre *2016-10-03 17:25:58* 922 | 923 | **doc** 924 | 925 | 926 | [25dc27205914a41](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/25dc27205914a41) Tomas Bjerre *2016-10-01 13:32:13* 927 | 928 | 929 | ## 1.19 930 | ### No issue 931 | 932 | **FXCop** 933 | 934 | 935 | [d5f7f2b17f3d3ce](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d5f7f2b17f3d3ce) Tomas Bjerre *2016-10-01 11:57:53* 936 | 937 | 938 | ## 1.18 939 | ### No issue 940 | 941 | **Distribution management in pom** 942 | 943 | 944 | [1207f7a8c721dbd](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/1207f7a8c721dbd) Tomas Bjerre *2016-09-25 08:37:51* 945 | 946 | 947 | ## 1.17 948 | ### No issue 949 | 950 | **Enabling using OAuth2 token from credentials #6** 951 | 952 | 953 | [3a5cc413a172fb5](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/3a5cc413a172fb5) Tomas Bjerre *2016-09-25 08:31:43* 954 | 955 | **doc** 956 | 957 | 958 | [6d74691070d94c0](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/6d74691070d94c0) Tomas Bjerre *2016-08-13 09:48:39* 959 | 960 | 961 | ## 1.16 962 | ### No issue 963 | 964 | **Evaluating credentials on master** 965 | 966 | 967 | [ef792066f9da126](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/ef792066f9da126) Tomas Bjerre *2016-08-13 09:04:48* 968 | 969 | 970 | ## 1.15 971 | ### No issue 972 | 973 | **Allowing pipeline DSL not to specify all reporters** 974 | 975 | 976 | [012593ed8acc4e3](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/012593ed8acc4e3) Tomas Bjerre *2016-08-11 19:01:05* 977 | 978 | 979 | ## 1.14 980 | ### No issue 981 | 982 | **Correcting job DSL** 983 | 984 | 985 | [f744cd609f27abf](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/f744cd609f27abf) Tomas Bjerre *2016-08-10 17:16:20* 986 | 987 | **Cleaning up pom.xml** 988 | 989 | 990 | [c46f4b0761f509d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/c46f4b0761f509d) Tomas Bjerre *2016-08-10 14:39:33* 991 | 992 | 993 | ## 1.13 994 | ### No issue 995 | 996 | **job-dsl-plugin compatible** 997 | 998 | * Adding @DataBoundConstructor to ViolationConfig to make it compatible with job-dsl-plugin. 999 | 1000 | [012460472023788](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/012460472023788) Tomas Bjerre *2016-08-09 17:58:22* 1001 | 1002 | 1003 | ## 1.12 1004 | ### No issue 1005 | 1006 | **Making credentials option persistent in job config view** 1007 | 1008 | 1009 | [c1ad09cf93badf8](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/c1ad09cf93badf8) Tomas Bjerre *2016-08-02 18:10:16* 1010 | 1011 | 1012 | ## 1.11 1013 | ### No issue 1014 | 1015 | **Credentials plugin #4** 1016 | 1017 | 1018 | [7d0b7e29d250ee7](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/7d0b7e29d250ee7) Tomas Bjerre *2016-08-02 05:29:32* 1019 | 1020 | **Reformat of Java code** 1021 | 1022 | 1023 | [fbb5ebe369e3f50](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/fbb5ebe369e3f50) Tomas Bjerre *2016-08-01 06:39:21* 1024 | 1025 | **Scripts for running and debuging** 1026 | 1027 | 1028 | [5558a1b40524b3d](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5558a1b40524b3d) Tomas Bjerre *2016-07-30 19:26:54* 1029 | 1030 | 1031 | ## 1.10 1032 | ### No issue 1033 | 1034 | **doc** 1035 | 1036 | 1037 | [fe2cf00ccdc98bc](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/fe2cf00ccdc98bc) Tomas Bjerre *2016-04-27 14:51:08* 1038 | 1039 | **Andoid lint** 1040 | 1041 | 1042 | [3dbced66cbfd772](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/3dbced66cbfd772) Tomas Bjerre *2016-04-27 06:07:29* 1043 | 1044 | 1045 | ## 1.9 1046 | ### No issue 1047 | 1048 | **Making Violation class serializable** 1049 | 1050 | 1051 | [2fb059a894ac812](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/2fb059a894ac812) Tomas Bjerre *2016-04-23 17:23:49* 1052 | 1053 | 1054 | ## 1.8 1055 | ### No issue 1056 | 1057 | **git-changelog-lib 1.6, improved FindBugs parsing** 1058 | 1059 | * Improving changelog 1060 | * And formatting some code after merge of PR. 1061 | 1062 | [d6b9c6b15b4a3a7](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d6b9c6b15b4a3a7) Tomas Bjerre *2016-04-07 17:33:36* 1063 | 1064 | **Merge pull request #3 from magnayn/master** 1065 | 1066 | * Various changes to support use of plugin within Jenkins workflow 1067 | 1068 | [b72d0074774fe80](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/b72d0074774fe80) Tomas Bjerre *2016-04-07 16:54:08* 1069 | 1070 | **Add some readme text about workflow.** 1071 | 1072 | * Signed-off-by: Nigel Magnay <nigel.magnay@gmail.com> 1073 | 1074 | [5029467d13b6ecc](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5029467d13b6ecc) Nigel Magnay *2016-04-07 16:21:15* 1075 | 1076 | **Set a default github url if not specified.** 1077 | 1078 | * Signed-off-by: Nigel Magnay <nigel.magnay@gmail.com> 1079 | 1080 | [5500b30687f5789](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/5500b30687f5789) Nigel Magnay *2016-04-07 16:06:38* 1081 | 1082 | **Various fixes required to make this work inside workflow.** 1083 | 1084 | * Signed-off-by: Nigel Magnay <nigel.magnay@gmail.com> 1085 | 1086 | [653298302969315](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/653298302969315) Nigel Magnay *2016-04-07 14:58:22* 1087 | 1088 | **Allow defaults to be specified as a part of Jenkins configuration.** 1089 | 1090 | * If you use workflow, your Jenkinsfile may be public - so you don't want 1091 | * your github credentials to be in there for all to see. 1092 | * Signed-off-by: Nigel Magnay <nigel.magnay@gmail.com> 1093 | 1094 | [a1236a4360179f6](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/a1236a4360179f6) Nigel Magnay *2016-04-07 12:08:37* 1095 | 1096 | **Support Jenkins Workflow.** 1097 | 1098 | * Signed-off-by: Nigel Magnay <nigel.magnay@gmail.com> 1099 | 1100 | [d6bc1c2dddcebed](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d6bc1c2dddcebed) Nigel Magnay *2016-04-07 12:06:53* 1101 | 1102 | 1103 | ## 1.7 1104 | ### No issue 1105 | 1106 | **Using comment only changed part of content correctly #5** 1107 | 1108 | * Was not expanding it. 1109 | * Also printing usage of username/password or oauth correcly in log. 1110 | 1111 | [d4ff698d9f5ad7f](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d4ff698d9f5ad7f) Tomas Bjerre *2016-04-07 04:48:01* 1112 | 1113 | 1114 | ## 1.6 1115 | ### No issue 1116 | 1117 | **Merge pull request #2 from anomalizer/remote-workspace** 1118 | 1119 | * Ability to execute plugin on remote slaves 1120 | 1121 | [3928d1ffbcfa977](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/3928d1ffbcfa977) Tomas Bjerre *2016-04-05 15:10:53* 1122 | 1123 | **Ability to execute plugin on remote slaves** 1124 | 1125 | * Accessing files on remote slaves requires one level of indirection by 1126 | * using workspace.channel(). Also, all the configurations needs to be 1127 | * serializable for this to work. 1128 | 1129 | [c66f26c4b7f0e3c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/c66f26c4b7f0e3c) Arvind Jayaprakash *2016-04-05 11:30:24* 1130 | 1131 | 1132 | ## 1.5 1133 | ### No issue 1134 | 1135 | **Trying to support slaves setup** 1136 | 1137 | 1138 | [b26fedebb903559](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/b26fedebb903559) Tomas Bjerre *2016-03-10 18:09:56* 1139 | 1140 | **retrigger build** 1141 | 1142 | 1143 | [b514c5e787cb163](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/b514c5e787cb163) Tomas Bjerre *2016-03-10 06:43:17* 1144 | 1145 | **Updating changelog** 1146 | 1147 | 1148 | [1a14f4f2f0a134b](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/1a14f4f2f0a134b) Tomas Bjerre *2016-03-09 17:54:15* 1149 | 1150 | 1151 | ## 1.4 1152 | ### No issue 1153 | 1154 | **Commenting on correct commit in PR** 1155 | 1156 | 1157 | [38ab30d4750b5a9](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/38ab30d4750b5a9) Tomas Bjerre *2016-03-09 17:45:25* 1158 | 1159 | **Update README.md** 1160 | 1161 | 1162 | [3968495eaec79c3](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/3968495eaec79c3) Tomas Bjerre *2016-03-09 07:08:37* 1163 | 1164 | **Updating screenshots** 1165 | 1166 | 1167 | [0dc00348e47ee77](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/0dc00348e47ee77) Tomas Bjerre *2016-03-08 20:36:20* 1168 | 1169 | **Updating changelog** 1170 | 1171 | 1172 | [d90dbb2a95e0ad6](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/d90dbb2a95e0ad6) Tomas Bjerre *2016-03-08 18:07:31* 1173 | 1174 | 1175 | ## 1.3 1176 | ### No issue 1177 | 1178 | **Optionally only comment the changed part in diffs** 1179 | 1180 | 1181 | [f600a0c78bfe0ff](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/f600a0c78bfe0ff) Tomas Bjerre *2016-03-08 18:05:32* 1182 | 1183 | **Correcting image links in README.md** 1184 | 1185 | 1186 | [111022d060bff50](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/111022d060bff50) Tomas Bjerre *2016-03-07 20:34:18* 1187 | 1188 | 1189 | ## 1.2 1190 | ### No issue 1191 | 1192 | **Cleaning up pom a bit** 1193 | 1194 | 1195 | [0cf33a158c76844](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/0cf33a158c76844) Tomas Bjerre *2016-03-07 19:15:25* 1196 | 1197 | 1198 | ## 1.0 1199 | ### No issue 1200 | 1201 | **Initial** 1202 | 1203 | 1204 | [f8b2993bc4d3a0c](https://github.com/jenkinsci/violation-comments-to-github-plugin/commit/f8b2993bc4d3a0c) Tomas Bjerre *2016-03-07 18:46:48* 1205 | 1206 | 1207 | --------------------------------------------------------------------------------