Skip to content

Commit

Permalink
Merge pull request #505 from evoToBetter/master
Browse files Browse the repository at this point in the history
[JENKINS-55342] Add hashtags support in Jenkins building parameters
  • Loading branch information
rsandell committed Apr 10, 2024
2 parents 34dd473 + eccef61 commit 294dbe6
Show file tree
Hide file tree
Showing 24 changed files with 957 additions and 106 deletions.
4 changes: 4 additions & 0 deletions docs/README.adoc
Expand Up @@ -144,6 +144,8 @@ contents should follow this syntax:
----
p=some/project
b^**/master/*
t~.*
h~.*
f~.*\.txt
p=some/other/project
b^**
Expand All @@ -153,6 +155,8 @@ Explanation:

p for project +
b for branch +
t for topic +
h for hashtags +
f for file +
= for plain syntax +
^ for ANT style syntax +
Expand Down
Expand Up @@ -28,6 +28,7 @@
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.CompareType;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.FilePath;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.GerritProject;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.Hashtag;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.Topic;

import org.kohsuke.accmod.Restricted;
Expand Down Expand Up @@ -63,6 +64,7 @@ public final class GerritDynamicUrlProcessor {
private static final String SHORTNAME_PROJECT = "p";
private static final String SHORTNAME_BRANCH = "b";
private static final String SHORTNAME_TOPIC = "t";
private static final String SHORTNAME_HASHTAG = "h";
private static final String SHORTNAME_FILE = "f";
private static final String SHORTNAME_FORBIDDEN_FILE = "o";
private static final int SOCKET_READ_TIMEOUT = 10000;
Expand All @@ -89,6 +91,7 @@ private static Pattern buildLinePattern() {
+ SHORTNAME_PROJECT
+ "|" + SHORTNAME_BRANCH
+ "|" + SHORTNAME_TOPIC
+ "|" + SHORTNAME_HASHTAG
+ "|" + SHORTNAME_FILE
+ "|" + SHORTNAME_FORBIDDEN_FILE
+ ")";
Expand Down Expand Up @@ -141,6 +144,7 @@ private static List<GerritProject> readAndParseTriggerConfig(BufferedReader read
List<GerritProject> dynamicGerritProjects = new ArrayList<GerritProject>();
List<Branch> branches = null;
List<Topic> topics = null;
List<Hashtag> hashtags = null;
List<FilePath> filePaths = null;
List<FilePath> forbiddenFilePaths = null;
GerritProject dynamicGerritProject = null;
Expand Down Expand Up @@ -192,9 +196,11 @@ private static List<GerritProject> readAndParseTriggerConfig(BufferedReader read

branches = new ArrayList<Branch>();
topics = new ArrayList<Topic>();
hashtags = new ArrayList<>();
filePaths = new ArrayList<FilePath>();
forbiddenFilePaths = new ArrayList<FilePath>();
dynamicGerritProject = new GerritProject(type, text, branches, topics, filePaths, forbiddenFilePaths, false);
dynamicGerritProject = new GerritProject(type, text, branches, topics,
filePaths, forbiddenFilePaths, false);
} else if (SHORTNAME_BRANCH.equals(item)) { // Branch
if (branches == null) {
throw new ParseException("Line " + lineNr + ": attempt to use 'Branch' before 'Project'", lineNr);
Expand Down Expand Up @@ -223,6 +229,13 @@ private static List<GerritProject> readAndParseTriggerConfig(BufferedReader read
FilePath filePath = new FilePath(type, text);
forbiddenFilePaths.add(filePath);
dynamicGerritProject.setForbiddenFilePaths(forbiddenFilePaths);
} else if (SHORTNAME_HASHTAG.equals(item)) {
if (hashtags == null) {
throw new ParseException("Line " + lineNr + ": attempt to use 'hashtag' before 'Project'", lineNr);
}
Hashtag hashtag = new Hashtag(type, text);
hashtags.add(hashtag);
dynamicGerritProject.setHashtags(hashtags);
}
}

Expand Down
Expand Up @@ -953,12 +953,12 @@ private boolean isChangeInteresting(Change change, GerritProject project, Gerrit
|| (project.getForbiddenFilePaths() != null && project.getForbiddenFilePaths().size() > 0));

if (isFileTriggerEnabled() && containsFilePathsOrForbiddenFilePaths) {
if (project.isInteresting(change.getProject(), change.getBranch(), change.getTopic(),
if (project.isInteresting(change,
() -> change.getFiles(gerritQueryHandler))) {
shouldTrigger = true;
}
} else {
if (project.isInteresting(change.getProject(), change.getBranch(), change.getTopic())) {
if (project.isInteresting(change)) {
shouldTrigger = true;
}
}
Expand Down Expand Up @@ -1167,9 +1167,10 @@ public boolean isInteresting(GerritTriggeredEvent event) {
}
} else if (event instanceof RefUpdated) {
RefUpdated refUpdated = (RefUpdated)event;
if (p.isInteresting(refUpdated.getRefUpdate().getProject(),
refUpdated.getRefUpdate().getRefName(),
null)) {
Change change = new Change();
change.setProject(refUpdated.getRefUpdate().getProject());
change.setBranch(refUpdated.getRefUpdate().getRefName());
if (p.isInteresting(change)) {
logger.trace("According to {} the event is interesting; event: {}", p, event);
return true;
}
Expand Down
Expand Up @@ -40,6 +40,7 @@
import com.sonymobile.tools.gerrit.gerritevents.dto.events.ChangeRestored;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.CommentAdded;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.HashtagsChanged;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.RefUpdated;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.TopicChanged;
import hudson.model.Job;
Expand All @@ -58,6 +59,7 @@
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
* The parameters to add to a build.
Expand Down Expand Up @@ -253,7 +255,19 @@ public enum GerritTriggerParameters {
/**
* Updated approvals.
*/
GERRIT_EVENT_UPDATED_APPROVALS;
GERRIT_EVENT_UPDATED_APPROVALS,
/**
* Hashtags posted to Gerrit in a change based event.
*/
GERRIT_HASHTAGS,
/**
* Hashtags removed to Gerrit in a hashtags-changed event.
*/
GERRIT_REMOVED_HASHTAGS,
/**
* Hashtags added to Gerrit in a hashtags-changed event.
*/
GERRIT_ADDED_HASHTAGS;

private static final Logger logger = LoggerFactory.getLogger(GerritTriggerParameters.class);

Expand Down Expand Up @@ -408,6 +422,65 @@ public static void setOrCreateParameters(GerritTriggeredEvent gerritEvent, Job p
parameters, String.valueOf(((java.lang.Object)gerritEvent).hashCode()), escapeQuotes);
if (gerritEvent instanceof ChangeBasedEvent) {
ChangeBasedEvent event = (ChangeBasedEvent)gerritEvent;
setOrCreateParametersForChangeBasedEvent(event, parameters, escapeQuotes, nameAndEmailParameterMode,
changeSubjectMode, project, commitMessageMode, commentTextMode);
} else if (gerritEvent instanceof RefUpdated) {
RefUpdated event = (RefUpdated)gerritEvent;
GERRIT_REFNAME.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getRefName(), escapeQuotes);
GERRIT_PROJECT.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getProject(), escapeQuotes);
GERRIT_OLDREV.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getOldRev(), escapeQuotes);
GERRIT_NEWREV.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getNewRev(), escapeQuotes);
}
Account account = gerritEvent.getAccount();
if (account != null) {
nameAndEmailParameterMode.setOrCreateParameterValue(GERRIT_EVENT_ACCOUNT, parameters,
getNameAndEmail(account), ParameterMode.PlainMode.STRING, escapeQuotes);
GERRIT_EVENT_ACCOUNT_NAME.setOrCreateStringParameterValue(
parameters, getName(account), escapeQuotes);
GERRIT_EVENT_ACCOUNT_EMAIL.setOrCreateStringParameterValue(
parameters, getEmail(account), escapeQuotes);
}
Provider provider = gerritEvent.getProvider();
if (provider != null) {
GERRIT_NAME.setOrCreateStringParameterValue(
parameters, provider.getName(), escapeQuotes);
GERRIT_HOST.setOrCreateStringParameterValue(
parameters, provider.getHost(), escapeQuotes);
GERRIT_PORT.setOrCreateStringParameterValue(
parameters, provider.getPort(), escapeQuotes);
GERRIT_SCHEME.setOrCreateStringParameterValue(
parameters, provider.getScheme(), escapeQuotes);
GERRIT_VERSION.setOrCreateStringParameterValue(
parameters, provider.getVersion(), escapeQuotes);
}
}

/**
* To avoid setOrCreateParameters too long,
* move change based event related function to separate method.
* Set or Create parameters for change based event.
*
* @param event ChangeBasedEvent
* @param parameters jenkins job parameters
* @param escapeQuotes do escape quotes or not
* @param nameAndEmailParameterMode mode for name and email
* @param changeSubjectMode mode for change subject
* @param project jenkins job
* @param commitMessageMode mode for commit message
* @param commentTextMode mode for comment text
*/
private static void setOrCreateParametersForChangeBasedEvent(ChangeBasedEvent event,
List<ParameterValue> parameters,
boolean escapeQuotes,
ParameterMode nameAndEmailParameterMode,
ParameterMode changeSubjectMode,
Job project,
ParameterMode commitMessageMode,
ParameterMode commentTextMode) {
GERRIT_CHANGE_WIP_STATE.setOrCreateStringParameterValue(
parameters, String.valueOf(event.getChange().isWip()), escapeQuotes);
GERRIT_CHANGE_PRIVATE_STATE.setOrCreateStringParameterValue(
Expand All @@ -420,6 +493,8 @@ public static void setOrCreateParameters(GerritTriggeredEvent gerritEvent, Job p
parameters, event.getChange().getNumber(), escapeQuotes);
GERRIT_CHANGE_ID.setOrCreateStringParameterValue(
parameters, event.getChange().getId(), escapeQuotes);
GERRIT_HASHTAGS.setOrCreateStringParameterValue(
parameters, String.join(",", event.getChange().getHashtags()), escapeQuotes);
String pNumber = null;
if (null != event.getPatchSet()) {
pNumber = event.getPatchSet().getNumber();
Expand Down Expand Up @@ -498,40 +573,15 @@ public static void setOrCreateParameters(GerritTriggeredEvent gerritEvent, Job p
parameters, comment, ParameterMode.PlainMode.TEXT, escapeQuotes);
}
GERRIT_EVENT_UPDATED_APPROVALS.setOrCreateStringParameterValue(parameters,
getUpdatedApprovals((CommentAdded)event), false);
getUpdatedApprovals((CommentAdded)event), false);
}
} else if (gerritEvent instanceof RefUpdated) {
RefUpdated event = (RefUpdated)gerritEvent;
GERRIT_REFNAME.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getRefName(), escapeQuotes);
GERRIT_PROJECT.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getProject(), escapeQuotes);
GERRIT_OLDREV.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getOldRev(), escapeQuotes);
GERRIT_NEWREV.setOrCreateStringParameterValue(
parameters, event.getRefUpdate().getNewRev(), escapeQuotes);
}
Account account = gerritEvent.getAccount();
if (account != null) {
nameAndEmailParameterMode.setOrCreateParameterValue(GERRIT_EVENT_ACCOUNT, parameters,
getNameAndEmail(account), ParameterMode.PlainMode.STRING, escapeQuotes);
GERRIT_EVENT_ACCOUNT_NAME.setOrCreateStringParameterValue(
parameters, getName(account), escapeQuotes);
GERRIT_EVENT_ACCOUNT_EMAIL.setOrCreateStringParameterValue(
parameters, getEmail(account), escapeQuotes);
}
Provider provider = gerritEvent.getProvider();
if (provider != null) {
GERRIT_NAME.setOrCreateStringParameterValue(
parameters, provider.getName(), escapeQuotes);
GERRIT_HOST.setOrCreateStringParameterValue(
parameters, provider.getHost(), escapeQuotes);
GERRIT_PORT.setOrCreateStringParameterValue(
parameters, provider.getPort(), escapeQuotes);
GERRIT_SCHEME.setOrCreateStringParameterValue(
parameters, provider.getScheme(), escapeQuotes);
GERRIT_VERSION.setOrCreateStringParameterValue(
parameters, provider.getVersion(), escapeQuotes);
if (event instanceof HashtagsChanged) {
String addedHashtags = ((HashtagsChanged)event).getAddedHashtags().stream()
.collect(Collectors.joining(","));
String removedHashtags = ((HashtagsChanged)event).getRemovedHashtags().stream()
.collect(Collectors.joining(","));
GERRIT_ADDED_HASHTAGS.setOrCreateStringParameterValue(parameters, addedHashtags, escapeQuotes);
GERRIT_REMOVED_HASHTAGS.setOrCreateStringParameterValue(parameters, removedHashtags, escapeQuotes);
}
}

Expand Down
Expand Up @@ -42,10 +42,12 @@
import jenkins.model.Jenkins;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;

import com.sonyericsson.hudson.plugins.gerrit.trigger.GerritServer;
import com.sonyericsson.hudson.plugins.gerrit.trigger.PluginImpl;
import com.sonymobile.tools.gerrit.gerritevents.dto.attr.Change;

/**
* Base settings for one matcher rule of a Gerrit project.
Expand All @@ -64,6 +66,7 @@ public class GerritProject implements Describable<GerritProject> {
private List<Branch> branches;
private List<FilePath> filePaths;
private List<Topic> topics;
private List<Hashtag> hashtags;
private List<FilePath> forbiddenFilePaths;
private boolean disableStrictForbiddenFileVerification;

Expand Down Expand Up @@ -199,6 +202,23 @@ public void setTopics(List<Topic> topics) {
this.topics = topics;
}

/**
*
* @return the hashtags-rules
*/
public List<Hashtag> getHashtags() {
return hashtags;
}

/**
* The list of the hashtags-rules.
* @param hashtags the hashtags-rules
*/
@DataBoundSetter
public void setHashtags(List<Hashtag> hashtags) {
this.hashtags = hashtags;
}

/**
* The list of the forbidden file-path rules.
* @return the forbidden file-path rules.
Expand All @@ -223,6 +243,7 @@ public void setForbiddenFilePaths(List<FilePath> forbiddenFilePaths) {
* @param files a closure which returns the list of files in the change.
* @return true is the rules match.
*/
@Deprecated
public boolean isInteresting(String project, String branch, String topic, Supplier<List<String>> files) {
if (isInteresting(project, branch, topic)) {
return isInterestingFile(files.get());
Expand All @@ -237,11 +258,38 @@ public boolean isInteresting(String project, String branch, String topic, Suppli
* @param topic the topic.
* @return true is the rules match.
*/
@Deprecated
public boolean isInteresting(String project, String branch, String topic) {
if (compareType.matches(pattern, project)) {
Change change = new Change();
change.setProject(project);
change.setBranch(branch);
change.setTopic(topic);
return isInteresting(change);
}

/**
* Compares the project, branch and files to see if the rules specified is a match.
* @param change gerrit change info.
* @param files a closure which returns the list of files in the change.
* @return true is the rules match.
*/
public boolean isInteresting(Change change, Supplier<List<String>> files) {
if (isInteresting(change)) {
return isInterestingFile(files.get());
}
return false;
}

/**
* Compares the project and branch to see if the rules specified is a match.
* @param change gerrit change info.
* @return true is the rules match.
*/
public boolean isInteresting(Change change) {
if (compareType.matches(pattern, change.getProject())) {
for (Branch b : branches) {
if (b.isInteresting(branch)) {
return isInterestingTopic(topic);
if (b.isInteresting(change.getBranch())) {
return isInterestingTopic(change.getTopic()) && isInterestingHashtags(change.getHashtags());
}
}
}
Expand All @@ -266,6 +314,19 @@ private boolean isInterestingTopic(String topic) {
return true;
}

/**
* Compare tags to see if the rules specified is a match.
*
* @param tags the tags in change.
* @return true if the rules match or no rules.
*/
private boolean isInterestingHashtags(List<String> tags) {
if (this.hashtags != null && this.hashtags.size() > 0) {
return this.hashtags.stream().anyMatch(h-> h.isInteresting(tags));
}
return true;
}

/**
* Compare files to see if the rules specified is a match.
*
Expand Down

0 comments on commit 294dbe6

Please sign in to comment.