macros) {
this.macros = Util.fixNull(macros);
@@ -201,8 +213,8 @@ public FormValidation doCheckUrl(@QueryParameter String value) {
return FormUtils.formValidateUrl(value);
}
- public FormValidation doCheckGlobalUrl(@QueryParameter String value) {
- if(StringUtils.isNotBlank(value)) {
+ public FormValidation doCheckGlobalUrl(@QueryParameter String value) {
+ if (StringUtils.isNotBlank(value)) {
return FormUtils.formValidateUrl(value);
} else {
return FormValidation.ok();
diff --git a/src/main/java/jenkins/plugins/office365connector/model/Card.java b/src/main/java/jenkins/plugins/office365connector/model/Card.java
index 8cfd9ab1..81fd1999 100644
--- a/src/main/java/jenkins/plugins/office365connector/model/Card.java
+++ b/src/main/java/jenkins/plugins/office365connector/model/Card.java
@@ -1,61 +1,18 @@
-/**
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package jenkins.plugins.office365connector.model;
-import java.util.Arrays;
import java.util.List;
-/**
- * @author srhebbar
- */
-public class Card {
-
- private String summary;
- private String themeColor = "3479BF";
-
- // even plugin needs only single 'section' connector API expects arrays
- private List sections;
-
- private List potentialAction;
-
- public Card(String summary, Section section) {
- this.summary = summary;
- this.sections = Arrays.asList(section);
- }
+public interface Card {
- public String getSummary() {
- return summary;
- }
+ public Object toPaylod();
- public List getSections() {
- return this.sections;
- }
+ void setAction(List actions);
- public void setThemeColor(String themeColor) {
- this.themeColor = themeColor;
- }
+ void setThemeColor(String cardThemeColor);
- public String getThemeColor() {
- return themeColor;
- }
+ String getSummary();
- public void setPotentialAction(List potentialActions) {
- this.potentialAction = potentialActions;
- }
+ List getSections();
- public List getPotentialAction() {
- return this.potentialAction;
- }
+ String getThemeColor();
}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/CardAction.java b/src/main/java/jenkins/plugins/office365connector/model/CardAction.java
new file mode 100644
index 00000000..5b909718
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/CardAction.java
@@ -0,0 +1,12 @@
+package jenkins.plugins.office365connector.model;
+
+import java.util.List;
+
+public interface CardAction {
+
+ void setName(String name);
+
+ void setTargets(List targets);
+
+ String getName();
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCard.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCard.java
new file mode 100644
index 00000000..34107e59
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCard.java
@@ -0,0 +1,104 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import hudson.model.Result;
+import jenkins.plugins.office365connector.model.Card;
+import jenkins.plugins.office365connector.model.CardAction;
+import jenkins.plugins.office365connector.model.Section;
+
+public class AdaptiveCard implements Card {
+
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ private String type = "AdaptiveCard";
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ @SerializedName("$schema")
+ private final String schema = "http://adaptivecards.io/schemas/adaptive-card.json";
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ private final String version = "1.4";
+ private final MsTeams msTeams = new MsTeams();
+ private final List body;
+ private List actions;
+
+ public AdaptiveCard(final String summary, final Section section, Result result) {
+ this.body = new ArrayList<>();
+ this.body.add(new TextBlock(summary, "large", "bolder", color(result)));
+ if (section != null) {
+ this.body.add(new ColumnSet(List.of(new Column(List.of(
+ new TextBlock(section.getActivityTitle(), "default", "bolder"),
+ new TextBlock(section.getActivitySubtitle())
+ )))));
+ if (!section.getFacts().isEmpty()) {
+ this.body.add(new FactSet(section.getFacts()));
+ }
+ }
+ }
+
+ private String color(final Result result) {
+ if (result.equals(Result.SUCCESS)) {
+ return "good";
+ } else if (result.equals(Result.UNSTABLE)) {
+ return "warning";
+ } else if (result.equals(Result.FAILURE)) {
+ return "attention";
+ }
+ return "default";
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getSchema() {
+ return schema;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public MsTeams getMsTeams() {
+ return msTeams;
+ }
+
+ public List getBody() {
+ return body;
+ }
+
+ public List getActions() {
+ return actions;
+ }
+
+ @Override
+ public Object toPaylod() {
+ return new Payload(this);
+ }
+
+ @Override
+ public void setAction(final List actions) {
+ this.actions = actions;
+ }
+
+ @Override
+ public void setThemeColor(final String cardThemeColor) {
+ // intentionally empty, unused with AdaptiveCard format
+ }
+
+ @Override
+ public String getSummary() {
+ return null;
+ }
+
+ @Override
+ public List getSections() {
+ return List.of();
+ }
+
+ @Override
+ public String getThemeColor() {
+ return null;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardAction.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardAction.java
new file mode 100644
index 00000000..01651ce6
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardAction.java
@@ -0,0 +1,58 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+import java.util.List;
+
+import jenkins.plugins.office365connector.model.CardAction;
+
+public class AdaptiveCardAction implements CardAction {
+
+ private String type = "Action.OpenUrl";
+
+ private String title;
+
+ private String url;
+
+ public AdaptiveCardAction(String title, String url) {
+ this.title = title;
+ this.url = url;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(final String title) {
+ this.title = title;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(final String url) {
+ this.url = url;
+ }
+
+ @Override
+ public void setName(final String name) {
+ setTitle(name);
+ }
+
+ @Override
+ public void setTargets(final List targets) {
+ targets.stream().findFirst().ifPresent(this::setUrl);
+ }
+
+ @Override
+ public String getName() {
+ return getTitle();
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardElement.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardElement.java
new file mode 100644
index 00000000..b95c0d92
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardElement.java
@@ -0,0 +1,5 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+public interface AdaptiveCardElement {
+ String getType();
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardFact.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardFact.java
new file mode 100644
index 00000000..27456fb5
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/AdaptiveCardFact.java
@@ -0,0 +1,19 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+public class AdaptiveCardFact {
+ private final String title;
+ private final String value;
+
+ public AdaptiveCardFact(final String title, final String value) {
+ this.title = title;
+ this.value = value;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Attachment.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Attachment.java
new file mode 100644
index 00000000..f44d655e
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Attachment.java
@@ -0,0 +1,23 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+public class Attachment {
+
+ private String contentType = "application/vnd.microsoft.card.adaptive";
+ private final AdaptiveCard content;
+
+ public Attachment(final AdaptiveCard content) {
+ this.content = content;
+ }
+
+ public void setContentType(final String contentType) {
+ this.contentType = contentType;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public AdaptiveCard getContent() {
+ return content;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Column.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Column.java
new file mode 100644
index 00000000..73dfa0b0
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Column.java
@@ -0,0 +1,25 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+import java.util.List;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+public class Column implements AdaptiveCardElement {
+
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ private final String type = "Column";
+ private final List items;
+
+ public Column(final List items) {
+ this.items = items;
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ public List getItems() {
+ return items;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/ColumnSet.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/ColumnSet.java
new file mode 100644
index 00000000..bf511160
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/ColumnSet.java
@@ -0,0 +1,31 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+import java.util.List;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+public class ColumnSet implements AdaptiveCardElement {
+
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ private final String type = "ColumnSet";
+ private final List columns;
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ private final String witdth = "stretch";
+
+ public ColumnSet(final List items) {
+ this.columns = items;
+ }
+
+ public String getWitdth() {
+ return witdth;
+ }
+
+ public List getColumns() {
+ return columns;
+ }
+
+ @Override
+ public String getType() {
+ return "";
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/FactSet.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/FactSet.java
new file mode 100644
index 00000000..f01a45c8
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/FactSet.java
@@ -0,0 +1,27 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import jenkins.plugins.office365connector.model.Fact;
+
+public class FactSet implements AdaptiveCardElement {
+
+ private final List facts;
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ private final String type = "FactSet";
+
+ public FactSet(List facts) {
+ this.facts = facts.stream().map(f -> new AdaptiveCardFact(f.getName(),f.getValue())).collect(Collectors.toList());
+ }
+
+ public List getFacts() {
+ return facts;
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/MsTeams.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/MsTeams.java
new file mode 100644
index 00000000..38fd5585
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/MsTeams.java
@@ -0,0 +1,10 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+public class MsTeams {
+
+ private String width = "Full";
+
+ public String getWidth() {
+ return width;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Payload.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Payload.java
new file mode 100644
index 00000000..6bb076d0
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/Payload.java
@@ -0,0 +1,22 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Payload {
+
+ private String type = "message";
+ private final List attachments = new ArrayList<>();
+
+ public Payload(AdaptiveCard adaptiveCard) {
+ attachments.add(new Attachment(adaptiveCard));
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public List getAttachments() {
+ return attachments;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/TextBlock.java b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/TextBlock.java
new file mode 100644
index 00000000..85205fcb
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/adaptivecard/TextBlock.java
@@ -0,0 +1,54 @@
+package jenkins.plugins.office365connector.model.adaptivecard;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+public class TextBlock implements AdaptiveCardElement {
+
+ private String text;
+ private String weight;
+ private String size;
+ private String color;
+ @SuppressFBWarnings(value = "SS_SHOULD_BE_STATIC")
+ private String type = "TextBlock";
+ private boolean wrap;
+
+ public TextBlock(final String text) {
+ this(text,"default", "default");
+ }
+
+ public TextBlock(final String text, final String size, final String weight) {
+ this(text, size,weight,"default");
+ }
+
+ public TextBlock(final String text, final String size, final String weight, final String color) {
+ this.text = text;
+ this.wrap = true;
+ this.size = size;
+ this.weight = weight;
+ this.color = color;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public boolean isWrap() {
+ return wrap;
+ }
+
+ public String getWeight() {
+ return weight;
+ }
+
+ public String getSize() {
+ return size;
+ }
+
+ public String getColor() {
+ return color;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/messagecard/MessageCard.java b/src/main/java/jenkins/plugins/office365connector/model/messagecard/MessageCard.java
new file mode 100644
index 00000000..50ae112f
--- /dev/null
+++ b/src/main/java/jenkins/plugins/office365connector/model/messagecard/MessageCard.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jenkins.plugins.office365connector.model.messagecard;
+
+import java.util.Arrays;
+import java.util.List;
+
+import jenkins.plugins.office365connector.model.CardAction;
+import jenkins.plugins.office365connector.model.Card;
+import jenkins.plugins.office365connector.model.Section;
+
+/**
+ * @author srhebbar
+ */
+public class MessageCard implements Card {
+
+ private String summary;
+ private String themeColor = "3479BF";
+
+ // even plugin needs only single 'section' connector API expects arrays
+ private List sections;
+
+ private List potentialAction;
+
+ public MessageCard(String summary, Section section) {
+ this.summary = summary;
+ this.sections = Arrays.asList(section);
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public List getSections() {
+ return this.sections;
+ }
+
+ public void setThemeColor(String themeColor) {
+ this.themeColor = themeColor;
+ }
+
+ public String getThemeColor() {
+ return themeColor;
+ }
+
+ public void setAction(List potentialActions) {
+ this.potentialAction = potentialActions;
+ }
+
+ public List getAction() {
+ return this.potentialAction;
+ }
+
+ @Override
+ public Object toPaylod() {
+ return this;
+ }
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/model/PotentialAction.java b/src/main/java/jenkins/plugins/office365connector/model/messagecard/PotentialAction.java
similarity index 84%
rename from src/main/java/jenkins/plugins/office365connector/model/PotentialAction.java
rename to src/main/java/jenkins/plugins/office365connector/model/messagecard/PotentialAction.java
index e6435efc..8b4b0842 100644
--- a/src/main/java/jenkins/plugins/office365connector/model/PotentialAction.java
+++ b/src/main/java/jenkins/plugins/office365connector/model/messagecard/PotentialAction.java
@@ -10,18 +10,19 @@
* limitations under the License.
*/
-package jenkins.plugins.office365connector.model;
+package jenkins.plugins.office365connector.model.messagecard;
import java.util.Collections;
import java.util.List;
import com.google.gson.annotations.SerializedName;
import hudson.Util;
+import jenkins.plugins.office365connector.model.CardAction;
/**
* @author srhebbar
*/
-public class PotentialAction {
+public class PotentialAction implements CardAction {
@SerializedName("@context")
private String context = "http://schema.org";
@@ -42,10 +43,12 @@ public PotentialAction(String name, List url) {
this.target = Util.fixNull(url);
}
+ @Override
public String getName() {
return name;
}
+ @Override
public void setName(String name) {
this.name = name;
}
@@ -54,8 +57,9 @@ public List getTarget() {
return target;
}
- public void setTarget(List target) {
- this.target = target;
+ @Override
+ public void setTargets(List targets) {
+ this.target = targets;
}
public String getContext() {
diff --git a/src/main/java/jenkins/plugins/office365connector/workflow/Execution.java b/src/main/java/jenkins/plugins/office365connector/workflow/Execution.java
index f533ffc3..b80cce4e 100644
--- a/src/main/java/jenkins/plugins/office365connector/workflow/Execution.java
+++ b/src/main/java/jenkins/plugins/office365connector/workflow/Execution.java
@@ -21,7 +21,7 @@ public class Execution extends SynchronousNonBlockingStepExecution {
public Execution(Office365ConnectorSendStep step, StepContext context) {
super(context);
stepParameters = new StepParameters(
- step.getMessage(), step.getWebhookUrl(), step.getStatus(), step.getFactDefinitions(), step.getColor());
+ step.getMessage(), step.getWebhookUrl(), step.getStatus(), step.getFactDefinitions(), step.getColor(), step.isAdaptiveCards());
}
@Override
@@ -33,4 +33,4 @@ protected Void run() throws IOException, InterruptedException {
notifier.sendBuildStepNotification(stepParameters);
return null;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep.java b/src/main/java/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep.java
index 85f79dcd..8f31cb7c 100644
--- a/src/main/java/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep.java
+++ b/src/main/java/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep.java
@@ -31,6 +31,7 @@ public class Office365ConnectorSendStep extends Step {
private String status;
private List factDefinitions;
private String color;
+ private boolean adaptiveCards;
@DataBoundConstructor
public Office365ConnectorSendStep(String webhookUrl) {
@@ -83,6 +84,15 @@ public StepExecution start(StepContext context) {
return new Execution(this, context);
}
+ public boolean isAdaptiveCards() {
+ return adaptiveCards;
+ }
+
+ @DataBoundSetter
+ public void setAdaptiveCards(boolean adaptiveCards) {
+ this.adaptiveCards = adaptiveCards;
+ }
+
@Extension
@Symbol("office365ConnectorSend")
public static class DescriptorImpl extends StepDescriptor {
diff --git a/src/main/java/jenkins/plugins/office365connector/workflow/StepParameters.java b/src/main/java/jenkins/plugins/office365connector/workflow/StepParameters.java
index a6b68c45..bba8e190 100644
--- a/src/main/java/jenkins/plugins/office365connector/workflow/StepParameters.java
+++ b/src/main/java/jenkins/plugins/office365connector/workflow/StepParameters.java
@@ -28,14 +28,16 @@ public class StepParameters {
private final String webhookUrl;
private final String status;
private final String color;
- private List factDefinitions;
+ private final boolean adaptiveCards;
+ private final List factDefinitions;
- public StepParameters(String message, String webhookUrl, String status, List factDefinitions, String color) {
+ public StepParameters(String message, String webhookUrl, String status, List factDefinitions, String color, boolean adaptiveCards) {
this.message = message;
this.webhookUrl = webhookUrl;
this.status = status;
this.factDefinitions = factDefinitions;
this.color = color;
+ this.adaptiveCards = adaptiveCards;
}
public String getMessage() {
@@ -58,4 +60,7 @@ public String getColor() {
return color;
}
+ public boolean isAdaptiveCards() {
+ return adaptiveCards;
+ }
}
diff --git a/src/main/resources/jenkins/plugins/office365connector/Webhook/config.jelly b/src/main/resources/jenkins/plugins/office365connector/Webhook/config.jelly
index 6917e9a3..e6e8ae1f 100644
--- a/src/main/resources/jenkins/plugins/office365connector/Webhook/config.jelly
+++ b/src/main/resources/jenkins/plugins/office365connector/Webhook/config.jelly
@@ -7,6 +7,9 @@
+
+
+
diff --git a/src/main/resources/jenkins/plugins/office365connector/Webhook/help-adaptiveCards.html b/src/main/resources/jenkins/plugins/office365connector/Webhook/help-adaptiveCards.html
new file mode 100644
index 00000000..4b6e90fe
--- /dev/null
+++ b/src/main/resources/jenkins/plugins/office365connector/Webhook/help-adaptiveCards.html
@@ -0,0 +1 @@
+Use AdaptiveCards format.
diff --git a/src/main/resources/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep/config.jelly b/src/main/resources/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep/config.jelly
index 00c6b7c8..0e8fc6b0 100644
--- a/src/main/resources/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep/config.jelly
+++ b/src/main/resources/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep/config.jelly
@@ -13,4 +13,7 @@
+
+
+
diff --git a/src/main/resources/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep/help-adaptiveCards.html b/src/main/resources/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep/help-adaptiveCards.html
new file mode 100644
index 00000000..4b6e90fe
--- /dev/null
+++ b/src/main/resources/jenkins/plugins/office365connector/workflow/Office365ConnectorSendStep/help-adaptiveCards.html
@@ -0,0 +1 @@
+Use AdaptiveCards format.
diff --git a/src/test/java/jenkins/plugins/office365connector/ActionableBuilderTest.java b/src/test/java/jenkins/plugins/office365connector/ActionableBuilderTest.java
index af3f495b..aee67884 100644
--- a/src/test/java/jenkins/plugins/office365connector/ActionableBuilderTest.java
+++ b/src/test/java/jenkins/plugins/office365connector/ActionableBuilderTest.java
@@ -11,7 +11,7 @@
import hudson.model.AbstractProject;
import hudson.model.TaskListener;
import jenkins.plugins.office365connector.helpers.SCMHeadBuilder;
-import jenkins.plugins.office365connector.model.PotentialAction;
+import jenkins.plugins.office365connector.model.CardAction;
import jenkins.scm.api.SCMHead;
import jenkins.scm.api.metadata.ContributorMetadataAction;
import jenkins.scm.api.metadata.ObjectMetadataAction;
@@ -43,7 +43,7 @@ public void setUp() {
taskListener = mock(TaskListener.class);
factsBuilder = new FactsBuilder(run, taskListener);
- actionableBuilder = new ActionableBuilder(run, factsBuilder);
+ actionableBuilder = new ActionableBuilder(run, factsBuilder, false);
DisplayURLProvider displayURLProvider = mock(DisplayURLProvider.class);
when(displayURLProvider.getRunURL(run)).thenReturn(JOB_URL);
@@ -64,11 +64,11 @@ public void buildActionable_OnEmptyAction_ReturnsEmptyList() {
// from @Before
// when
- List potentialActions = actionableBuilder.buildActionable();
+ List potentialActions = actionableBuilder.buildActionable();
// then
assertThat(potentialActions).hasSize(1);
- PotentialAction potentialAction = potentialActions.get(0);
+ CardAction potentialAction = potentialActions.get(0);
assertThat(potentialAction.getName()).isEqualTo("View Build");
}
@@ -133,7 +133,7 @@ public void pullRequestActionable_OnContributorMetadataAction_AddsFact() throws
// then
assertThat(factsBuilder.collect()).hasSize(1);
- List potentialActions = FieldReflection.getFieldValue(actionableBuilder.getClass().getDeclaredField("potentialActions"), actionableBuilder);
+ List potentialActions = FieldReflection.getFieldValue(actionableBuilder.getClass().getDeclaredField("potentialActions"), actionableBuilder);
assertThat(potentialActions).hasSize(1);
}
@@ -164,7 +164,7 @@ public void pullRequestActionable_OnObjectMetadataAction_DoesNotAddFact() throws
// then
assertThat(factsBuilder.collect()).hasSize(1);
- List potentialActions = FieldReflection.getFieldValue(actionableBuilder.getClass().getDeclaredField("potentialActions"), actionableBuilder);
+ List potentialActions = FieldReflection.getFieldValue(actionableBuilder.getClass().getDeclaredField("potentialActions"), actionableBuilder);
assertThat(potentialActions).isEmpty();
}
diff --git a/src/test/java/jenkins/plugins/office365connector/CardBuilderTest.java b/src/test/java/jenkins/plugins/office365connector/CardBuilderMessageCardTest.java
similarity index 98%
rename from src/test/java/jenkins/plugins/office365connector/CardBuilderTest.java
rename to src/test/java/jenkins/plugins/office365connector/CardBuilderMessageCardTest.java
index 4ec31837..add00734 100644
--- a/src/test/java/jenkins/plugins/office365connector/CardBuilderTest.java
+++ b/src/test/java/jenkins/plugins/office365connector/CardBuilderMessageCardTest.java
@@ -21,7 +21,7 @@
import org.junit.Before;
import org.junit.Test;
-public class CardBuilderTest extends AbstractTest {
+public class CardBuilderMessageCardTest extends AbstractTest {
private static final String JOB_DISPLAY_NAME = "myJobDisplayName";
private static final int BUILD_NUMBER = 7;
@@ -44,7 +44,7 @@ public void setUp() throws Exception {
mockDisplayURLProvider(JOB_DISPLAY_NAME, BUILD_NUMBER);
TaskListener taskListener = mock(TaskListener.class);
- cardBuilder = new CardBuilder(run, taskListener);
+ cardBuilder = new CardBuilder(run, taskListener, false);
}
@@ -421,7 +421,7 @@ public void createBuildMessageCard_ReturnsCard() {
String status = Result.SUCCESS.toString();
String color = "blue";
- StepParameters stepParameters = new StepParameters(message, webhookUrl, status, Collections.emptyList(), color);
+ StepParameters stepParameters = new StepParameters(message, webhookUrl, status, Collections.emptyList(), color, false);
// then
Card card = cardBuilder.createBuildMessageCard(stepParameters);
@@ -443,7 +443,7 @@ public void createBuildMessageCard_OnMissingStatus_ReturnsCard() {
String status = null;
String color = "blue";
- StepParameters stepParameters = new StepParameters(message, webhookUrl, status, Collections.emptyList(), color);
+ StepParameters stepParameters = new StepParameters(message, webhookUrl, status, Collections.emptyList(), color, false);
// then
Card card = cardBuilder.createBuildMessageCard(stepParameters);
@@ -464,7 +464,7 @@ public void createBuildMessageCard_OnMissingColor_ReturnsCard() {
String status = Result.ABORTED.toString();
String color = null;
- StepParameters stepParameters = new StepParameters(message, webhookUrl, status, Collections.emptyList(), color);
+ StepParameters stepParameters = new StepParameters(message, webhookUrl, status, Collections.emptyList(), color, false);
// then
Card card = cardBuilder.createBuildMessageCard(stepParameters);
@@ -494,7 +494,7 @@ public void getEscapedDisplayName_OnNameWithSpecialCharacters_EscapesSpecialChar
when(run.getParent()).thenReturn(job);
TaskListener taskListener = mock(TaskListener.class);
- cardBuilder = new CardBuilder(run, taskListener);
+ cardBuilder = new CardBuilder(run, taskListener, false);
// when
String displayName = MethodReflection.invokeWithCheckedThrows(cardBuilder.getClass(), cardBuilder, "getEscapedDisplayName", new Class[]{});
diff --git a/src/test/java/jenkins/plugins/office365connector/helpers/WebhookBuilder.java b/src/test/java/jenkins/plugins/office365connector/helpers/WebhookBuilder.java
index 07662e10..1702d225 100644
--- a/src/test/java/jenkins/plugins/office365connector/helpers/WebhookBuilder.java
+++ b/src/test/java/jenkins/plugins/office365connector/helpers/WebhookBuilder.java
@@ -12,11 +12,20 @@
*/
public class WebhookBuilder {
+ public static List sampleWebhookWithAllStatusesAdaptiveCard() {
+ Webhook webhook = new Webhook(ClassicDisplayURLProviderBuilder.LOCALHOST_URL_TEMPLATE);
+
+ enableAllStatuses(webhook);
+ webhook.setAdaptiveCards(true);
+
+ return List.of(webhook);
+ }
+
public static List sampleWebhookWithAllStatuses() {
Webhook webhook = new Webhook(ClassicDisplayURLProviderBuilder.LOCALHOST_URL_TEMPLATE);
enableAllStatuses(webhook);
- return Arrays.asList(webhook);
+ return List.of(webhook);
}
public static List sampleMultiplyWebhookWithAllStatuses() {
@@ -41,7 +50,7 @@ private static Webhook createWebhook(String template, String value) {
enableAllStatuses(webhook);
- webhook.setMacros(Arrays.asList(new Macro(template, value)));
+ webhook.setMacros(List.of(new Macro(template, value)));
return webhook;
}
diff --git a/src/test/java/jenkins/plugins/office365connector/model/CardTest.java b/src/test/java/jenkins/plugins/office365connector/model/messagecard/MessageCardTest.java
similarity index 52%
rename from src/test/java/jenkins/plugins/office365connector/model/CardTest.java
rename to src/test/java/jenkins/plugins/office365connector/model/messagecard/MessageCardTest.java
index a11440b2..d7467cc8 100644
--- a/src/test/java/jenkins/plugins/office365connector/model/CardTest.java
+++ b/src/test/java/jenkins/plugins/office365connector/model/messagecard/MessageCardTest.java
@@ -1,15 +1,16 @@
-package jenkins.plugins.office365connector.model;
+package jenkins.plugins.office365connector.model.messagecard;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Collections;
+import jenkins.plugins.office365connector.model.Section;
import org.junit.Test;
/**
* @author Damian Szczepanik (damianszczepanik@github)
*/
-public class CardTest {
+public class MessageCardTest {
@Test
public void getSummary_ReturnsSummary() {
@@ -18,10 +19,10 @@ public void getSummary_ReturnsSummary() {
String summary = "mySummary";
// when
- Card card = new Card(summary, null);
+ MessageCard messageCard = new MessageCard(summary, null);
// then
- assertThat(card.getSummary()).isEqualTo(summary);
+ assertThat(messageCard.getSummary()).isEqualTo(summary);
}
@Test
@@ -31,10 +32,10 @@ public void getSections_ReturnsSection() {
Section section = new Section("myTitle", null, null);
// when
- Card card = new Card(null, section);
+ MessageCard messageCard = new MessageCard(null, section);
// then
- assertThat(card.getSections()).hasSize(1).containsOnly(section);
+ assertThat(messageCard.getSections()).hasSize(1).containsOnly(section);
}
@Test
@@ -42,13 +43,13 @@ public void getThemeColor_ReturnsThemeColor() {
// given
String themeColor = "red";
- Card card = new Card("mySummary", null);
+ MessageCard messageCard = new MessageCard("mySummary", null);
// when
- card.setThemeColor(themeColor);
+ messageCard.setThemeColor(themeColor);
// then
- assertThat(card.getThemeColor()).isEqualTo(themeColor);
+ assertThat(messageCard.getThemeColor()).isEqualTo(themeColor);
}
@Test
@@ -56,12 +57,12 @@ public void getPotentialAction_ReturnsPotentialActions() {
// given
PotentialAction action = new PotentialAction("myName", Collections.singletonList("someUrl"));
- Card card = new Card("mySummary", null);
+ MessageCard messageCard = new MessageCard("mySummary", null);
// when
- card.setPotentialAction(Collections.singletonList(action));
+ messageCard.setAction(Collections.singletonList(action));
// then
- assertThat(card.getPotentialAction()).hasSize(1).containsOnly(action);
+ assertThat(messageCard.getAction()).hasSize(1).containsOnly(action);
}
}
diff --git a/src/test/java/jenkins/plugins/office365connector/model/PotentialActionTest.java b/src/test/java/jenkins/plugins/office365connector/model/messagecard/PotentialActionTest.java
similarity index 94%
rename from src/test/java/jenkins/plugins/office365connector/model/PotentialActionTest.java
rename to src/test/java/jenkins/plugins/office365connector/model/messagecard/PotentialActionTest.java
index 2b7427bb..c656807b 100644
--- a/src/test/java/jenkins/plugins/office365connector/model/PotentialActionTest.java
+++ b/src/test/java/jenkins/plugins/office365connector/model/messagecard/PotentialActionTest.java
@@ -1,4 +1,4 @@
-package jenkins.plugins.office365connector.model;
+package jenkins.plugins.office365connector.model.messagecard;
import static org.assertj.core.api.Assertions.assertThat;
@@ -48,7 +48,7 @@ public void getTarget_ReturnsTarget() {
PotentialAction potentialAction = new PotentialAction("name", "url");
// then
- potentialAction.setTarget(target);
+ potentialAction.setTargets(target);
// then
assertThat(potentialAction.getTarget()).isEqualTo(target);
diff --git a/src/test/java/jenkins/plugins/office365connector/workflow/AdaptiveCardIT.java b/src/test/java/jenkins/plugins/office365connector/workflow/AdaptiveCardIT.java
new file mode 100644
index 00000000..ae56b157
--- /dev/null
+++ b/src/test/java/jenkins/plugins/office365connector/workflow/AdaptiveCardIT.java
@@ -0,0 +1,117 @@
+package jenkins.plugins.office365connector.workflow;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.*;
+
+import java.util.Collections;
+import java.util.List;
+
+import hudson.model.AbstractBuild;
+import hudson.model.Job;
+import hudson.model.Result;
+import hudson.scm.ChangeLogSet;
+import jenkins.model.Jenkins;
+import jenkins.plugins.office365connector.FileUtils;
+import jenkins.plugins.office365connector.Office365ConnectorWebhookNotifier;
+import jenkins.plugins.office365connector.Webhook;
+import jenkins.plugins.office365connector.helpers.AffectedFileBuilder;
+import jenkins.plugins.office365connector.helpers.ClassicDisplayURLProviderBuilder;
+import jenkins.plugins.office365connector.helpers.WebhookBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockedStatic;
+
+/**
+ * @author Markus Helbig (markush81@github)
+ */
+public class AdaptiveCardIT extends AbstractTest {
+
+ private static final String JOB_NAME = "myFirst_Job_";
+ private static final String CAUSE_DESCRIPTION = "Started by John";
+ private static final int BUILD_NUMBER = 167;
+ private static final String DEVELOPER = "Mike";
+
+ private MockedStatic staticJenkins;
+
+ @Before
+ public void setUp() {
+ staticJenkins = mockStatic(Jenkins.class);
+ Jenkins jenkins = mock(Jenkins.class);
+ mockListener();
+
+ run = mockRun();
+ mockCause(CAUSE_DESCRIPTION);
+
+ mockDisplayURLProvider(JOB_NAME, BUILD_NUMBER);
+ mockEnvironment();
+ mockHttpWorker();
+ mockGetChangeSets();
+
+ staticJenkins.when(Jenkins::get).thenReturn(jenkins);
+
+ Webhook.DescriptorImpl mockDescriptor = mock(Webhook.DescriptorImpl.class);
+ when(mockDescriptor.getName()).thenReturn("testName");
+
+ when(jenkins.getDescriptorOrDie(Webhook.class)).thenReturn(mockDescriptor);
+ }
+
+ @After
+ public void tearDown() {
+ staticJenkins.close();
+ }
+
+ private AbstractBuild mockRun() {
+ AbstractBuild run = mock(AbstractBuild.class);
+
+ when(run.getNumber()).thenReturn(BUILD_NUMBER);
+
+ Job job = mockJob(JOB_NAME);
+ when(run.getParent()).thenReturn(job);
+
+ mockProperty(job, WebhookBuilder.sampleWebhookWithAllStatusesAdaptiveCard());
+
+ return run;
+ }
+
+ private void mockGetChangeSets() {
+ List files = new AffectedFileBuilder().singleChangeLog(run, DEVELOPER);
+ when(run.getChangeSets()).thenReturn(files);
+ }
+
+
+ @Test
+ public void testAdaptiveCardStarted() {
+
+ // given
+ when(run.getResult()).thenReturn(Result.SUCCESS);
+ Office365ConnectorWebhookNotifier notifier = new Office365ConnectorWebhookNotifier(run, mockListener());
+
+ // when
+ notifier.sendBuildCompletedNotification();
+
+ // then
+ assertHasSameContent(workerData.get(0), FileUtils.getContentFile("adaptivecard-success.json"));
+ assertEquals(1, workerConstruction.constructed().size());
+ }
+
+ @Test
+ public void testAdaptiveCardStep() {
+
+ // given
+ StepParameters stepParameters = new StepParameters(
+ "helloMessage", ClassicDisplayURLProviderBuilder.LOCALHOST_URL_TEMPLATE,
+ "funnyStatus", Collections.emptyList(), "#FF00FF", false);
+
+ when(run.getResult()).thenReturn(Result.FAILURE);
+ Office365ConnectorWebhookNotifier notifier = new Office365ConnectorWebhookNotifier(run, mockListener());
+
+ // when
+ notifier.sendBuildStepNotification(stepParameters);
+
+ // then
+ assertHasSameContent(workerData.get(0), FileUtils.getContentFile("adaptivecard-step.json"));
+ assertEquals(1, workerConstruction.constructed().size());
+ }
+}
diff --git a/src/test/java/jenkins/plugins/office365connector/workflow/SampleIT.java b/src/test/java/jenkins/plugins/office365connector/workflow/SampleIT.java
index 5cb097d8..b999e9c8 100644
--- a/src/test/java/jenkins/plugins/office365connector/workflow/SampleIT.java
+++ b/src/test/java/jenkins/plugins/office365connector/workflow/SampleIT.java
@@ -149,7 +149,7 @@ public void sendBuildStepNotification_SendsProperData() {
// given
StepParameters stepParameters = new StepParameters(
"helloMessage", ClassicDisplayURLProviderBuilder.LOCALHOST_URL_TEMPLATE,
- "funnyStatus", Collections.emptyList(), "#FF00FF");
+ "funnyStatus", Collections.emptyList(), "#FF00FF", false);
when(run.getResult()).thenReturn(Result.FAILURE);
Office365ConnectorWebhookNotifier notifier = new Office365ConnectorWebhookNotifier(run, mockListener());
diff --git a/src/test/java/jenkins/plugins/office365connector/workflow/StepParametersTest.java b/src/test/java/jenkins/plugins/office365connector/workflow/StepParametersTest.java
index c2217dbd..2d030cac 100644
--- a/src/test/java/jenkins/plugins/office365connector/workflow/StepParametersTest.java
+++ b/src/test/java/jenkins/plugins/office365connector/workflow/StepParametersTest.java
@@ -25,7 +25,7 @@ public class StepParametersTest {
@Before
public void setUp() {
stepParameters = new StepParameters(
- MESSAGE, WEBHOOK_URL, STATUS, Collections.singletonList(FACT_DEFINITION), COLOR);
+ MESSAGE, WEBHOOK_URL, STATUS, Collections.singletonList(FACT_DEFINITION), COLOR, false);
}
@Test
diff --git a/src/test/resources/requests/adaptivecard-step.json b/src/test/resources/requests/adaptivecard-step.json
new file mode 100644
index 00000000..69e4a369
--- /dev/null
+++ b/src/test/resources/requests/adaptivecard-step.json
@@ -0,0 +1,27 @@
+{
+ "summary": "myFirst_Job_: Build #167",
+ "themeColor": "#FF00FF",
+ "sections": [
+ {
+ "markdown": true,
+ "facts": [
+ {
+ "name": "Status",
+ "value": "funnyStatus"
+ }
+ ],
+ "activityTitle": "Notification from myFirst\\_Job\\_",
+ "activitySubtitle": "helloMessage"
+ }
+ ],
+ "potentialAction": [
+ {
+ "@context": "http://schema.org",
+ "@type": "ViewAction",
+ "name": "View Build",
+ "target": [
+ "http://localhost/job/myFirst_Job_/167/display/redirect"
+ ]
+ }
+ ]
+}
diff --git a/src/test/resources/requests/adaptivecard-success.json b/src/test/resources/requests/adaptivecard-success.json
new file mode 100644
index 00000000..672772a2
--- /dev/null
+++ b/src/test/resources/requests/adaptivecard-success.json
@@ -0,0 +1,70 @@
+{
+ "type": "message",
+ "attachments": [
+ {
+ "contentType": "application/vnd.microsoft.card.adaptive",
+ "content": {
+ "type": "AdaptiveCard",
+ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
+ "version": "1.4",
+ "msTeams": {
+ "width": "Full"
+ },
+ "body": [
+ {
+ "text": "myFirst_Job_: Build #167 Success",
+ "weight": "bolder",
+ "size": "large",
+ "color": "good",
+ "type": "TextBlock",
+ "wrap": true
+ },
+ {
+ "type": "ColumnSet",
+ "columns": [
+ {
+ "type": "Column",
+ "items": [
+ {
+ "text": "Notification from myFirst\\_Job\\_: Build Success",
+ "weight": "bolder",
+ "size": "default",
+ "color": "default",
+ "type": "TextBlock",
+ "wrap": true
+ },
+ {
+ "text": "Latest status of build #167",
+ "weight": "default",
+ "size": "default",
+ "color": "default",
+ "type": "TextBlock",
+ "wrap": true
+ }
+ ]
+ }
+ ],
+ "witdth": "stretch"
+ },
+ {
+ "facts": [
+ {
+ "title": "Status",
+ "value": "Build Success"
+ },
+ {
+ "title": "Remarks",
+ "value": "Started by John."
+ },
+ {
+ "title": "Developers",
+ "value": "Mike"
+ }
+ ],
+ "type": "FactSet"
+ }
+ ]
+ }
+ }
+ ]
+}