From 4c310c5201901159aeb00d8884c6edbc81a0bf68 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Wed, 1 Oct 2025 16:28:24 +0100 Subject: [PATCH] Show build cause on experimental build UI (#11128) Co-authored-by: Kris Stern --- core/src/main/java/hudson/Functions.java | 2 +- core/src/main/java/hudson/model/Cause.java | 17 ++++- core/src/main/java/hudson/model/Run.java | 3 +- .../jenkins/model/details/CauseDetail.java | 29 +++++++++ .../java/jenkins/model/details/Detail.java | 4 +- .../model/details/TimestampDetail.java | 5 ++ .../model/Cause/RemoteCause/description.jelly | 2 +- .../Cause/RemoteCause/description.properties | 1 - .../RemoteCause/description_fr.properties | 1 - .../model/Cause/RemoteCause/detail.jelly | 32 ++++++++++ .../model/Cause/UpstreamCause/detail.jelly | 64 +++++++++++++++++++ .../detail.properties} | 13 ++-- .../model/Cause/UserIdCause/detail.jelly | 48 ++++++++++++++ .../detail.properties} | 13 ++-- .../hudson/model/CauseAction/summary.jelly | 24 ++++--- .../model/details/CauseDetail/detail.jelly | 39 +++++++++++ src/main/scss/components/_details.scss | 5 +- .../main/resources/images/symbols/cause.svg | 1 + 18 files changed, 270 insertions(+), 33 deletions(-) create mode 100644 core/src/main/java/jenkins/model/details/CauseDetail.java delete mode 100644 core/src/main/resources/hudson/model/Cause/RemoteCause/description.properties delete mode 100644 core/src/main/resources/hudson/model/Cause/RemoteCause/description_fr.properties create mode 100644 core/src/main/resources/hudson/model/Cause/RemoteCause/detail.jelly create mode 100644 core/src/main/resources/hudson/model/Cause/UpstreamCause/detail.jelly rename core/src/main/resources/hudson/model/Cause/{RemoteCause/description_sv_SE.properties => UpstreamCause/detail.properties} (83%) create mode 100644 core/src/main/resources/hudson/model/Cause/UserIdCause/detail.jelly rename core/src/main/resources/hudson/model/Cause/{RemoteCause/description_pt_BR.properties => UserIdCause/detail.properties} (86%) create mode 100644 core/src/main/resources/jenkins/model/details/CauseDetail/detail.jelly create mode 100644 war/src/main/resources/images/symbols/cause.svg diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 054b441f8e..b13d854756 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -2621,7 +2621,7 @@ public class Functions { for (Map.Entry> entry : result.entrySet()) { List detailList = entry.getValue(); - detailList.sort(Comparator.comparingInt(Detail::getOrder)); + detailList.sort(Comparator.comparingInt(Detail::getOrder).reversed()); } return result; diff --git a/core/src/main/java/hudson/model/Cause.java b/core/src/main/java/hudson/model/Cause.java index 668587ffc8..ecad4e8c53 100644 --- a/core/src/main/java/hudson/model/Cause.java +++ b/core/src/main/java/hudson/model/Cause.java @@ -24,6 +24,8 @@ package hudson.model; +import static hudson.Functions.getAvatar; + import com.thoughtworks.xstream.converters.UnmarshallingContext; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -445,19 +447,30 @@ public abstract class Cause { return userId != null ? userId : User.getUnknown().getId(); } + private User getUser() { + return userId == null ? null : User.getById(userId, false); + } + @Exported(visibility = 3) public String getUserName() { - final User user = userId == null ? null : User.getById(userId, false); + final User user = getUser(); return user == null ? "anonymous" : user.getDisplayName(); } @Restricted(DoNotUse.class) // for Jelly @CheckForNull public String getUserUrl() { - final User user = userId == null ? null : User.getById(userId, false); + final User user = getUser(); return user != null ? user.getUrl() : null; } + @Restricted(DoNotUse.class) // for Jelly + @CheckForNull + public String getUserAvatar() { + final User user = getUser(); + return user != null ? getAvatar(user, "48x48") : null; + } + @Override public String getShortDescription() { return Messages.Cause_UserIdCause_ShortDescription(getUserName()); diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index 975899575d..33510af1d4 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -120,6 +120,7 @@ import jenkins.model.Jenkins; import jenkins.model.JenkinsLocationConfiguration; import jenkins.model.RunAction2; import jenkins.model.StandardArtifactManager; +import jenkins.model.details.CauseDetail; import jenkins.model.details.Detail; import jenkins.model.details.DetailFactory; import jenkins.model.details.DurationDetail; @@ -2706,7 +2707,7 @@ public abstract class Run, RunT extends Run createFor(@NonNull Run target) { - return List.of(new TimestampDetail(target), new DurationDetail(target)); + return List.of(new CauseDetail(target), new TimestampDetail(target), new DurationDetail(target)); } } } diff --git a/core/src/main/java/jenkins/model/details/CauseDetail.java b/core/src/main/java/jenkins/model/details/CauseDetail.java new file mode 100644 index 0000000000..645e561d95 --- /dev/null +++ b/core/src/main/java/jenkins/model/details/CauseDetail.java @@ -0,0 +1,29 @@ +package jenkins.model.details; + +import hudson.model.Cause; +import hudson.model.CauseAction; +import hudson.model.Run; +import java.util.Map; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * Displays the cause for the given run + */ +public class CauseDetail extends Detail { + + public CauseDetail(Run run) { + super(run); + } + + @Override + public int getOrder() { + return Integer.MAX_VALUE; + } + + @Restricted(NoExternalUse.class) + public Map getCauseCounts() { + CauseAction causeAction = getObject().getAction(CauseAction.class); + return causeAction.getCauseCounts(); + } +} diff --git a/core/src/main/java/jenkins/model/details/Detail.java b/core/src/main/java/jenkins/model/details/Detail.java index 10df02f78f..757f00c60a 100644 --- a/core/src/main/java/jenkins/model/details/Detail.java +++ b/core/src/main/java/jenkins/model/details/Detail.java @@ -60,9 +60,9 @@ public abstract class Detail implements ModelObject, IconSpec { } /** - * @return order in the group, zero is first, MAX_VALUE is any order + * @return order in the group, MAX_VALUE is first, zero is any order */ public int getOrder() { - return Integer.MAX_VALUE; + return 0; } } diff --git a/core/src/main/java/jenkins/model/details/TimestampDetail.java b/core/src/main/java/jenkins/model/details/TimestampDetail.java index fb000089ad..c29b5395ef 100644 --- a/core/src/main/java/jenkins/model/details/TimestampDetail.java +++ b/core/src/main/java/jenkins/model/details/TimestampDetail.java @@ -10,4 +10,9 @@ public class TimestampDetail extends Detail { public TimestampDetail(Run run) { super(run); } + + @Override + public int getOrder() { + return Integer.MAX_VALUE - 1; + } } diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description.jelly b/core/src/main/resources/hudson/model/Cause/RemoteCause/description.jelly index 57d84a3d71..1ae99147c0 100644 --- a/core/src/main/resources/hudson/model/Cause/RemoteCause/description.jelly +++ b/core/src/main/resources/hudson/model/Cause/RemoteCause/description.jelly @@ -23,5 +23,5 @@ THE SOFTWARE. --> - ${%blurb(it.addr, it.note)} + ${it.shortDescription} diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description.properties b/core/src/main/resources/hudson/model/Cause/RemoteCause/description.properties deleted file mode 100644 index 5274b4ad9f..0000000000 --- a/core/src/main/resources/hudson/model/Cause/RemoteCause/description.properties +++ /dev/null @@ -1 +0,0 @@ -blurb = Started by remote host {0} with note: {1} diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description_fr.properties b/core/src/main/resources/hudson/model/Cause/RemoteCause/description_fr.properties deleted file mode 100644 index b8f241f448..0000000000 --- a/core/src/main/resources/hudson/model/Cause/RemoteCause/description_fr.properties +++ /dev/null @@ -1 +0,0 @@ -blurb = Démarré par l''hôte distant {0} avec la note : {1} diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/detail.jelly b/core/src/main/resources/hudson/model/Cause/RemoteCause/detail.jelly new file mode 100644 index 0000000000..d94291c0ea --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/RemoteCause/detail.jelly @@ -0,0 +1,32 @@ + + + +
+
+ +
+ +
+
diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/detail.jelly b/core/src/main/resources/hudson/model/Cause/UpstreamCause/detail.jelly new file mode 100644 index 0000000000..72d839c0b8 --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/detail.jelly @@ -0,0 +1,64 @@ + + + + + + + + +
+ +
+ + ${%started_by_project(app.getItemByFullName(it.upstreamProject).fullDisplayName,it.upstreamBuild.toString(),it.upstreamUrl,rootURL)} + +
+
+ + +
+ +
+ + ${%started_by_project_with_deleted_build(app.getItemByFullName(it.upstreamProject).fullDisplayName,it.upstreamBuild.toString(),it.upstreamUrl,rootURL)} + +
+
+
+
+ +
+
+ +
+ + ${it.shortDescription} + +
+
+
+
diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description_sv_SE.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/detail.properties similarity index 83% rename from core/src/main/resources/hudson/model/Cause/RemoteCause/description_sv_SE.properties rename to core/src/main/resources/hudson/model/Cause/UpstreamCause/detail.properties index a89762053f..f49710550f 100644 --- a/core/src/main/resources/hudson/model/Cause/RemoteCause/description_sv_SE.properties +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/detail.properties @@ -1,17 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors -# +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Alan Harder +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blurb=Startades av fjärrvärden {0} med följande anteckning: {1} +started_by_project=Started by upstream project {0} #{1} +started_by_project_with_deleted_build=Started by upstream project {0} #{1} diff --git a/core/src/main/resources/hudson/model/Cause/UserIdCause/detail.jelly b/core/src/main/resources/hudson/model/Cause/UserIdCause/detail.jelly new file mode 100644 index 0000000000..020440bb9f --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/UserIdCause/detail.jelly @@ -0,0 +1,48 @@ + + + + + + +
+ +
+ + ${%started_by_user(it.userName)} + +
+
+ +
+
+ +
+ + ${%started_by_anonymous} + +
+
+
+
diff --git a/core/src/main/resources/hudson/model/Cause/RemoteCause/description_pt_BR.properties b/core/src/main/resources/hudson/model/Cause/UserIdCause/detail.properties similarity index 86% rename from core/src/main/resources/hudson/model/Cause/RemoteCause/description_pt_BR.properties rename to core/src/main/resources/hudson/model/Cause/UserIdCause/detail.properties index 0d08d7aa9c..d2b0ebe5ba 100644 --- a/core/src/main/resources/hudson/model/Cause/RemoteCause/description_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Cause/UserIdCause/detail.properties @@ -1,17 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributors -# +# +# Copyright (c) 2004-2011, Seiji Sogabe +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blurb=Iniciado pelo hospedeiro remoto {0} com a nota: {1} +started_by_user=Started by {0} +started_by_anonymous=Started by anonymous user diff --git a/core/src/main/resources/hudson/model/CauseAction/summary.jelly b/core/src/main/resources/hudson/model/CauseAction/summary.jelly index ccde699aee..1dd70de53d 100644 --- a/core/src/main/resources/hudson/model/CauseAction/summary.jelly +++ b/core/src/main/resources/hudson/model/CauseAction/summary.jelly @@ -24,14 +24,18 @@ THE SOFTWARE. - - -

- - - ${%Ntimes(entry.value)} - -

-
-
+ + + + + +

+ + + ${%Ntimes(entry.value)} + +

+
+
+
diff --git a/core/src/main/resources/jenkins/model/details/CauseDetail/detail.jelly b/core/src/main/resources/jenkins/model/details/CauseDetail/detail.jelly new file mode 100644 index 0000000000..c923ca3d9d --- /dev/null +++ b/core/src/main/resources/jenkins/model/details/CauseDetail/detail.jelly @@ -0,0 +1,39 @@ + + + + + + +
+
+ +
+
+ +
+
+
+
+
diff --git a/src/main/scss/components/_details.scss b/src/main/scss/components/_details.scss index 90286abad0..075d3d4f4d 100644 --- a/src/main/scss/components/_details.scss +++ b/src/main/scss/components/_details.scss @@ -5,7 +5,7 @@ $icon-size: 1.125rem; .jenkins-details { display: flex; align-items: center; - gap: 0.75rem 1.25rem; + gap: 0.25rem 1.25rem; flex-wrap: wrap; button.jenkins-details__item, @@ -37,7 +37,8 @@ $icon-size: 1.125rem; width: $icon-size; height: 2rem; - svg { + svg, + img { width: $icon-size; height: $icon-size; diff --git a/war/src/main/resources/images/symbols/cause.svg b/war/src/main/resources/images/symbols/cause.svg new file mode 100644 index 0000000000..dbc1a605cf --- /dev/null +++ b/war/src/main/resources/images/symbols/cause.svg @@ -0,0 +1 @@ + \ No newline at end of file