From a1c8c83cf7fa58a1d0f4ca92b4e293601966d13e Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 15 Nov 2024 10:58:26 -0800 Subject: [PATCH 01/17] Register `OptionHandler`s through `META-INF/services/annotations` and Annotation Indexer rather than `META-INF/services` and Commons Discovery --- core/src/main/java/hudson/cli/CLICommand.java | 29 ++++++++----------- .../hudson/cli/declarative/CLIRegisterer.java | 1 - .../declarative/OptionHandlerExtension.java | 1 - .../handlers/AbstractItemOptionHandler.java | 6 ++-- .../AbstractProjectOptionHandler.java | 5 ++-- .../hudson/cli/handlers/JobOptionHandler.java | 5 ++-- .../cli/handlers/NodeOptionHandler.java | 4 +-- .../ParameterizedJobOptionHandler.java | 5 ++-- .../handlers/TopLevelItemOptionHandler.java | 5 ++-- .../cli/handlers/ViewOptionHandler.java | 4 +-- 10 files changed, 27 insertions(+), 38 deletions(-) diff --git a/core/src/main/java/hudson/cli/CLICommand.java b/core/src/main/java/hudson/cli/CLICommand.java index f2dc2f8b5fc3..ba7fd4250fdd 100644 --- a/core/src/main/java/hudson/cli/CLICommand.java +++ b/core/src/main/java/hudson/cli/CLICommand.java @@ -242,7 +242,6 @@ public int main(List args, Locale locale, InputStream stdin, PrintStream this.stdout = stdout; this.stderr = stderr; this.locale = locale; - registerOptionHandlers(); CmdLineParser p = getCmdLineParser(); // add options from the authenticator @@ -527,20 +526,6 @@ protected CLICommand createClone() { } } - /** - * Auto-discovers {@link OptionHandler}s and add them to the given command line parser. - */ - protected void registerOptionHandlers() { - try { - for (Class c : Index.list(OptionHandlerExtension.class, Jenkins.get().pluginManager.uberClassLoader, Class.class)) { - Type t = Types.getBaseClass(c, OptionHandler.class); - CmdLineParser.registerHandler(Types.erasure(Types.getTypeArgument(t, 0)), c); - } - } catch (IOException e) { - throw new Error(e); - } - } - /** * Returns all the registered {@link CLICommand}s. */ @@ -577,11 +562,21 @@ public static CLICommand getCurrent() { static { // register option handlers that are defined - ClassLoaders cls = new ClassLoaders(); Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { // only when running on the controller - cls.put(j.getPluginManager().uberClassLoader); + // Register OptionHandlers through META-INF/services/annotations and Annotation Indexer + try { + for (Class c : Index.list(OptionHandlerExtension.class, Jenkins.get().pluginManager.uberClassLoader, Class.class)) { + Type t = Types.getBaseClass(c, OptionHandler.class); + CmdLineParser.registerHandler(Types.erasure(Types.getTypeArgument(t, 0)), c); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + // Register OptionHandlers through META-INF/services and Commons Discovery + ClassLoaders cls = new ClassLoaders(); + cls.put(j.getPluginManager().uberClassLoader); ResourceNameIterator servicesIter = new DiscoverServiceNames(cls).findResourceNames(OptionHandler.class.getName()); final ResourceClassIterator itr = diff --git a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java index f5d050174940..76b2c2612c15 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java +++ b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java @@ -131,7 +131,6 @@ protected CmdLineParser getCmdLineParser() { private CmdLineParser bindMethod(List binders) { - registerOptionHandlers(); ParserProperties properties = ParserProperties.defaults().withAtSyntax(ALLOW_AT_SYNTAX); CmdLineParser parser = new CmdLineParser(null, properties); diff --git a/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java b/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java index f009038ed2ac..3972514bc46c 100644 --- a/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java +++ b/core/src/main/java/hudson/cli/declarative/OptionHandlerExtension.java @@ -35,7 +35,6 @@ /** * {@link OptionHandler}s that should be auto-discovered. - * TODO is this actually necessary? {@code @MetaInfServices(OptionHandler.class)} seems to work as well. * @author Kohsuke Kawaguchi */ @Indexed diff --git a/core/src/main/java/hudson/cli/handlers/AbstractItemOptionHandler.java b/core/src/main/java/hudson/cli/handlers/AbstractItemOptionHandler.java index c99f3090799e..6919bd8a1ebc 100644 --- a/core/src/main/java/hudson/cli/handlers/AbstractItemOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/AbstractItemOptionHandler.java @@ -24,18 +24,18 @@ package hudson.cli.handlers; +import hudson.cli.declarative.OptionHandlerExtension; import hudson.model.AbstractItem; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Setter; /** * Refers to an {@link AbstractItem} by name. * @since 1.538 */ -@MetaInfServices(OptionHandler.class) public class AbstractItemOptionHandler extends GenericItemOptionHandler { +@OptionHandlerExtension +public class AbstractItemOptionHandler extends GenericItemOptionHandler { public AbstractItemOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { super(parser, option, setter); diff --git a/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java b/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java index ab7402de65ae..0efd7fca54f8 100644 --- a/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/AbstractProjectOptionHandler.java @@ -24,11 +24,10 @@ package hudson.cli.handlers; +import hudson.cli.declarative.OptionHandlerExtension; import hudson.model.AbstractProject; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Setter; /** @@ -36,7 +35,7 @@ * * @author Kohsuke Kawaguchi */ -@MetaInfServices(OptionHandler.class) +@OptionHandlerExtension @SuppressWarnings("rawtypes") public class AbstractProjectOptionHandler extends GenericItemOptionHandler { public AbstractProjectOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { diff --git a/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java b/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java index 519293150341..e0141446cce1 100644 --- a/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java @@ -24,11 +24,10 @@ package hudson.cli.handlers; +import hudson.cli.declarative.OptionHandlerExtension; import hudson.model.Job; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Setter; /** @@ -36,7 +35,7 @@ * * @author Kohsuke Kawaguchi */ -@MetaInfServices(OptionHandler.class) +@OptionHandlerExtension @SuppressWarnings("rawtypes") public class JobOptionHandler extends GenericItemOptionHandler { public JobOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { diff --git a/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java index 45bd0f4e679b..7e4d0367bd9e 100644 --- a/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java @@ -24,9 +24,9 @@ package hudson.cli.handlers; +import hudson.cli.declarative.OptionHandlerExtension; import hudson.model.Node; import jenkins.model.Jenkins; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; @@ -40,7 +40,7 @@ * @author ogondza * @since 1.526 */ -@MetaInfServices +@OptionHandlerExtension public class NodeOptionHandler extends OptionHandler { public NodeOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { diff --git a/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java b/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java index a37dbf1790f1..b75369070581 100644 --- a/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/ParameterizedJobOptionHandler.java @@ -24,20 +24,19 @@ package hudson.cli.handlers; +import hudson.cli.declarative.OptionHandlerExtension; import jenkins.model.ParameterizedJobMixIn; -import org.kohsuke.MetaInfServices; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Setter; /** * Refer to {@link jenkins.model.ParameterizedJobMixIn.ParameterizedJob} by its name. */ @Restricted(DoNotUse.class) -@MetaInfServices(OptionHandler.class) +@OptionHandlerExtension @SuppressWarnings("rawtypes") public class ParameterizedJobOptionHandler extends GenericItemOptionHandler { diff --git a/core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java b/core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java index 97fdf4b8c5b6..93f1dd969ba1 100644 --- a/core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/TopLevelItemOptionHandler.java @@ -1,10 +1,9 @@ package hudson.cli.handlers; +import hudson.cli.declarative.OptionHandlerExtension; import hudson.model.TopLevelItem; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Setter; /** @@ -12,7 +11,7 @@ * * @author Kohsuke Kawaguchi */ -@MetaInfServices(OptionHandler.class) +@OptionHandlerExtension public class TopLevelItemOptionHandler extends GenericItemOptionHandler { public TopLevelItemOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { super(parser, option, setter); diff --git a/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java b/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java index 65656c15e33c..50101b284908 100644 --- a/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java @@ -25,11 +25,11 @@ package hudson.cli.handlers; import edu.umd.cs.findbugs.annotations.CheckForNull; +import hudson.cli.declarative.OptionHandlerExtension; import hudson.model.View; import hudson.model.ViewGroup; import java.util.StringTokenizer; import jenkins.model.Jenkins; -import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; @@ -58,7 +58,7 @@ * @author ogondza * @since 1.538 */ -@MetaInfServices +@OptionHandlerExtension public class ViewOptionHandler extends OptionHandler { public ViewOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { From fc4a567604527120e7d321032b3336806deca8da Mon Sep 17 00:00:00 2001 From: Michael Tughan Date: Wed, 4 Dec 2024 15:15:13 -0500 Subject: [PATCH 02/17] Allow all immutable List subclasses from Java 11 A previous commit specifically allowed one of the two subclasses used by `List.of` and `List.copyOf`, but not the other, which can result in unexpected errors and bugs. Add the other to the default allow list of classes to avoid these. --- core/src/main/resources/jenkins/security/whitelisted-classes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/resources/jenkins/security/whitelisted-classes.txt b/core/src/main/resources/jenkins/security/whitelisted-classes.txt index b1805a6bd387..f3f9080bde81 100644 --- a/core/src/main/resources/jenkins/security/whitelisted-classes.txt +++ b/core/src/main/resources/jenkins/security/whitelisted-classes.txt @@ -105,6 +105,7 @@ java.util.HashMap java.util.HashSet java.util.Hashtable java.util.ImmutableCollections$List12 +java.util.ImmutableCollections$ListN java.util.LinkedHashMap java.util.LinkedHashSet java.util.LinkedList From 387dcbc84f06e2232530f9244b4d7ae6e8df6046 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:08:15 +0000 Subject: [PATCH 03/17] Use modern color function notation --- .stylelintrc.js | 1 - src/main/scss/abstracts/_theme.scss | 63 +++++++++--------- src/main/scss/base/_style.scss | 2 +- src/main/scss/components/_badges.scss | 2 +- src/main/scss/form/_toggle-switch.scss | 6 +- src/main/scss/pages/_about.scss | 30 ++++----- src/main/scss/pluginSetupWizard.scss | 90 +++++++++++++------------- 7 files changed, 96 insertions(+), 98 deletions(-) diff --git a/.stylelintrc.js b/.stylelintrc.js index cfea225e3035..c73ee6eecfe9 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -28,7 +28,6 @@ module.exports = { ], }, ], - "color-function-notation": "legacy", "alpha-value-notation": "number", "number-max-precision": 5, "function-no-unknown": null, diff --git a/src/main/scss/abstracts/_theme.scss b/src/main/scss/abstracts/_theme.scss index f1248e5b21de..9d750a5791d6 100644 --- a/src/main/scss/abstracts/_theme.scss +++ b/src/main/scss/abstracts/_theme.scss @@ -47,12 +47,12 @@ $semantics: ( // Color palette --very-light-grey: #f8f8f8; - --light-grey: hsl(240, 20%, 96.5%); + --light-grey: hsl(240 20% 96.5%); --medium-grey: #9ba7af; --dark-grey: #4d545d; // branding - --secondary: rgb(96, 125, 159); + --secondary: rgb(96 125 159); --focus-input-border: var(--accent-color); --focus-input-glow: color-mix(in sRGB, var(--accent-color) 15%, transparent); @@ -82,14 +82,14 @@ $semantics: ( --search-input-color: var(--brand-link-color); --search-bg: var(--white); --search-box-completion-bg: var(--primary-hover); - --search-box-shadow: 0 1px 7px 0 rgba(0, 0, 0, 0.3); + --search-box-shadow: 0 1px 7px 0 rgb(0 0 0 / 0.3); --header-bg-classic: #000; --header-link-bg-classic-hover: #404040; --header-link-bg-classic-active: #404040; --header-item-border-radius: 4px; // Breadcrumbs bar - --breadcrumbs-bar-background: hsla(240, 20%, 96.5%, 0.8); + --breadcrumbs-bar-background: hsl(240 20% 96.5% / 0.8); // Alert call outs --alert-success-text-color: var(--success-color); @@ -202,35 +202,34 @@ $semantics: ( // Command Palette --command-palette-results-backdrop-filter: contrast(0.7) brightness(1.5) saturate(1.4) blur(20px); - --command-palette-inset-shadow: inset 0 0 2px 2px rgba(255, 255, 255, 0.1); + --command-palette-inset-shadow: inset 0 0 2px 2px rgb(255 255 255 / 0.1); ::backdrop { --command-palette-backdrop-background: radial-gradient( farthest-corner at 50% 30vh, - rgba(0, 0, 0, 0.3), - rgba(0, 0, 0, 0.1) + rgb(0 0 0 / 0.3), + rgb(0 0 0 / 0.1) ); } // Tooltips --tooltip-backdrop-filter: saturate(2) blur(20px); --tooltip-color: var(--text-color); - --tooltip-box-shadow: 0 0 8px 2px rgba(0, 0, 30, 0.05), - 0 0 1px 1px rgba(0, 0, 20, 0.025), 0 10px 20px rgba(0, 0, 20, 0.15); + --tooltip-box-shadow: 0 0 8px 2px rgb(0 0 30 / 0.05), + 0 0 1px 1px rgb(0 0 20 / 0.025), 0 10px 20px rgb(0 0 20 / 0.15); // Dropdowns --dropdown-backdrop-filter: saturate(1.5) blur(20px); - --dropdown-box-shadow: 0 10px 30px rgba(0, 0, 20, 0.2), - 0 2px 10px rgba(0, 0, 20, 0.05), inset 0 -1px 2px rgba(255, 255, 255, 0.025); + --dropdown-box-shadow: 0 10px 30px rgb(0 0 20 / 0.2), + 0 2px 10px rgb(0 0 20 / 0.05), inset 0 -1px 2px rgb(255 255 255 / 0.025); // Dialogs ::backdrop { - --dialog-backdrop-background: hsla(240, 10%, 20%, 0.8); + --dialog-backdrop-background: hsl(240 10% 20% / 0.8); } - --dialog-box-shadow: 0 10px 40px rgba(0, 0, 20, 0.15), - 0 2px 15px rgba(0, 0, 20, 0.05), - inset 0 0 2px 2px rgba(255, 255, 255, 0.025); + --dialog-box-shadow: 0 10px 40px rgb(0 0 20 / 0.15), + 0 2px 15px rgb(0 0 20 / 0.05), inset 0 0 2px 2px rgb(255 255 255 / 0.025); // Dark link --link-dark-color: var(--text-color); @@ -257,18 +256,18 @@ $semantics: ( --card-background: var(--background); --card-background--hover: transparent; --card-background--active: transparent; - --card-border-color: hsla(240, 25%, 75%, 0.25); - --card-border-color--hover: hsla(240, 25%, 75%, 0.5); - --card-border-color--active: hsla(240, 25%, 75%, 0.75); + --card-border-color: hsl(240 25% 75% / 0.25); + --card-border-color--hover: hsl(240 25% 75% / 0.5); + --card-border-color--active: hsl(240 25% 75% / 0.75); --card-border-width: 2px; // Tab bar --tabs-background: var(--panel-header-bg-color); --tabs-item-background: transparent; --tabs-item-foreground: var(--text-color); - --tabs-item-background--hover: rgba(0, 0, 0, 0.05); + --tabs-item-background--hover: rgb(0 0 0 / 0.05); --tabs-item-foreground--hover: var(--text-color); - --tabs-item-background--active: rgba(0, 0, 0, 0.1); + --tabs-item-background--active: rgb(0 0 0 / 0.1); --tabs-item-foreground--active: var(--text-color); --tabs-item-background--selected: white; --tabs-item-foreground--selected: var(--link-color); @@ -322,9 +321,9 @@ $semantics: ( --form-input-border-radius: 0.625rem; --form-input-glow: 0 0 0 10px transparent; --form-input-glow--focus: 0 0 0 5px var(--focus-input-glow); - --pre-background: rgba(0, 0, 0, 0.05); + --pre-background: rgb(0 0 0 / 0.05); --pre-color: var(--text-color); - --selection-color: rgba(2, 76, 182, 0.3); + --selection-color: rgb(2 76 182 / 0.3); // Animations --standard-transition: 0.3s ease; @@ -334,13 +333,13 @@ $semantics: ( --menu-text-color: black; --menu-bg-color: var(--white); --menu-selected-color: #b3d4ff; - --menu-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3); + --menu-box-shadow: 0 3px 10px rgb(0 0 0 / 0.3); // Deprecated - Add form widget / configure job --light-bg-color: #eee; - --light-bg-color--hover: rgba(255, 255, 255, 0.65); + --light-bg-color--hover: rgb(255 255 255 / 0.65); --add-item-btn-decorator-border-color: #acb; - --add-item-btn-decorator-bg-color: rgba(245, 249, 239, 0.75); + --add-item-btn-decorator-bg-color: rgb(245 249 239 / 0.75); // Plugin manager --plugin-manager-bg-color-already-upgraded: var(--light-grey); @@ -349,15 +348,15 @@ $semantics: ( --auto-complete-bg-color--prehighlight: #b3d4ff; // Default button - --button-background: hsla(240, 25%, 75%, 0.1); - --button-background--hover: hsla(240, 25%, 75%, 0.175); - --button-background--active: hsla(240, 25%, 75%, 0.25); - --button-box-shadow--focus: hsla(240, 25%, 75%, 0.1); + --button-background: hsl(240 25% 75% / 0.1); + --button-background--hover: hsl(240 25% 75% / 0.175); + --button-background--active: hsl(240 25% 75% / 0.25); + --button-box-shadow--focus: hsl(240 25% 75% / 0.1); // Variables for sidebar items, card items - --item-background--hover: hsla(240, 25%, 75%, 0.15); - --item-background--active: hsla(240, 25%, 75%, 0.225); - --item-box-shadow--focus: hsla(240, 25%, 75%, 0.105); + --item-background--hover: hsl(240 25% 75% / 0.15); + --item-background--active: hsl(240 25% 75% / 0.225); + --item-box-shadow--focus: hsl(240 25% 75% / 0.105); // Deprecated --primary: var(--accent-color); // Use var(--accent-color) instead diff --git a/src/main/scss/base/_style.scss b/src/main/scss/base/_style.scss index 98807c6e5401..7150ce0c9818 100644 --- a/src/main/scss/base/_style.scss +++ b/src/main/scss/base/_style.scss @@ -209,7 +209,7 @@ pre.console { width: 100%; border-radius: 3px; border: 1px solid var(--input-border); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgb(0 0 0 / 0.075); padding: 6px; box-sizing: border-box; -webkit-box-sizing: border-box; diff --git a/src/main/scss/components/_badges.scss b/src/main/scss/components/_badges.scss index 45fc8b9dc803..4e4f10e5da76 100644 --- a/src/main/scss/components/_badges.scss +++ b/src/main/scss/components/_badges.scss @@ -18,7 +18,7 @@ background: color-mix(in sRGB, var(--color) 85%, transparent); color: var(--white) !important; box-shadow: inset 0 -1px 2px var(--color, var(--text-color-secondary)); - text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + text-shadow: 0 1px 1px rgb(0 0 0 / 0.1); backdrop-filter: blur(2.5px); } } diff --git a/src/main/scss/form/_toggle-switch.scss b/src/main/scss/form/_toggle-switch.scss index 451bceb71cfb..5f7f46a7f53a 100644 --- a/src/main/scss/form/_toggle-switch.scss +++ b/src/main/scss/form/_toggle-switch.scss @@ -113,7 +113,7 @@ transition: var(--standard-transition); margin-right: 1rem; box-shadow: - inset 0 0 0 1px rgba(0, 0, 0, 0.05), + inset 0 0 0 1px rgb(0 0 0 / 0.05), 0 0 0 10px transparent; } @@ -132,7 +132,7 @@ mask-position: center; border-radius: 100px; transition: var(--standard-transition); - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 0 rgb(0 0 0 / 0.1); } &:hover::before { @@ -143,7 +143,7 @@ &:focus { &::before { box-shadow: - inset 0 0 0 1px rgba(0, 0, 0, 0.05), + inset 0 0 0 1px rgb(0 0 0 / 0.05), 0 0 0 5px var(--focus-input-glow); } diff --git a/src/main/scss/pages/_about.scss b/src/main/scss/pages/_about.scss index b39fc84e4cd9..4417d5750ed1 100644 --- a/src/main/scss/pages/_about.scss +++ b/src/main/scss/pages/_about.scss @@ -18,7 +18,7 @@ z-index: 1; background: repeating-conic-gradient( var(--background) 0deg, - rgba(100, 100, 100, 0.25) 20deg + rgb(100 100 100 / 0.25) 20deg ); animation: app-about-starburst 100s linear infinite; opacity: 0.25; @@ -48,15 +48,15 @@ background-color: var(--color); background-image: radial-gradient( at 40% 20%, - hsla(28, 100%, 74%, 1) 0, + hsl(28 100% 74% / 1) 0, transparent 50% ), - radial-gradient(at 80% 0%, hsla(189, 100%, 56%, 1) 0, transparent 50%), - radial-gradient(at 0% 50%, hsla(355, 85%, 93%, 1) 0, transparent 50%), - radial-gradient(at 80% 50%, hsl(359, 70%, 46%) 0, transparent 50%), - radial-gradient(at 0% 100%, hsla(22, 100%, 77%, 1) 0, transparent 50%), - radial-gradient(at 80% 100%, hsla(242, 100%, 70%, 1) 0, transparent 50%), - radial-gradient(at 0% 0%, hsla(343, 100%, 76%, 1) 0, transparent 50%); + radial-gradient(at 80% 0%, hsl(189 100% 56% / 1) 0, transparent 50%), + radial-gradient(at 0% 50%, hsl(355 85% 93% / 1) 0, transparent 50%), + radial-gradient(at 80% 50%, hsl(359 70% 46%) 0, transparent 50%), + radial-gradient(at 0% 100%, hsl(22 100% 77% / 1) 0, transparent 50%), + radial-gradient(at 80% 100%, hsl(242 100% 70% / 1) 0, transparent 50%), + radial-gradient(at 0% 0%, hsl(343 100% 76% / 1) 0, transparent 50%); opacity: 0.4; animation: app-about-aurora-one 7s linear infinite; } @@ -64,15 +64,15 @@ &::after { background-image: radial-gradient( at 40% 20%, - hsla(212, 100%, 74%, 1) 0, + hsl(212 100% 74% / 1) 0, transparent 50% ), - radial-gradient(at 80% 0%, hsla(13, 100%, 56%, 1) 0, transparent 50%), - radial-gradient(at 0% 50%, hsla(179, 85%, 93%, 1) 0, transparent 50%), - radial-gradient(at 80% 50%, hsla(164, 100%, 76%, 1) 0, transparent 50%), - radial-gradient(at 0% 100%, hsla(206, 100%, 77%, 1) 0, transparent 50%), - radial-gradient(at 80% 100%, hsla(66, 100%, 70%, 1) 0, transparent 50%), - radial-gradient(at 0% 0%, hsla(167, 100%, 76%, 1) 0, transparent 50%); + radial-gradient(at 80% 0%, hsl(13 100% 56% / 1) 0, transparent 50%), + radial-gradient(at 0% 50%, hsl(179 85% 93% / 1) 0, transparent 50%), + radial-gradient(at 80% 50%, hsl(164 100% 76% / 1) 0, transparent 50%), + radial-gradient(at 0% 100%, hsl(206 100% 77% / 1) 0, transparent 50%), + radial-gradient(at 80% 100%, hsl(66 100% 70% / 1) 0, transparent 50%), + radial-gradient(at 0% 0%, hsl(167 100% 76% / 1) 0, transparent 50%); opacity: 0.2; animation: app-about-aurora-two 14s linear infinite; } diff --git a/src/main/scss/pluginSetupWizard.scss b/src/main/scss/pluginSetupWizard.scss index 9b9f5b72ed8d..0643003925fe 100644 --- a/src/main/scss/pluginSetupWizard.scss +++ b/src/main/scss/pluginSetupWizard.scss @@ -21,7 +21,7 @@ position: fixed; inset: 0; z-index: 1000; - background: rgba(0, 0, 0, 0.2); + background: rgb(0 0 0 / 0.2); text-align: initial; font-size: 13px; @@ -94,8 +94,8 @@ background: linear-gradient( 175deg, #f8f8f8 0%, - rgba(255, 255, 255, 1) 22%, - rgba(255, 255, 255, 0) 100% + rgb(255 255 255 / 1) 22%, + rgb(255 255 255 / 0) 100% ); overflow-y: auto; height: 100%; @@ -108,7 +108,7 @@ display: block; bottom: 0; right: 50px; - color: rgba(0, 0, 0, 0.05); + color: rgb(0 0 0 / 0.05); } .installing-panel { @@ -118,7 +118,7 @@ height: 33.3%; position: relative; z-index: 9; - box-shadow: rgba(0, 0, 0, 0.5) 0 1px 5px; + box-shadow: rgb(0 0 0 / 0.5) 0 1px 5px; @media screen and (width <= 992px) { padding: 5%; @@ -187,7 +187,7 @@ .plugins { padding-top: 2.75em; position: relative; - border-left: 1px solid rgba(0, 0, 0, 0.2); + border-left: 1px solid rgb(0 0 0 / 0.2); @media screen and (width >= 768px) { height: 100%; @@ -266,8 +266,8 @@ padding: 0 10px; height: 2.75em; z-index: 100; - background: rgba(0, 0, 0, 0.03); - border-bottom: 1px solid rgba(0, 0, 0, 0.2); + background: rgb(0 0 0 / 0.03); + border-bottom: 1px solid rgb(0 0 0 / 0.2); .form-control { font-size: 13px; @@ -282,7 +282,7 @@ margin: -10px -10px 0; padding: 10px 20px; opacity: 0.7; - border-bottom: 1px solid rgba(0, 0, 0, 0.2); + border-bottom: 1px solid rgb(0 0 0 / 0.2); } .plugin-list { @@ -383,10 +383,10 @@ margin: 4px -7px; &:hover { - background: rgba(100, 200, 255, 0.1); + background: rgb(100 200 255 / 0.1); box-shadow: - inset 0 400px 400px -100px rgba(100, 200, 255, 0.33), - inset 0 0 0 1px rgba(100, 200, 255, 0.33); + inset 0 400px 400px -100px rgb(100 200 255 / 0.33), + inset 0 0 0 1px rgb(100 200 255 / 0.33); } .title { @@ -469,7 +469,7 @@ padding-left: 9px; background: $badge-background; color: $badge-color; - box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 0 1px 0 rgb(0 0 0 / 0.25); &::after { content: ""; @@ -511,7 +511,7 @@ color: #555; font-size: 14px; border-bottom: 1px solid #fff; - border-bottom: 1px solid rgba(255, 255, 255, 0.5); + border-bottom: 1px solid rgb(255 255 255 / 0.5); padding-bottom: 5px; } @@ -520,7 +520,7 @@ margin: 5px 3px 0 0; background: $badge-background; color: $badge-color; - box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 0 1px 0 rgb(0 0 0 / 0.25); &::after { content: ""; @@ -595,8 +595,8 @@ &:hover, &:focus { - background: rgba(100, 200, 255, 0.1); - box-shadow: inset -200px 0 200px -200px rgba(100, 200, 255, 0.33); + background: rgb(100 200 255 / 0.1); + box-shadow: inset -200px 0 200px -200px rgb(100 200 255 / 0.33); color: #337ab7; &::after { @@ -651,7 +651,7 @@ padding: 1px 10px; &:nth-child(odd) { - background: rgba(0, 0, 0, 0.05); + background: rgb(0 0 0 / 0.05); } } @@ -687,9 +687,9 @@ padding: 0; width: 75%; font-size: 0; - background: rgba(0, 0, 0, 0.1); + background: rgb(0 0 0 / 0.1); border-bottom: 1px solid #ccc; - border-top: 1px solid rgba(0, 0, 0, 0.1); + border-top: 1px solid rgb(0 0 0 / 0.1); @media screen and (width <= 992px) { width: 100%; @@ -713,15 +713,15 @@ overflow: hidden; font-size: 13px; height: 45px; - border-right: 1px solid rgba(0, 0, 0, 0.1); - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); - background: rgba(255, 255, 255, 0.75); + border-right: 1px solid rgb(0 0 0 / 0.1); + border-bottom: 1px solid rgb(0 0 0 / 0.1); + box-shadow: 0 1px 3px rgb(0 0 0 / 0.2); + background: rgb(255 255 255 / 0.75); &:nth-child(odd) { box-shadow: - 0 1px 3px rgba(0, 0, 0, 0.2), - inset 0 0 0 999px rgba(0, 0, 0, 0.05); + 0 1px 3px rgb(0 0 0 / 0.2), + inset 0 0 0 999px rgb(0 0 0 / 0.05); } &::before { @@ -734,12 +734,12 @@ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Ccircle cx='256' cy='256' r='192' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='32'/%3E%3C/svg%3E"); mask-size: contain; mask-position: center; - background: rgba(0, 0, 0, 0.1); + background: rgb(0 0 0 / 0.1); } &.installing { &::before { - background: rgba(0, 60, 100, 0.33); + background: rgb(0 60 100 / 0.33); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M400 148l-21.12-24.57A191.43 191.43 0 00240 64C134 64 48 150 48 256s86 192 192 192a192.09 192.09 0 00181.07-128' fill='none' stroke='currentColor' stroke-linecap='round' stroke-miterlimit='10' stroke-width='32'/%3E%3Cpath d='M464 97.42V208a16 16 0 01-16 16H337.42c-14.26 0-21.4-17.23-11.32-27.31L436.69 86.1C446.77 76 464 83.16 464 97.42z'/%3E%3C/svg%3E"); mask-size: contain; mask-position: center; @@ -810,12 +810,12 @@ margin-top: 1em; padding: 20px 25px; box-shadow: - inset 0 -200px 200px -100px rgba(0, 0, 0, 0.1), - 0 1px 3px rgba(0, 0, 0, 0.2); - border: 1px solid rgba(0, 60, 100, 0.5); + inset 0 -200px 200px -100px rgb(0 0 0 / 0.1), + 0 1px 3px rgb(0 0 0 / 0.2); + border: 1px solid rgb(0 60 100 / 0.5); text-shadow: #fff 0 1px 3px; position: relative; - background: rgba(255, 255, 255, 0.75); + background: rgb(255 255 255 / 0.75); @media screen and (width >= 768px) { max-width: 41%; @@ -824,37 +824,37 @@ } &:hover { - box-shadow: inset 0 1px 3px -1px rgba(0, 0, 0, 0.2); - background: rgba(100, 200, 255, 0.1); + box-shadow: inset 0 1px 3px -1px rgb(0 0 0 / 0.2); + background: rgb(100 200 255 / 0.1); } &:focus { background: #fff; box-shadow: - inset 0 -200px 200px -100px rgba(0, 0, 0, 0.1), - 0 0 5px 3px rgba(00, 180, 250, 0.2); + inset 0 -200px 200px -100px rgb(0 0 0 / 0.1), + 0 0 5px 3px rgb(00 180 250 / 0.2); } &:hover:focus { - background: rgba(100, 200, 255, 0.1); + background: rgb(100 200 255 / 0.1); } &.btn-primary { - background: rgba(200, 240, 255, 0.2); + background: rgb(200 240 255 / 0.2); box-shadow: - inset 0 -200px 200px -100px rgba(0, 120, 160, 0.2), - 0 1px 3px rgba(0, 0, 0, 0.2); - color: rgba(0, 80, 120, 1); + inset 0 -200px 200px -100px rgb(0 120 160 / 0.2), + 0 1px 3px rgb(0 0 0 / 0.2); + color: rgb(0 80 120 / 1); &:hover { - box-shadow: inset 0 1px 3px -1px rgba(0, 0, 0, 0.2); - background: rgba(70, 200, 255, 0.2); + box-shadow: inset 0 1px 3px -1px rgb(0 0 0 / 0.2); + background: rgb(70 200 255 / 0.2); } &:focus { box-shadow: - inset 0 -200px 200px -100px rgba(0, 120, 160, 0.2), - 0 0 5px 3px rgba(00, 180, 250, 0.2); + inset 0 -200px 200px -100px rgb(0 120 160 / 0.2), + 0 0 5px 3px rgb(00 180 250 / 0.2); } } From 5fd9f5178f9572c4c16654a45360fad560045357 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Mon, 30 Dec 2024 22:20:15 +0000 Subject: [PATCH 04/17] [JENKINS-74868] Use new build status symbols in multi branch projects --- .../resources/lib/hudson/ballColorTd.jelly | 67 +++++++++++-------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/core/src/main/resources/lib/hudson/ballColorTd.jelly b/core/src/main/resources/lib/hudson/ballColorTd.jelly index 9cbefdf3d43f..2fd299d2e496 100644 --- a/core/src/main/resources/lib/hudson/ballColorTd.jelly +++ b/core/src/main/resources/lib/hudson/ballColorTd.jelly @@ -24,9 +24,9 @@ THE SOFTWARE. - Display the ball in a TD. - - Color of the ball or null to skip drawing. + Display the build status icon in a table cell. + + Icon to be displayed. Specifies the size of the icon. If unspecified, it inherits from @@ -56,33 +56,42 @@ THE SOFTWARE. - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + From e1dff1ae2922cf995e7e2917c0d2818e60b0f0f8 Mon Sep 17 00:00:00 2001 From: Tim Jacomb Date: Tue, 31 Dec 2024 19:46:12 +0000 Subject: [PATCH 05/17] Adjust test --- test/src/test/java/lib/layout/IconTest.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test/src/test/java/lib/layout/IconTest.java b/test/src/test/java/lib/layout/IconTest.java index 033d8f161a7e..ef5043ee4309 100644 --- a/test/src/test/java/lib/layout/IconTest.java +++ b/test/src/test/java/lib/layout/IconTest.java @@ -93,11 +93,14 @@ public void testBallColorTd() throws Exception { HtmlPage p = j.createWebClient().goTo("testBallColorTd"); DomElement ballColorAborted = p.getElementById("ballColorAborted"); - List ballIcons = StreamSupport.stream(ballColorAborted.getChildElements().spliterator(), false).collect(Collectors.toList()); - assertIconToSvgIconOkay(ballIcons.get(0).getFirstElementChild(), "icon-aborted icon-md"); + assertThat("Aborted", is(ballColorAborted.getTextContent())); + HtmlElement symbol = ballColorAborted.getElementsByTagName("svg").get(0); + assertThat("icon-md", is(symbol.getAttribute("class"))); + + assertIconToSymbolOkay(symbol); DomElement statusIcons = p.getElementById("statusIcons"); - List statusIconsList = StreamSupport.stream(statusIcons.getChildElements().spliterator(), false).collect(Collectors.toList()); + List statusIconsList = StreamSupport.stream(statusIcons.getChildElements().spliterator(), false).toList(); assertIconToSvgOkay(statusIconsList.get(0).getFirstElementChild().getNextElementSibling(), "icon-user icon-xlg"); @@ -182,13 +185,6 @@ private void assertIconToSvgOkay(DomElement icon, String classSpec) { } } - private void assertIconToSvgIconOkay(DomElement icon, String classSpec) { - assertThat(icon.getTagName(), is("span")); - if (classSpec != null) { - assertThat(icon.getAttribute("class"), endsWith(classSpec)); - } - } - private void assertIconToSymbolOkay(DomElement icon) { assertThat("svg", is(icon.getTagName())); } From 1aa9c5755f3660f265aee6e07d08fa2ffc90ee72 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:44:50 -0800 Subject: [PATCH 06/17] Update Yarn to v4.6.0 (#10109) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9bb668c18686..bb6c03a0f5a7 100644 --- a/package.json +++ b/package.json @@ -68,5 +68,5 @@ "engines": { "node": ">=20.0.0" }, - "packageManager": "yarn@4.5.3" + "packageManager": "yarn@4.6.0" } From 75410bc607e9f59de1d7f2ebb7e0d8573eddf141 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:45:55 -0800 Subject: [PATCH 07/17] Update dependency io.jenkins.plugins:json-api to v20241224 (#10110) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- war/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/war/pom.xml b/war/pom.xml index 3ca47c03c952..a36affc90a15 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -551,7 +551,7 @@ THE SOFTWARE. io.jenkins.plugins json-api - 20240303-101.v7a_8666713110 + 20241224-119.va_dca_a_b_ea_7da_5 hpi From 238c498144ed416e65a5b70218a4206a5caa9a30 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 20:32:04 -0800 Subject: [PATCH 08/17] Update dependency io.jenkins.plugins:design-library to v342 (#10111) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pom.xml b/test/pom.xml index b79bfd5d1008..b659ea3d20b2 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -344,7 +344,7 @@ THE SOFTWARE. io.jenkins.plugins design-library - 336.v9effb_429a_d34 + 342.v9b_fb_09074f21 hpi ${project.build.outputDirectory}/plugins design-library.jpi From d3e8908b42d48ddd284c93cfd4f5d0c9ff88f33b Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 3 Jan 2025 05:43:27 -0500 Subject: [PATCH 09/17] Correcting API documentation of `builds` vs. `allBuilds` (#10112) --- core/src/main/resources/hudson/model/Job/_api.jelly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/hudson/model/Job/_api.jelly b/core/src/main/resources/hudson/model/Job/_api.jelly index 28a161afbb65..652a44c4ec56 100644 --- a/core/src/main/resources/hudson/model/Job/_api.jelly +++ b/core/src/main/resources/hudson/model/Job/_api.jelly @@ -30,7 +30,7 @@ THE SOFTWARE.

Retrieving all builds

To prevent Jenkins from having to load all builds from disk when someone accesses the job API, the builds - tree only contains the 50 newest builds. If you really need to get all builds, access the allBuilds tree, + tree only contains the 100 newest builds. If you really need to get all builds, access the allBuilds tree, e.g. by fetching …/api/xml?tree=allBuilds[…]. Note that this may result in significant performance degradation if you have a lot of builds in this job.

From 11e4b8d23713bcb95afe5878d87603da9771a96b Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sat, 4 Jan 2025 14:48:20 +0000 Subject: [PATCH 10/17] Init --- core/src/main/java/hudson/Functions.java | 12 +++++ .../jenkins/console/ConsoleUrlProvider.java | 20 +++++--- .../ConsoleWidgetUserExperimentalFlag.java | 49 +++++++++++++++++++ .../hudson/model/Run/console-log.jelly | 38 ++++++++++++++ .../hudson/model/Run/console-log.properties | 1 + .../resources/hudson/model/Run/console.jelly | 33 +------------ .../resources/hudson/model/Run/index.jelly | 5 ++ .../DefaultConsoleUrlProvider/console.jelly | 14 ++++++ .../resources/lib/hudson/progressive-text.js | 2 +- src/main/scss/pages/_build.scss | 16 ++++++ .../main/webapp/scripts/hudson-behavior.js | 10 ++-- 11 files changed, 158 insertions(+), 42 deletions(-) create mode 100644 core/src/main/java/jenkins/model/experimentalflags/ConsoleWidgetUserExperimentalFlag.java create mode 100644 core/src/main/resources/hudson/model/Run/console-log.jelly create mode 100644 core/src/main/resources/hudson/model/Run/console-log.properties create mode 100644 core/src/main/resources/jenkins/console/DefaultConsoleUrlProvider/console.jelly diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 67801475233d..153ff4c56b2c 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -54,6 +54,7 @@ import hudson.model.ParameterDefinition; import hudson.model.ParameterDefinition.ParameterDescriptor; import hudson.model.PasswordParameterDefinition; +import hudson.model.Queue; import hudson.model.Run; import hudson.model.Slave; import hudson.model.TimeZoneProperty; @@ -1993,6 +1994,17 @@ public static String joinPath(String... components) { return consoleUrl != null ? Stapler.getCurrentRequest().getContextPath() + '/' + consoleUrl : null; } + public static @CheckForNull ConsoleUrlProvider getConsoleProvider(Queue.Executable executable) { + if (executable == null) { + return null; + } else if (executable instanceof Run) { + return ConsoleUrlProvider.getProvider((Run) executable); + } else { + // Handles cases such as PlaceholderExecutable for Pipeline node steps. + return getConsoleProvider(executable.getParentExecutable()); + } + } + /** * Escapes the character unsafe for e-mail address. * See the Wikipedia page for the details, diff --git a/core/src/main/java/jenkins/console/ConsoleUrlProvider.java b/core/src/main/java/jenkins/console/ConsoleUrlProvider.java index 637cf10145c6..9c6080ac02fa 100644 --- a/core/src/main/java/jenkins/console/ConsoleUrlProvider.java +++ b/core/src/main/java/jenkins/console/ConsoleUrlProvider.java @@ -83,11 +83,7 @@ default Descriptor getDescriptor() { return Stapler.getCurrentRequest().getContextPath() + '/' + run.getConsoleUrl(); } - /** - * Looks up the {@link #getConsoleUrl} value from the first provider to offer one. - * @since 2.476 - */ - static @NonNull String consoleUrlOf(Run run) { + static List all() { final List providers = new ArrayList<>(); User currentUser = User.current(); if (currentUser != null) { @@ -105,8 +101,20 @@ default Descriptor getDescriptor() { if (globalProviders != null) { providers.addAll(globalProviders); } + return providers; + } + + static ConsoleUrlProvider getProvider(Run run) { + return all().stream().filter(provider -> provider.getConsoleUrl(run) != null).findFirst().orElse(null); + } + + /** + * Looks up the {@link #getConsoleUrl} value from the first provider to offer one. + * @since 2.476 + */ + static @NonNull String consoleUrlOf(Run run) { String url = null; - for (ConsoleUrlProvider provider : providers) { + for (ConsoleUrlProvider provider : all()) { try { String tempUrl = provider.getConsoleUrl(run); if (tempUrl != null) { diff --git a/core/src/main/java/jenkins/model/experimentalflags/ConsoleWidgetUserExperimentalFlag.java b/core/src/main/java/jenkins/model/experimentalflags/ConsoleWidgetUserExperimentalFlag.java new file mode 100644 index 000000000000..15e8671b0d33 --- /dev/null +++ b/core/src/main/java/jenkins/model/experimentalflags/ConsoleWidgetUserExperimentalFlag.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright (c) 2025, Jan Faracik + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.experimentalflags; + +import edu.umd.cs.findbugs.annotations.Nullable; +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@Extension +@Restricted(NoExternalUse.class) +public class ConsoleWidgetUserExperimentalFlag extends BooleanUserExperimentalFlag { + public ConsoleWidgetUserExperimentalFlag() { + super("console-widget.flag"); + } + + @Override + public String getDisplayName() { + return "Show Console Output on build pages"; + } + + @Nullable + @Override + public String getShortDescription() { + return "Shows the Console Output as a widget on build pages."; + } +} diff --git a/core/src/main/resources/hudson/model/Run/console-log.jelly b/core/src/main/resources/hudson/model/Run/console-log.jelly new file mode 100644 index 000000000000..bb2aad579a92 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/console-log.jelly @@ -0,0 +1,38 @@ + + + + + + + + + + ${%skipSome(offset / 1024)} + + + + + + + + + + + + +
+      
+ +
+ + + + +
+        
+        ${it.writeLogTo(offset,output)}
+      
+
+ + diff --git a/core/src/main/resources/hudson/model/Run/console-log.properties b/core/src/main/resources/hudson/model/Run/console-log.properties new file mode 100644 index 000000000000..12f13f7125d6 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/console-log.properties @@ -0,0 +1 @@ +skipSome=This log is too long to show here, {0,number,integer} KB has been skipped — click to see the complete log diff --git a/core/src/main/resources/hudson/model/Run/console.jelly b/core/src/main/resources/hudson/model/Run/console.jelly index ad38828dad5a..333fc741d9c0 100644 --- a/core/src/main/resources/hudson/model/Run/console.jelly +++ b/core/src/main/resources/hudson/model/Run/console.jelly @@ -50,38 +50,7 @@ THE SOFTWARE. ${%Console Output} - - - - - - ${%skipSome(offset/1024,"consoleFull")} - - - - - - - - - - - -
-            
- -
- - - - -
-            
-            ${it.writeLogTo(offset,output)}
-          
-
- + diff --git a/core/src/main/resources/hudson/model/Run/index.jelly b/core/src/main/resources/hudson/model/Run/index.jelly index b164817a164f..c37b7108a428 100644 --- a/core/src/main/resources/hudson/model/Run/index.jelly +++ b/core/src/main/resources/hudson/model/Run/index.jelly @@ -43,6 +43,11 @@ THE SOFTWARE. + + + + +
${%startedAgo(it.timestampString)} diff --git a/core/src/main/resources/jenkins/console/DefaultConsoleUrlProvider/console.jelly b/core/src/main/resources/jenkins/console/DefaultConsoleUrlProvider/console.jelly new file mode 100644 index 000000000000..ad11b66b7699 --- /dev/null +++ b/core/src/main/resources/jenkins/console/DefaultConsoleUrlProvider/console.jelly @@ -0,0 +1,14 @@ + + + + + + + + + +
+ +
+
+
diff --git a/core/src/main/resources/lib/hudson/progressive-text.js b/core/src/main/resources/lib/hudson/progressive-text.js index 71f84b2b2238..ede4d46eba6f 100644 --- a/core/src/main/resources/lib/hudson/progressive-text.js +++ b/core/src/main/resources/lib/hudson/progressive-text.js @@ -10,7 +10,7 @@ Behaviour.specify( let onFinishEvent = holder.getAttribute("data-on-finish-event"); let errorMessage = holder.getAttribute("data-error-message"); - var scroller = new AutoScroller(document.body); + var scroller = new AutoScroller(holder.closest(".progressive-text-container") || document.body); /* fetches the latest update from the server @param e diff --git a/src/main/scss/pages/_build.scss b/src/main/scss/pages/_build.scss index 6bcf404773fa..cb5e3298faf1 100644 --- a/src/main/scss/pages/_build.scss +++ b/src/main/scss/pages/_build.scss @@ -5,3 +5,19 @@ flex-wrap: nowrap; gap: 10px; } + +.app-console-output-widget { + min-height: 340px; + max-height: 340px; + overflow-y: auto; + margin: 0 -1rem -1rem; + padding: 0 1rem 1rem; + + pre { + background: transparent; + margin: 0; + padding: 0; + line-height: 1.75; + font-size: var(--font-size-sm); + } +} diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index 715984f6ca33..93918dac11c5 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -2030,10 +2030,14 @@ function AutoScroller(scrollContainer) { scrollToBottom: function () { var scrollDiv = this.scrollContainer; var currentHeight = this.getCurrentHeight(); - if (document.documentElement) { - document.documentElement.scrollTop = currentHeight; + + if (scrollDiv === document.body) { + window.scrollTo({ + top: currentHeight, + }); + } else { + scrollDiv.scrollTop = currentHeight; } - scrollDiv.scrollTop = currentHeight; }, }; } From ebb68318ca27be87816b84ada793ea8be109d60f Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sat, 4 Jan 2025 15:23:03 +0000 Subject: [PATCH 11/17] Lint --- core/src/main/resources/lib/hudson/progressive-text.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/resources/lib/hudson/progressive-text.js b/core/src/main/resources/lib/hudson/progressive-text.js index ede4d46eba6f..696a4d144c76 100644 --- a/core/src/main/resources/lib/hudson/progressive-text.js +++ b/core/src/main/resources/lib/hudson/progressive-text.js @@ -10,7 +10,9 @@ Behaviour.specify( let onFinishEvent = holder.getAttribute("data-on-finish-event"); let errorMessage = holder.getAttribute("data-error-message"); - var scroller = new AutoScroller(holder.closest(".progressive-text-container") || document.body); + var scroller = new AutoScroller( + holder.closest(".progressive-text-container") || document.body, + ); /* fetches the latest update from the server @param e From 76d4bb8ea93af11aa7080bf2df23169eb6545d88 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sun, 5 Jan 2025 11:01:47 +0000 Subject: [PATCH 12/17] Fix in case of null provider --- core/src/main/java/hudson/Functions.java | 18 ++++++++---------- .../resources/hudson/model/Run/index.jelly | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index 153ff4c56b2c..ea677293cb60 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -54,7 +54,6 @@ import hudson.model.ParameterDefinition; import hudson.model.ParameterDefinition.ParameterDescriptor; import hudson.model.PasswordParameterDefinition; -import hudson.model.Queue; import hudson.model.Run; import hudson.model.Slave; import hudson.model.TimeZoneProperty; @@ -144,6 +143,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.SortedMap; import java.util.TimeZone; @@ -159,6 +159,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import jenkins.console.ConsoleUrlProvider; +import jenkins.console.DefaultConsoleUrlProvider; import jenkins.console.WithConsoleUrl; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; @@ -1994,15 +1995,12 @@ public static String joinPath(String... components) { return consoleUrl != null ? Stapler.getCurrentRequest().getContextPath() + '/' + consoleUrl : null; } - public static @CheckForNull ConsoleUrlProvider getConsoleProvider(Queue.Executable executable) { - if (executable == null) { - return null; - } else if (executable instanceof Run) { - return ConsoleUrlProvider.getProvider((Run) executable); - } else { - // Handles cases such as PlaceholderExecutable for Pipeline node steps. - return getConsoleProvider(executable.getParentExecutable()); - } + /** + * @param run the run + * @return the Console Provider for the given run, if null, the default Console Provider + */ + public static ConsoleUrlProvider getConsoleProviderFor(Run run) { + return Optional.ofNullable(ConsoleUrlProvider.getProvider(run)).orElse(new DefaultConsoleUrlProvider()); } /** diff --git a/core/src/main/resources/hudson/model/Run/index.jelly b/core/src/main/resources/hudson/model/Run/index.jelly index c37b7108a428..ba7353955daa 100644 --- a/core/src/main/resources/hudson/model/Run/index.jelly +++ b/core/src/main/resources/hudson/model/Run/index.jelly @@ -45,7 +45,7 @@ THE SOFTWARE. - +
From a568323fa3376d0d476d46bef4f0df6a06c48bcb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:34:56 +0000 Subject: [PATCH 13/17] Update dependency io.jenkins.plugins:design-library to v350 --- test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pom.xml b/test/pom.xml index b659ea3d20b2..94300a30a37e 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -344,7 +344,7 @@ THE SOFTWARE. io.jenkins.plugins design-library - 342.v9b_fb_09074f21 + 350.v5a_69266b_2c7c hpi ${project.build.outputDirectory}/plugins design-library.jpi From 1cc9ec3edab9a274737731d6d721342e84c01173 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:31:35 +0000 Subject: [PATCH 14/17] Update eps1lon/actions-label-merge-conflict action to v3.0.3 --- .github/workflows/label-conflicting-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-conflicting-pr.yml b/.github/workflows/label-conflicting-pr.yml index 8b78edd6004c..9d36c4749c79 100644 --- a/.github/workflows/label-conflicting-pr.yml +++ b/.github/workflows/label-conflicting-pr.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Label conflicting PRs - uses: eps1lon/actions-label-merge-conflict@v3.0.2 + uses: eps1lon/actions-label-merge-conflict@v3.0.3 with: dirtyLabel: "unresolved-merge-conflict" repoToken: "${{ secrets.GITHUB_TOKEN }}" From 84177eb6b4bc032f7b8fd4d9b8285dc224ccd95f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 23:55:11 +0000 Subject: [PATCH 15/17] Update dependency commons-codec:commons-codec to v1.17.2 --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 8de2f4bc33ad..4689eb7504a2 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -119,7 +119,7 @@ THE SOFTWARE. commons-codec commons-codec - 1.17.1 + 1.17.2 commons-collections From 21bfc3819c2524da9d21e3d854c7e03ababe7c4e Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:25:03 +0000 Subject: [PATCH 16/17] New build page flag --- ...Flag.java => NewBuildPageUserExperimentalFlag.java} | 10 +++++----- core/src/main/resources/hudson/model/Run/index.jelly | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) rename core/src/main/java/jenkins/model/experimentalflags/{ConsoleWidgetUserExperimentalFlag.java => NewBuildPageUserExperimentalFlag.java} (83%) diff --git a/core/src/main/java/jenkins/model/experimentalflags/ConsoleWidgetUserExperimentalFlag.java b/core/src/main/java/jenkins/model/experimentalflags/NewBuildPageUserExperimentalFlag.java similarity index 83% rename from core/src/main/java/jenkins/model/experimentalflags/ConsoleWidgetUserExperimentalFlag.java rename to core/src/main/java/jenkins/model/experimentalflags/NewBuildPageUserExperimentalFlag.java index 15e8671b0d33..22f26213b8be 100644 --- a/core/src/main/java/jenkins/model/experimentalflags/ConsoleWidgetUserExperimentalFlag.java +++ b/core/src/main/java/jenkins/model/experimentalflags/NewBuildPageUserExperimentalFlag.java @@ -31,19 +31,19 @@ @Extension @Restricted(NoExternalUse.class) -public class ConsoleWidgetUserExperimentalFlag extends BooleanUserExperimentalFlag { - public ConsoleWidgetUserExperimentalFlag() { - super("console-widget.flag"); +public class NewBuildPageUserExperimentalFlag extends BooleanUserExperimentalFlag { + public NewBuildPageUserExperimentalFlag() { + super("new-build-page.flag"); } @Override public String getDisplayName() { - return "Show Console Output on build pages"; + return "New build page"; } @Nullable @Override public String getShortDescription() { - return "Shows the Console Output as a widget on build pages."; + return "Enables a revamped build page. This is a work in progress."; } } diff --git a/core/src/main/resources/hudson/model/Run/index.jelly b/core/src/main/resources/hudson/model/Run/index.jelly index ba7353955daa..29d8427d4f0b 100644 --- a/core/src/main/resources/hudson/model/Run/index.jelly +++ b/core/src/main/resources/hudson/model/Run/index.jelly @@ -43,8 +43,8 @@ THE SOFTWARE.
- - + + From ce0d0bc73f8aa4eec4d07dca80bea49771ae83a0 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:29:38 +0000 Subject: [PATCH 17/17] Use flag for the entire page --- .../NewBuildPageUserExperimentalFlag.java | 2 +- .../resources/hudson/model/Run/index.jelly | 92 ++++++++++--------- .../hudson/model/Run/new-build-page.jelly | 78 ++++++++++++++++ 3 files changed, 127 insertions(+), 45 deletions(-) create mode 100644 core/src/main/resources/hudson/model/Run/new-build-page.jelly diff --git a/core/src/main/java/jenkins/model/experimentalflags/NewBuildPageUserExperimentalFlag.java b/core/src/main/java/jenkins/model/experimentalflags/NewBuildPageUserExperimentalFlag.java index 22f26213b8be..cbe6e908cdc1 100644 --- a/core/src/main/java/jenkins/model/experimentalflags/NewBuildPageUserExperimentalFlag.java +++ b/core/src/main/java/jenkins/model/experimentalflags/NewBuildPageUserExperimentalFlag.java @@ -44,6 +44,6 @@ public String getDisplayName() { @Nullable @Override public String getShortDescription() { - return "Enables a revamped build page. This is a work in progress."; + return "Enables a revamped build page. This feature is still a work in progress, so some things might not work perfectly yet."; } } diff --git a/core/src/main/resources/hudson/model/Run/index.jelly b/core/src/main/resources/hudson/model/Run/index.jelly index 29d8427d4f0b..c358324918f2 100644 --- a/core/src/main/resources/hudson/model/Run/index.jelly +++ b/core/src/main/resources/hudson/model/Run/index.jelly @@ -25,58 +25,62 @@ THE SOFTWARE. - - + - - - - - - - - + + + + + + + - ${it.displayName} () + + + + + + + + -
- -
+ ${it.displayName} () - - - - +
+ +
-
-
- ${%startedAgo(it.timestampString)} -
-
- - ${%beingExecuted(it.executor.timestampString)} - - - ${%Took} ${it.durationString} - - -
-
+
+
+ ${%startedAgo(it.timestampString)} +
+
+ + ${%beingExecuted(it.executor.timestampString)} + + + ${%Took} ${it.durationString} + + +
+
- - +
+ - - - - + + + + - -
+ + - -
-
+ +
+
+ +
diff --git a/core/src/main/resources/hudson/model/Run/new-build-page.jelly b/core/src/main/resources/hudson/model/Run/new-build-page.jelly new file mode 100644 index 000000000000..cf1c270163e5 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/new-build-page.jelly @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + ${it.displayName} () + +
+ +
+ + + +
+
+ ${%startedAgo(it.timestampString)} +
+
+ + ${%beingExecuted(it.executor.timestampString)} + + + ${%Took} ${it.durationString} + + +
+
+ + + + + + + + + + +
+ + +
+
+