Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JENKINS-39192 - support for updating custom fields
Merge branch 'tequillaz-feature/issue_custom_field_updater' * tequillaz-feature/issue_custom_field_updater: Add JiraIssueFieldUpdater and JiraIssueField
- Loading branch information
Showing
9 changed files
with
421 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package hudson.plugins.jira; | ||
|
||
import java.lang.String; | ||
|
||
public class JiraIssueField implements Comparable<JiraIssueField> { | ||
|
||
private final String fieldId; | ||
private final Object fieldValue; | ||
|
||
public JiraIssueField(String fieldId, Object fieldValue) { | ||
this.fieldId = fieldId; | ||
this.fieldValue = fieldValue; | ||
} | ||
|
||
public int compareTo(JiraIssueField that) { | ||
return this.compareTo(that); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
final int prime = 31; | ||
int result = 1; | ||
result = prime * result + ((fieldId == null) ? 0 : fieldId.hashCode()); | ||
result = prime * result + ((fieldValue == null) ? 0 : fieldValue.hashCode()); | ||
return result; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (obj == null) { | ||
return false; | ||
} | ||
if (getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
|
||
JiraIssueField other = (JiraIssueField) obj; | ||
if (fieldId == null) { | ||
if (other.fieldId != null) { | ||
return false; | ||
} | ||
} else if (!fieldId.equals(other.fieldId)) { | ||
return false; | ||
} | ||
|
||
if (fieldValue == null) { | ||
if (other.fieldValue != null) { | ||
return false; | ||
} | ||
} else if (!fieldValue.equals(other.fieldValue)) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
public String getId() { | ||
return fieldId; | ||
} | ||
|
||
public Object getValue() { | ||
return fieldValue; | ||
} | ||
|
||
} |
186 changes: 186 additions & 0 deletions
186
src/main/java/hudson/plugins/jira/JiraIssueFieldUpdater.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
package hudson.plugins.jira; | ||
|
||
import java.io.IOException; | ||
import java.io.PrintStream; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import javax.servlet.ServletException; | ||
|
||
import org.kohsuke.stapler.DataBoundConstructor; | ||
import org.kohsuke.stapler.DataBoundSetter; | ||
import org.kohsuke.stapler.QueryParameter; | ||
|
||
import com.atlassian.jira.rest.client.api.RestClientException; | ||
import com.google.common.collect.Lists; | ||
|
||
import hudson.Extension; | ||
import hudson.FilePath; | ||
import hudson.Launcher; | ||
import hudson.Util; | ||
import hudson.matrix.MatrixRun; | ||
import hudson.model.AbstractBuild; | ||
import hudson.model.AbstractProject; | ||
import hudson.model.BuildListener; | ||
import hudson.model.Result; | ||
import hudson.model.Run; | ||
import hudson.model.TaskListener; | ||
import hudson.plugins.jira.selector.AbstractIssueSelector; | ||
import hudson.tasks.BuildStepDescriptor; | ||
import hudson.tasks.Builder; | ||
import hudson.util.FormValidation; | ||
import jenkins.model.Jenkins; | ||
import jenkins.tasks.SimpleBuildStep; | ||
|
||
/** | ||
* Issue custom fields updater | ||
* | ||
* @author Dmitry Frolov tekillaz.dev@gmail.com | ||
* | ||
*/ | ||
public class JiraIssueFieldUpdater extends Builder implements SimpleBuildStep { | ||
|
||
private AbstractIssueSelector issueSelector; | ||
|
||
public AbstractIssueSelector getIssueSelector() { | ||
return this.issueSelector; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setIssueSelector(AbstractIssueSelector issueSelector) { | ||
this.issueSelector = issueSelector; | ||
} | ||
|
||
public String fieldId; | ||
|
||
public String getFieldId() { | ||
return this.fieldId; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setFieldId(String fieldId) { | ||
this.fieldId = fieldId; | ||
} | ||
|
||
public String fieldValue; | ||
|
||
public String getFieldValue() { | ||
return this.fieldValue; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setFieldValue(String fieldValue) { | ||
this.fieldValue = fieldValue; | ||
} | ||
|
||
@DataBoundConstructor | ||
public JiraIssueFieldUpdater(AbstractIssueSelector issueSelector, String fieldId, String fieldValue) { | ||
this.issueSelector = issueSelector; | ||
this.fieldId = fieldId; | ||
this.fieldValue = fieldValue; | ||
} | ||
|
||
public String prepareFieldId(String fieldId) { | ||
String prepared = fieldId; | ||
if (!prepared.startsWith("customfield_")) | ||
prepared = "customfield_" + prepared; | ||
return prepared; | ||
} | ||
|
||
@Override | ||
public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) | ||
throws InterruptedException, IOException { | ||
PrintStream logger = listener.getLogger(); | ||
|
||
AbstractIssueSelector selector = issueSelector; | ||
if (selector == null) { | ||
logger.println("[JIRA][JiraIssueFieldUpdater] No issue selector found!"); | ||
throw new IOException("[JIRA][JiraIssueFieldUpdater] No issue selector found!"); | ||
} | ||
|
||
JiraSite site = JiraSite.get(run.getParent()); | ||
if (site == null) { | ||
logger.println(Messages.Updater_NoJiraSite()); | ||
run.setResult(Result.FAILURE); | ||
return; | ||
} | ||
|
||
JiraSession session = null; | ||
try { | ||
session = site.getSession(); | ||
} catch (IOException e) { | ||
listener.getLogger().println(Messages.Updater_FailedToConnect()); | ||
e.printStackTrace(listener.getLogger()); | ||
} | ||
if (session == null) { | ||
logger.println(Messages.Updater_NoRemoteAccess()); | ||
run.setResult(Result.FAILURE); | ||
return; | ||
} | ||
|
||
Set<String> issues = selector.findIssueIds(run, site, listener); | ||
if (issues.isEmpty()) { | ||
logger.println("[JIRA][JiraIssueFieldUpdater] Issue list is empty!"); | ||
return; | ||
} | ||
|
||
List<JiraIssueField> fields = Lists.newArrayList(); | ||
fields.add(new JiraIssueField(prepareFieldId(fieldId), fieldValue)); | ||
|
||
for (String issue : issues) { | ||
submitFields(session, issue, fields, logger); | ||
} | ||
} | ||
|
||
public void submitFields(JiraSession session, String issueId, List<JiraIssueField> fields, PrintStream logger) { | ||
try { | ||
session.addFields(issueId, fields); | ||
} catch (RestClientException e) { | ||
|
||
if (e.getStatusCode().or(0).equals(404)) { | ||
logger.println(issueId + " - JIRA issue not found"); | ||
} | ||
|
||
if (e.getStatusCode().or(0).equals(403)) { | ||
logger.println(issueId | ||
+ " - Jenkins JIRA user does not have permissions to comment on this issue"); | ||
} | ||
|
||
if (e.getStatusCode().or(0).equals(401)) { | ||
logger.println( | ||
issueId + " - Jenkins JIRA authentication problem"); | ||
} | ||
|
||
logger.println(Messages.Updater_FailedToCommentOnIssue(issueId)); | ||
logger.println(e.getLocalizedMessage()); | ||
} | ||
} | ||
|
||
@Override | ||
public DescriptorImpl getDescriptor() { | ||
return (DescriptorImpl) super.getDescriptor(); | ||
} | ||
|
||
@Extension | ||
public static class DescriptorImpl extends BuildStepDescriptor<Builder> { | ||
|
||
public FormValidation doCheckField_id(@QueryParameter String value) throws IOException, ServletException { | ||
if (Util.fixNull(value).trim().length() == 0) | ||
return FormValidation.warning(Messages.JiraIssueFieldUpdater_NoIssueFieldID()); | ||
if (!value.matches("\\d+")) | ||
return FormValidation.error(Messages.JiraIssueFieldUpdater_NotAtIssueFieldID()); | ||
return FormValidation.ok(); | ||
} | ||
|
||
@Override | ||
public boolean isApplicable(Class<? extends AbstractProject> jobType) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public String getDisplayName() { | ||
return Messages.JiraIssueFieldUpdater_DisplayName(); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/main/resources/hudson/plugins/jira/JiraIssueFieldUpdater/config.jelly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<?jelly escape-by-default='true'?> | ||
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form"> | ||
<f:dropdownDescriptorSelector field="issueSelector" title="${%Issue selector}"/> | ||
<f:entry field="fieldId" title="Custom field ID"> | ||
<f:textbox /> | ||
</f:entry> | ||
<f:entry field="fieldValue" title="Field value"> | ||
<f:textbox /> | ||
</f:entry> | ||
</j:jelly> |
3 changes: 3 additions & 0 deletions
3
src/main/resources/hudson/plugins/jira/JiraIssueFieldUpdater/help-field_id.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div> | ||
Issue custom field ID. For example, 10100 | ||
</div> |
3 changes: 3 additions & 0 deletions
3
src/main/resources/hudson/plugins/jira/JiraIssueFieldUpdater/help.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div> | ||
JiraIssueFieldUpdater can be used to update custom JIRA issue field. | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.