diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 04e2248e67003..30b72e988449f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -31,6 +31,7 @@ N/A - [ ] Changelog entries and upgrade guidelines are appropriate for the audience affected by the change (users or developer, depending on the change). [Examples](https://github.com/jenkins-infra/jenkins.io/blob/master/content/_data/changelogs/weekly.yml) * Fill-in the `Proposed changelog entries` section only if there are breaking changes or other changes which may require extra steps from users during the upgrade - [ ] Appropriate autotests or explanation to why this change has no tests +- [ ] New public classes, fields, and methods are annotated with `@Restricted` or have `@since TODO` Javadoc, as appropriate. - [ ] For dependency updates: links to external changelogs and, if possible, full diffs diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9cec7116807de..891d18c8a469f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -23,6 +23,9 @@ updates: - dependency-name: "javax.servlet.servlet-api" # needs a jakarta upgrade project, imports changed - dependency-name: "jakarta.servlet.jsp.jstl.jakarta.servlet.jsp.jstl-api" + # Starting with version 2.0.2, this library requires Java 11 + - dependency-name: "org.glassfish.tyrus.bundles:tyrus-standalone-client-jdk" + versions: [">=2.0.2"] # see https://github.com/jenkinsci/jenkins/pull/4224 can't be updated without breaking api - dependency-name: "org.jfree:jfreechart" # the dependency is actually provided by the Web container, hence it is aligned with Jetty. See https://github.com/jenkinsci/jenkins/pull/5211 diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 61333709c4951..255f98d3fb2b6 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -17,7 +17,7 @@ jobs: # Drafts your next Release notes as Pull Requests are merged into "master" - name: Generate GitHub Release Draft id: release-drafter - uses: release-drafter/release-drafter@v5.17.6 + uses: release-drafter/release-drafter@v5.18.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Generates a YAML changelog file using https://github.com/jenkinsci/jenkins-core-changelog-generator diff --git a/bom/pom.xml b/bom/pom.xml index 84d864182d726..35d5a93daa5c6 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -324,7 +324,7 @@ THE SOFTWARE. com.thoughtworks.xstream xstream - 1.4.18 + 1.4.19 net.sf.kxml diff --git a/core/pom.xml b/core/pom.xml index 28fbaaaf812bd..af1529aa61b06 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -41,7 +41,7 @@ THE SOFTWARE. true 2.2 - 2.8.4 + 2.9.0 diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index b4b24f858fd6c..c63e1f813a96e 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -255,7 +255,7 @@ public void run() { Files.deleteIfExists(BootFailure.getBootFailureFile(_home).toPath()); // at this point we are open for business and serving requests normally - LOGGER.info("Jenkins is fully up and running"); + Jenkins.get().getLifecycle().onReady(); success = true; } catch (Error e) { new HudsonFailedToLoad(e).publish(context, _home); @@ -322,14 +322,11 @@ public FileAndDescription(File file, String description) { /** * Determines the home directory for Jenkins. * - *

- * We look for a setting that affects the smallest scope first, then bigger ones later. + *

We look for a setting that affects the smallest scope first, then bigger ones later. * - *

- * People makes configuration mistakes, so we are trying to be nice + *

People make configuration mistakes, so we are trying to be nice * with those by doing {@link String#trim()}. * - *

* @return the File alongside with some description to help the user troubleshoot issues */ public FileAndDescription getHomeDir(ServletContextEvent event) { diff --git a/core/src/main/java/hudson/lifecycle/Lifecycle.java b/core/src/main/java/hudson/lifecycle/Lifecycle.java index 8e84179b5a0fb..92abad4cb6326 100644 --- a/core/src/main/java/hudson/lifecycle/Lifecycle.java +++ b/core/src/main/java/hudson/lifecycle/Lifecycle.java @@ -24,6 +24,8 @@ package hudson.lifecycle; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.Functions; import hudson.Util; @@ -32,6 +34,7 @@ import java.io.UncheckedIOException; import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; @@ -52,6 +55,19 @@ public abstract class Lifecycle implements ExtensionPoint { private static Lifecycle INSTANCE = null; + public Lifecycle() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + Jenkins jenkins = Jenkins.getInstanceOrNull(); + if (jenkins != null) { + try { + jenkins.cleanUp(); + } catch (Throwable t) { + LOGGER.log(Level.SEVERE, "Failed to clean up. Shutdown will continue.", t); + } + } + })); + } + /** * Gets the singleton instance. * @@ -107,6 +123,9 @@ public void verifyRestartable() throws RestartNotSupportedException { } else if (System.getenv("SMF_FMRI") != null && System.getenv("SMF_RESTARTER") != null) { // when we are run by Solaris SMF, these environment variables are set. instance = new SolarisSMFLifecycle(); + } else if (System.getenv("NOTIFY_SOCKET") != null) { + // When we are running under systemd with Type=notify, this environment variable is set. + instance = new SystemdLifecycle(); } else { // if run on Unix, we can do restart try { @@ -232,5 +251,74 @@ public boolean canRestart() { } } + /** + * Called when Jenkins startup is finished or when Jenkins has finished reloading its + * configuration. + * + * @since 2.333 + */ + public void onReady() { + LOGGER.log(Level.INFO, "Jenkins is fully up and running"); + } + + /** + * Called when Jenkins is reloading its configuration. + * + *

Callers must also send an {@link #onReady()} notification when Jenkins has finished + * reloading its configuration. + * + * @since 2.333 + */ + public void onReload(@NonNull String user, @CheckForNull String remoteAddr) { + if (remoteAddr != null) { + LOGGER.log( + Level.INFO, + "Reloading Jenkins as requested by {0} from {1}", + new Object[] {user, remoteAddr}); + } else { + LOGGER.log(Level.INFO, "Reloading Jenkins as requested by {0}", user); + } + } + + /** + * Called when Jenkins is beginning its shutdown. + * + * @since 2.333 + */ + public void onStop(@NonNull String user, @CheckForNull String remoteAddr) { + if (remoteAddr != null) { + LOGGER.log( + Level.INFO, + "Stopping Jenkins as requested by {0} from {1}", + new Object[] {user, remoteAddr}); + } else { + LOGGER.log(Level.INFO, "Stopping Jenkins as requested by {0}", user); + } + } + + /** + * Tell the service manager to extend the startup or shutdown timeout. The value specified is a + * time during which either {@link #onExtendTimeout(long, TimeUnit)} must be called again or + * startup/shutdown must complete. + * + * @param timeout The amount by which to extend the timeout. + * @param unit The time unit of the timeout argument. + * + * @since TODO + */ + public void onExtendTimeout(long timeout, @NonNull TimeUnit unit) {} + + /** + * Called when Jenkins service state has changed. + * + * @param status The status string. This is free-form and can be used for various purposes: + * general state feedback, completion percentages, human-readable error message, etc. + * + * @since 2.333 + */ + public void onStatusUpdate(String status) { + LOGGER.log(Level.INFO, status); + } + private static final Logger LOGGER = Logger.getLogger(Lifecycle.class.getName()); } diff --git a/core/src/main/java/hudson/lifecycle/SystemdLifecycle.java b/core/src/main/java/hudson/lifecycle/SystemdLifecycle.java new file mode 100644 index 0000000000000..31afd55ccf60a --- /dev/null +++ b/core/src/main/java/hudson/lifecycle/SystemdLifecycle.java @@ -0,0 +1,69 @@ +package hudson.lifecycle; + +import com.sun.jna.LastErrorException; +import com.sun.jna.Library; +import com.sun.jna.Native; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * {@link Lifecycle} that delegates its responsibility to {@code systemd(1)}. + * + * @author Basil Crow + */ +@Restricted(NoExternalUse.class) +@Extension(optional = true) +public class SystemdLifecycle extends ExitLifecycle { + + private static final Logger LOGGER = Logger.getLogger(SystemdLifecycle.class.getName()); + + interface Systemd extends Library { + Systemd INSTANCE = Native.load("systemd", Systemd.class); + + int sd_notify(int unset_environment, String state) throws LastErrorException; + } + + @Override + public void onReady() { + super.onReady(); + notify("READY=1"); + } + + @Override + public void onReload(@NonNull String user, @CheckForNull String remoteAddr) { + super.onReload(user, remoteAddr); + notify("RELOADING=1"); + } + + @Override + public void onStop(@NonNull String user, @CheckForNull String remoteAddr) { + super.onStop(user, remoteAddr); + notify("STOPPING=1"); + } + + @Override + public void onExtendTimeout(long timeout, @NonNull TimeUnit unit) { + super.onExtendTimeout(timeout, unit); + notify(String.format("EXTEND_TIMEOUT_USEC=%d", unit.toMicros(timeout))); + } + + @Override + public void onStatusUpdate(String status) { + super.onStatusUpdate(status); + notify(String.format("STATUS=%s", status)); + } + + private static synchronized void notify(String message) { + try { + Systemd.INSTANCE.sd_notify(0, message); + } catch (LastErrorException e) { + LOGGER.log(Level.WARNING, null, e); + } + } +} diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index 458718e89aff7..c60530639cbfe 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -527,9 +527,6 @@ public void onLoad(ItemGroup parent, String name) throws IOExcep * then it will be loaded, then this method will be invoked * to perform any implementation-specific work. * - *

- * - * * @param src * Item from which it's copied from. The same type as {@code this}. Never null. */ diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index e0abed68ccd5e..50ad97232bd5a 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -1919,9 +1919,8 @@ default CauseOfBlockage getCauseOfBlockage() { * amongst all the free executors on all possibly suitable nodes. * NOTE: To be able to re-use the same node during the next run this key should not change from one run to * another. You probably want to compute that key based on the job's name. - *

- * @return by default: {@link #getFullDisplayName()} * + * @return by default: {@link #getFullDisplayName()} * @see hudson.model.LoadBalancer */ default String getAffinityKey() { return getFullDisplayName(); } diff --git a/core/src/main/java/hudson/scheduler/Hash.java b/core/src/main/java/hudson/scheduler/Hash.java index eb69cfda04fb5..86520ed87faae 100644 --- a/core/src/main/java/hudson/scheduler/Hash.java +++ b/core/src/main/java/hudson/scheduler/Hash.java @@ -33,16 +33,12 @@ /** * Generates a pseudo-random sequence of integers in the specified range. * - *

- * {@link CronTab} supports tokens like '@daily', which means "do it once a day". + *

{@link CronTab} supports tokens like '@daily', which means "do it once a day". * Exactly which time of the day this gets scheduled is randomized --- randomized * in the sense that it's spread out when many jobs choose @daily, but it's at * the same time stable so that every job sticks to a specific time of the day * even after the configuration is updated. * - *

- * - * * @author Kohsuke Kawaguchi * @since 1.448 */ diff --git a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java index 924c77e25cd5b..dd29dc3004fea 100644 --- a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java +++ b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java @@ -67,7 +67,7 @@ * This causes the container to perform authentication, but there's no way * to find out whether the user has been successfully authenticated or not. * So to find this out, we then redirect the user to - * {@link jenkins.model.Jenkins#doSecured(StaplerRequest, StaplerResponse) {@code /secured/...} page}. + * {@link jenkins.model.Jenkins#doSecured(StaplerRequest, StaplerResponse) /secured/... page}. * *

* The handler of the above URL checks if the user is authenticated, diff --git a/core/src/main/java/hudson/util/LogTaskListener.java b/core/src/main/java/hudson/util/LogTaskListener.java index 7d696ada46323..267f8f7bf27fc 100644 --- a/core/src/main/java/hudson/util/LogTaskListener.java +++ b/core/src/main/java/hudson/util/LogTaskListener.java @@ -37,12 +37,10 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; -// TODO: AbstractTaskListener is empty now, but there are dependencies on that e.g. Ruby Runtime - JENKINS-48116) -// The change needs API deprecation policy or external usages cleanup. - /** * {@link TaskListener} which sends messages to a {@link Logger}. */ +@SuppressWarnings("deprecation") // to preserve serial form public class LogTaskListener extends AbstractTaskListener implements TaskListener, Closeable { // would be simpler to delegate to the LogOutputStream but this would incompatibly change the serial form diff --git a/core/src/main/java/hudson/util/StreamTaskListener.java b/core/src/main/java/hudson/util/StreamTaskListener.java index 8aad40f5b5999..f19db94b45cd4 100644 --- a/core/src/main/java/hudson/util/StreamTaskListener.java +++ b/core/src/main/java/hudson/util/StreamTaskListener.java @@ -48,9 +48,6 @@ import jenkins.util.SystemProperties; import org.kohsuke.stapler.framework.io.WriterOutputStream; -// TODO: AbstractTaskListener is empty now, but there are dependencies on that e.g. Ruby Runtime - JENKINS-48116) -// The change needs API deprecation policy or external usages cleanup. - /** * {@link TaskListener} that generates output into a single stream. * @@ -59,6 +56,7 @@ * * @author Kohsuke Kawaguchi */ +@SuppressWarnings("deprecation") // to preserve serial form public class StreamTaskListener extends AbstractTaskListener implements TaskListener, Closeable { @NonNull private PrintStream out; diff --git a/core/src/main/java/hudson/util/XStream2.java b/core/src/main/java/hudson/util/XStream2.java index 2ac02f6062b6e..204fd0e39d851 100644 --- a/core/src/main/java/hudson/util/XStream2.java +++ b/core/src/main/java/hudson/util/XStream2.java @@ -81,7 +81,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; import jenkins.model.Jenkins; import jenkins.util.xstream.SafeURLConverter; @@ -570,18 +569,12 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext co throw new ConversionException("Refusing to unmarshal " + reader.getNodeName() + " for security reasons; see https://www.jenkins.io/redirect/class-filter/"); } - /** TODO see comment in {@code whitelisted-classes.txt} */ - private static final Pattern JRUBY_PROXY = Pattern.compile("org[.]jruby[.]proxy[.].+[$]Proxy\\d+"); - @Override public boolean canConvert(Class type) { if (type == null) { return false; } String name = type.getName(); - if (JRUBY_PROXY.matcher(name).matches()) { - return false; - } // claim we can convert all the scary stuff so we can throw exceptions when attempting to do so return ClassFilter.DEFAULT.isBlacklisted(name) || ClassFilter.DEFAULT.isBlacklisted(type); } diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index a9323a48bf700..5e6b074be66cb 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -1181,6 +1181,7 @@ private boolean containsLinkageError(Throwable x) { @Override protected void onInitMilestoneAttained(InitMilestone milestone) { initLevel = milestone; + getLifecycle().onExtendTimeout(EXTEND_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (milestone == PLUGINS_PREPARED) { // set up Guice to enable injection as early as possible // before this milestone, ExtensionList.ensureLoaded() won't actually try to locate instances @@ -2268,7 +2269,7 @@ private void trimLabels(@CheckForNull Set includedLabels) { this.getNodes().forEach(n -> nodeLabels.addAll(n.getAssignedLabels())); for (Iterator

Path Names

- *

- * If the name starts from '/', like "/foo/bar/zot", then it's interpreted as absolute. + * + *

If the name starts from '/', like "/foo/bar/zot", then it's interpreted as absolute. * Otherwise, the name should be something like "foo/bar" and it's interpreted like * relative path name in the file system is, against the given context. + * *

For compatibility, as a fallback when nothing else matches, a simple path * like {@code foo/bar} can also be treated with {@link #getItemByFullName}. + * * @param context * null is interpreted as {@link Jenkins}. Base 'directory' of the interpretation. * @since 1.406 @@ -3564,7 +3567,7 @@ public void cleanUp() { cleanUpStarted = true; } try { - LOGGER.log(Level.INFO, "Stopping Jenkins"); + getLifecycle().onStatusUpdate("Stopping Jenkins"); final List errors = new ArrayList<>(); @@ -3596,7 +3599,7 @@ public void cleanUp() { _cleanUpReleaseAllLoggers(errors); - LOGGER.log(Level.INFO, "Jenkins stopped"); + getLifecycle().onStatusUpdate("Jenkins stopped"); if (!errors.isEmpty()) { StringBuilder message = new StringBuilder("Unexpected issues encountered during cleanUp: "); @@ -4306,7 +4309,7 @@ public Slave.JnlpJar doJnlpJars(StaplerRequest req) { @RequirePOST public synchronized HttpResponse doReload() throws IOException { checkPermission(MANAGE); - LOGGER.log(Level.WARNING, "Reloading Jenkins as requested by {0}", getAuthentication2().getName()); + getLifecycle().onReload(getAuthentication2().getName(), null); // engage "loading ..." UI and then run the actual task in a separate thread WebApp.get(servletContext).setApp(new HudsonIsLoading()); @@ -4316,6 +4319,7 @@ public synchronized HttpResponse doReload() throws IOException { public void run() { try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { reload(); + getLifecycle().onReady(); } catch (Exception e) { LOGGER.log(SEVERE, "Failed to reload Jenkins config", e); new JenkinsReloadFailed(e).publish(servletContext, root); @@ -4503,8 +4507,9 @@ public void restart() throws RestartNotSupportedException { public void run() { try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { // give some time for the browser to load the "reloading" page + lifecycle.onStatusUpdate("Restart in 5 seconds"); Thread.sleep(TimeUnit.SECONDS.toMillis(5)); - LOGGER.info(String.format("Restarting VM as requested by %s", exitUser)); + lifecycle.onStop(exitUser, null); Listeners.notify(RestartListener.class, true, RestartListener::onRestart); lifecycle.restart(); } catch (InterruptedException | InterruptedIOException e) { @@ -4539,13 +4544,13 @@ public void run() { if (isQuietingDown()) { servletContext.setAttribute("app", new HudsonIsRestarting()); // give some time for the browser to load the "reloading" page - LOGGER.info("Restart in 10 seconds"); + lifecycle.onStatusUpdate("Restart in 10 seconds"); Thread.sleep(TimeUnit.SECONDS.toMillis(10)); - LOGGER.info(String.format("Restarting VM as requested by %s", exitUser)); + lifecycle.onStop(exitUser, null); Listeners.notify(RestartListener.class, true, RestartListener::onRestart); lifecycle.restart(); } else { - LOGGER.info("Safe-restart mode cancelled"); + lifecycle.onStatusUpdate("Safe-restart mode cancelled"); } } catch (Throwable e) { LOGGER.log(Level.WARNING, "Failed to restart Jenkins", e); @@ -4585,6 +4590,8 @@ protected RestartCause() { @RequirePOST public void doExit(StaplerRequest req, StaplerResponse rsp) throws IOException { checkPermission(ADMINISTER); + final String exitUser = getAuthentication2().getName(); + final String exitAddr = req != null ? req.getRemoteAddr() : null; if (rsp != null) { rsp.setStatus(HttpServletResponse.SC_OK); rsp.setContentType("text/plain"); @@ -4598,8 +4605,7 @@ public void doExit(StaplerRequest req, StaplerResponse rsp) throws IOException { @SuppressFBWarnings(value = "DM_EXIT", justification = "Exit is really intended.") public void run() { try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { - LOGGER.info(String.format("Shutting down VM as requested by %s from %s", - getAuthentication2().getName(), req != null ? req.getRemoteAddr() : "???")); + getLifecycle().onStop(exitUser, exitAddr); cleanUp(); System.exit(0); @@ -4620,14 +4626,13 @@ public HttpResponse doSafeExit(StaplerRequest req) throws IOException { checkPermission(ADMINISTER); quietDownInfo = new QuietDownInfo(); final String exitUser = getAuthentication2().getName(); - final String exitAddr = req != null ? req.getRemoteAddr() : "unknown"; + final String exitAddr = req != null ? req.getRemoteAddr() : null; new Thread("safe-exit thread") { @Override @SuppressFBWarnings(value = "DM_EXIT", justification = "Exit is really intended.") public void run() { try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { - LOGGER.info(String.format("Shutting down VM as requested by %s from %s", - exitUser, exitAddr)); + getLifecycle().onStop(exitUser, exitAddr); // Wait 'til we have no active executors. doQuietDown(true, 0, null); // Make sure isQuietingDown is still true. @@ -5517,6 +5522,12 @@ public boolean shouldShowStackTrace() { @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static boolean AUTOMATIC_AGENT_LAUNCH = SystemProperties.getBoolean(Jenkins.class.getName() + ".automaticAgentLaunch", true); + /** + * The amount of time by which to extend the startup notification timeout as each initialization milestone is attained. + */ + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") + public static /* not final */ int EXTEND_TIMEOUT_SECONDS = SystemProperties.getInteger(Jenkins.class.getName() + ".extendTimeoutSeconds", 15); + private static final Logger LOGGER = Logger.getLogger(Jenkins.class.getName()); private static final SecureRandom RANDOM = new SecureRandom(); diff --git a/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java b/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java index afa608fce5dee..c601ffc77d69b 100644 --- a/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java +++ b/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java @@ -460,9 +460,6 @@ public boolean runExists(int number) { /** * Finds the build #M where M is nearby the given 'n'. * - *

- * - * * @param n * the index to start the search from * @param d diff --git a/core/src/main/java/jenkins/util/Listeners.java b/core/src/main/java/jenkins/util/Listeners.java index 4d85c6c5cd8fa..9cc0489cc94eb 100644 --- a/core/src/main/java/jenkins/util/Listeners.java +++ b/core/src/main/java/jenkins/util/Listeners.java @@ -71,14 +71,6 @@ public static void notify(Class listenerType, boolean asSystem, Consumer< } } - /** - * @deprecated call {@link #notify(Class, boolean, Consumer)} - */ - @Deprecated - public static void notify(Class listenerType, Consumer notification) { - notify(listenerType, true, notification); - } - private Listeners() {} } diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly b/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly index f72787a64fa2c..30238f1fb53b8 100644 --- a/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly @@ -63,7 +63,7 @@ THE SOFTWARE.

diff --git a/core/src/main/resources/hudson/model/Api/index.jelly b/core/src/main/resources/hudson/model/Api/index.jelly index b927eafb513d6..cc208c986d7dd 100644 --- a/core/src/main/resources/hudson/model/Api/index.jelly +++ b/core/src/main/resources/hudson/model/Api/index.jelly @@ -84,18 +84,6 @@ THE SOFTWARE. ast.literal_eval(urllib.urlopen("...").read())

- -

diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/people-resources.js b/core/src/main/resources/hudson/model/View/AsynchPeople/people-resources.js index 3a90ccf9d7eb7..880d302694f3c 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/people-resources.js +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/people-resources.js @@ -27,15 +27,13 @@ function display(data) { d = document.createElement('td'); var a = document.createElement('a'); a.href = rootURL + "/" + e.url; + a.className = "jenkins-table__link" a.appendChild(document.createTextNode(e.id)); d.appendChild(a); r.appendChild(d); d = document.createElement('td'); - var a = document.createElement('a'); - a.href = rootURL + "/" + e.url; - a.appendChild(document.createTextNode(e.fullName)); - d.appendChild(a); + d.appendChild(document.createTextNode(e.fullName)); r.appendChild(d); d = document.createElement('td'); @@ -55,4 +53,4 @@ function display(data) { ts_refresh(p); } -} \ No newline at end of file +} diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly index 863035f7cb83b..c2bb1da166b38 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly @@ -34,7 +34,7 @@ THE SOFTWARE. -

${%blurb}

+

${%blurb}

@@ -49,18 +49,16 @@ THE SOFTWARE. -
+
- - - +
- ${user.id} + ${user.id} - ${user.fullName} + ${user.fullName}
diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly b/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly index 19fbbd1e8eec5..7da40bad1859d 100644 --- a/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/columnHeader.jelly @@ -23,5 +23,5 @@ THE SOFTWARE. --> -
- \ No newline at end of file + + diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties index 699b262351b62..0e629cbd23ab0 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_ko.properties @@ -20,21 +20,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blue=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD568. -blue_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD568. \uC2E0\uADDC \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784. -grey=\uD504\uB85C\uC81D\uD2B8\uAC00 \uBE4C\uB4DC\uB41C \uC801\uC774 \uC5C6\uAC70\uB098, \uC0AC\uC6A9\uBD88\uAC00\uC784. -grey_anime=\uD504\uB85C\uC81D\uD2B8\uC758 \uCD5C\uCD08 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784. -health-00to19=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 20% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-00to20=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uC774\uD558\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-20to39=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 20% \uC774\uC0C1 40% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-21to40=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uCD08\uACFC 40% \uC774\uD558\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-40to59=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 40% \uC774\uC0C1 60% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-41to60=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 40% \uCD08\uACFC 60% \uC774\uD558\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-60to79=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 60% \uC774\uC0C1 80% \uBBF8\uB9CC \uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-61to80=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 60% \uCD08\uACFC\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -health-80plus=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 \uC801\uC5B4\uB3C4 80%\uC784. \uC880 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uC704\uD574\uC11C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58 \uC704\uC5D0 \uB9C8\uC6B0\uC2A4\uB97C \uC704\uCE58\uC2DC\uD0AC \uC218 \uC788\uC74C -health-81plus=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 28% \uCD08\uACFC\uC784. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. -red=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2EC\uAC01\uD558\uAC8C \uC2E4\uD328\uD568. -red_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2EC\uAC01\uD558\uAC8C \uC2E4\uD328\uD568. \uC2E0\uADDC \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784. -yellow=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD568. \uC8FC\uB85C \uB0A8\uC544\uC788\uB358 \uAC80\uC99D \uC2E4\uD328\uB97C \uC0AC\uC6A9\uD55C \uAC83\uC784. -yellow_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD568. \uC2E0\uADDC \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC784 +lightgrey=\uD504\uB85C\uC81D\uD2B8\uAC00 \uBE4C\uB4DC\uB41C \uC801\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. +lightgrey_anime=\uD504\uB85C\uC81D\uD2B8\uC758 \uCD5C\uCD08 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +grey=\uD504\uB85C\uC81D\uD2B8\uAC00 \uBE4C\uB4DC\uB41C \uC801\uC774 \uC5C6\uAC70\uB098, \uBE44\uD65C\uC131 \uC0C1\uD0DC\uC785\uB2C8\uB2E4. +grey_anime=\uD504\uB85C\uC81D\uD2B8\uC758 \uCD5C\uCD08 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +darkgrey=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. +darkgrey_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +blue=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC2B5\uB2C8\uB2E4. +blue_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +yellow=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD569\uB2C8\uB2E4. \uC774\uAC83\uC740 \uC8FC\uB85C \uD14C\uC2A4\uD2B8 \uC2E4\uD328\uB97C \uB098\uD0C0\uB0B4\uB294 \uB370 \uC0AC\uC6A9\uB429\uB2C8\uB2E4. +yellow_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uC9C0\uB9CC \uBD88\uC548\uC815\uD569\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +red=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. +red_anime=\uB9C8\uC9C0\uB9C9 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4. +health-81plus=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 80% \uCD08\uACFC\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-61to80=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 60% \uCD08\uACFC 80% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-41to60=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 40% \uCD08\uACFC 60% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-21to40=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uCD08\uACFC 40% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. +health-00to20=\uD504\uB85C\uC81D\uD2B8 \uAC74\uAC15\uC0C1\uD0DC\uAC00 20% \uC774\uD558\uC785\uB2C8\uB2E4. \uB9C8\uC6B0\uC2A4\uB97C \uD504\uB85C\uC81D\uD2B8 \uC544\uC774\uCF58\uC5D0 \uC62C\uB824\uB193\uC73C\uBA74 \uB354 \uC790\uC138\uD55C \uC124\uBA85\uC744 \uBCFC \uC218 \uC788\uC2B5\uB2C8\uB2E4. diff --git a/core/src/main/resources/jenkins/security/whitelisted-classes.txt b/core/src/main/resources/jenkins/security/whitelisted-classes.txt index b7d4049406287..fbcdc1a9de017 100644 --- a/core/src/main/resources/jenkins/security/whitelisted-classes.txt +++ b/core/src/main/resources/jenkins/security/whitelisted-classes.txt @@ -135,34 +135,10 @@ org.apache.commons.fileupload.disk.DiskFileItem org.apache.commons.fileupload.util.FileItemHeadersImpl org.apache.tools.ant.Location -# TODO see main ruby-runtime section below -org.jenkinsci.jruby.JRubyMapper$DynamicProxy - # TODO remove when https://github.com/jenkinsci/xtrigger-lib/pull/9 is widely adopted in fstrigger-plugin, urltrigger-plugin, etc. org.jenkinsci.lib.xtrigger.XTriggerCause org.jenkinsci.lib.xtrigger.XTriggerCauseAction -# TODO remove (also XStream2.BlacklistedTypesConverter.JRUBY_PROXY) when Ruby Runtime is fixed -# Related PRs: -# - https://github.com/jenkinsci/ruby-runtime-plugin/pull/5, -# - https://github.com/jenkinsci/ruby-runtime-plugin/pull/6 -# -# oleg-nenashev in PR#6 we are trying to get help from last maintainers due to the plugin codebase splitbrain. -# It is required to fix JENKINS-50616 in a proper way for 2.107.x -org.jruby.RubyArray -org.jruby.RubyBignum -org.jruby.RubyBoolean -org.jruby.RubyBoolean$False -org.jruby.RubyBoolean$True -org.jruby.RubyFixnum -org.jruby.RubyHash -org.jruby.RubyNil -org.jruby.RubyObject -org.jruby.RubyString -org.jruby.RubySymbol -org.jruby.java.proxies.ConcreteJavaProxy -org.jruby.runtime.builtin.IRubyObject - org.jvnet.hudson.MemoryUsage org.jvnet.localizer.Localizable org.jvnet.localizer.ResourceBundleHolder diff --git a/core/src/main/resources/lib/hudson/buildCaption.jelly b/core/src/main/resources/lib/hudson/buildCaption.jelly index 94de09be0ee8e..c3e0c400d0454 100644 --- a/core/src/main/resources/lib/hudson/buildCaption.jelly +++ b/core/src/main/resources/lib/hudson/buildCaption.jelly @@ -33,7 +33,7 @@ THE SOFTWARE. -
+
diff --git a/core/src/main/resources/lib/hudson/projectViewRow.jelly b/core/src/main/resources/lib/hudson/projectViewRow.jelly index 0e623b850d1aa..f264e3fa00785 100644 --- a/core/src/main/resources/lib/hudson/projectViewRow.jelly +++ b/core/src/main/resources/lib/hudson/projectViewRow.jelly @@ -34,8 +34,5 @@ THE SOFTWARE. - diff --git a/pom.xml b/pom.xml index deb6ea5bbdc0e..a05581a8fd23a 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ THE SOFTWARE. - 2.333 + 2.334 -SNAPSHOT - + - \ No newline at end of file + diff --git a/war/pom.xml b/war/pom.xml index e0c5d5f6e171a..034f1e06c29ae 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -258,13 +258,13 @@ THE SOFTWARE. org.jenkins-ci.plugins display-url-api - 2.3.1 + 2.3.4 hpi org.jenkins-ci.plugins mailer - 1.32.1 + 408.vd726a_1130320 hpi @@ -288,7 +288,7 @@ THE SOFTWARE. org.jenkins-ci.plugins matrix-project - 1.18 + 1.20 hpi @@ -300,7 +300,7 @@ THE SOFTWARE. org.jenkins-ci.plugins junit - 1.29 + 1.47 hpi @@ -310,6 +310,82 @@ THE SOFTWARE. 2.42 hpi + + + io.jenkins.plugins + plugin-util-api + 1.5.0 + hpi + + + + io.jenkins.plugins + bootstrap4-api + 4.5.3-1 + hpi + + + + io.jenkins.plugins + checks-api + 1.1.1 + hpi + + + + org.jenkins-ci.plugins + jackson2-api + 2.12.0 + hpi + + + + io.jenkins.plugins + echarts-api + 4.9.0-2 + hpi + + + + + io.jenkins.plugins + snakeyaml-api + 1.27.0 + hpi + + + + + io.jenkins.plugins + jquery3-api + 3.5.1-2 + hpi + + + + + org.jenkins-ci.plugins + jackson2-api + 2.12.0 + hpi + + + + + io.jenkins.plugins + popper-api + 1.16.0-7 + hpi + + + + + io.jenkins.plugins + font-awesome-api + 5.15.1-1 + hpi + + org.jenkins-ci.plugins.workflow diff --git a/war/src/main/js/sortable-drag-drop.js b/war/src/main/js/sortable-drag-drop.js index 84217f3ce2382..4130af451f915 100644 --- a/war/src/main/js/sortable-drag-drop.js +++ b/war/src/main/js/sortable-drag-drop.js @@ -23,6 +23,14 @@ function registerSortableDragDrop(e) { forceFallback: true, // Do not use html5 drag & drop behaviour because it does not work with autoscroll scroll: true, bubbleScroll: true, + onChoose: function (event) { + const draggableDiv = event.item; + const height = draggableDiv.clientHeight; + draggableDiv.style.height = `${height}px`; + }, + onUnchoose: function (event) { + event.item.style.removeProperty('height'); + } }); } diff --git a/war/src/main/less/abstracts/theme.less b/war/src/main/less/abstracts/theme.less index ebfe268255817..ac24f307c49cf 100644 --- a/war/src/main/less/abstracts/theme.less +++ b/war/src/main/less/abstracts/theme.less @@ -21,9 +21,9 @@ // branding --primary: #024cb6; --secondary: #4d545d; - --success: #138347; - --danger: #cc0003; - --warning: #ea6b19; + --success: var(--green); + --danger: var(--red); + --warning: var(--orange); --focus: #3fb3f7; --focus-btn-primary: fade(#0b6aa2, 50%); --focus-btn-secondary: fade(#0b6aa2, 50%); @@ -174,7 +174,7 @@ --table-body-background: white; --table-body-foreground: black; --table-border-radius: 10px; - --table-body-radius: 6px; + --table-row-border-radius: 4px; // Deprecated --even-row-color: var(--very-light-grey); diff --git a/war/src/main/less/base/layout-commons.less b/war/src/main/less/base/layout-commons.less index fd85351bf5834..008b1c4b2a096 100644 --- a/war/src/main/less/base/layout-commons.less +++ b/war/src/main/less/base/layout-commons.less @@ -127,10 +127,13 @@ body.full-screen #main-panel { h1.build-caption.page-headline { display: flex; align-items: center; - max-width: 1200px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; +} + +h1.build-caption.page-headline > span { + max-width: 1200px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } // Clearfixes extracted from responsive-grid.css as they essential diff --git a/war/src/main/less/base/style.less b/war/src/main/less/base/style.less index 6f832502b5c62..3e351db890d8b 100644 --- a/war/src/main/less/base/style.less +++ b/war/src/main/less/base/style.less @@ -724,6 +724,12 @@ table.parameters > tbody:hover { border-radius: 0; min-width: 450px; margin-bottom: 5px; + box-sizing: content-box; + padding-bottom: 2px; + + * { + box-sizing: border-box; + } } } diff --git a/war/src/main/less/modules/draggable-card.less b/war/src/main/less/modules/draggable-card.less index 5ff558111c67c..68ef14c86a1ea 100644 --- a/war/src/main/less/modules/draggable-card.less +++ b/war/src/main/less/modules/draggable-card.less @@ -46,6 +46,11 @@ div.to-be-removed { display: none; } /* ========================= D&D support in heterogenous/repeatable lists = */ +.hetero-list-container.with-drag-drop .repeated-chunk, +.repeated-container.with-drag-drop .repeated-chunk { + margin-bottom: 1rem; +} + // SortableJS drag & drop classes .repeated-chunk--sortable-ghost { height: 100px; diff --git a/war/src/main/less/modules/table.less b/war/src/main/less/modules/table.less index 803023fdc95d5..9804595a3ab29 100644 --- a/war/src/main/less/modules/table.less +++ b/war/src/main/less/modules/table.less @@ -1,12 +1,13 @@ .jenkins-table { + --table-padding: 0.55rem; + width: calc(100% - 10px); background: var(--table-background); - border-collapse: collapse; - border-radius: 6px; - overflow: hidden; - box-shadow: 0 0 0 5px var(--table-background); - margin: 5px 5px calc(var(--section-padding) + 5px); - --table-padding: 0.55rem; + border-radius: calc(var(--table-border-radius) + 2px); + border: 5px solid var(--table-background); + border-bottom-width: 3px; + border-spacing: 0 2px; + margin-bottom: var(--section-padding); * { -webkit-border-horizontal-spacing: 0; @@ -52,7 +53,6 @@ & > tr { background: var(--table-body-background); color: var(--table-body-foreground); - border-bottom: 2px solid var(--table-background); & > td { vertical-align: middle; @@ -61,36 +61,43 @@ height: 50px; &:first-of-type { - border-radius: var(--table-body-radius) 0 0 var(--table-body-radius); padding-left: calc(var(--table-padding) * 2); } &:last-of-type { - border-radius: 0 var(--table-body-radius) var(--table-body-radius) 0; padding-right: var(--table-padding); } } - &:last-of-type { - border-bottom: none; - } - } - - & > tr:first-of-type { + // Style the rows so that the first and last have a larger border radius & > td:first-of-type { - border-radius: var(--table-border-radius) 0 0 var(--table-body-radius); + border-top-left-radius: var(--table-row-border-radius); + border-bottom-left-radius: var(--table-row-border-radius); } + & > td:last-of-type { - border-radius: 0 var(--table-border-radius) var(--table-body-radius) 0; + border-top-right-radius: var(--table-row-border-radius); + border-bottom-right-radius: var(--table-row-border-radius); } - } - & > tr:last-of-type { - & > td:first-of-type { - border-radius: var(--table-body-radius) 0 0 var(--table-border-radius); + // First row + &:first-of-type { + & > td:first-of-type { + border-top-left-radius: var(--table-border-radius); + } + & > td:last-of-type { + border-top-right-radius: var(--table-border-radius); + } } - & > td:last-of-type { - border-radius: 0 var(--table-body-radius) var(--table-border-radius) 0; + + // Last row + &:last-of-type { + & > td:first-of-type { + border-bottom-left-radius: var(--table-border-radius); + } + & > td:last-of-type { + border-bottom-right-radius: var(--table-border-radius); + } } } } @@ -102,10 +109,10 @@ } &__cell--tight { - padding-left: 0!important; - text-align: center!important; + padding-left: 0 !important; + text-align: center !important; white-space: nowrap; - width: 60px; + width: 3.5rem; } &__cell--no-wrap { @@ -120,15 +127,15 @@ display: inline-flex; } - &__button, &__link, &__icon { + &__button, &__icon { svg, .build-status-icon__wrapper, img { - width: 24px!important; - height: 24px!important; + width: 24px !important; + height: 24px !important; } } &--medium { - --table-padding: 0.4rem!important; + --table-padding: 0.4rem !important; tbody > tr > td { height: 40px; @@ -136,8 +143,8 @@ .jenkins-table__button, .jenkins-table__link, .jenkins-table__icon { svg, .build-status-icon__wrapper, img { - width: 20px!important; - height: 20px!important; + width: 20px !important; + height: 20px !important; } } } @@ -151,14 +158,14 @@ .jenkins-table__button, .jenkins-table__link, .jenkins-table__icon { svg, .build-status-icon__wrapper, img { - width: 16px!important; - height: 16px!important; + width: 16px !important; + height: 16px !important; } } } &__button, &__link { - color: var(--link-color)!important; + color: var(--link-color) !important; } &__button, .sortheader, &__link { @@ -176,54 +183,68 @@ font-weight: inherit; font-size: inherit; background: transparent; - text-decoration: none!important; - line-height: 1!important; + text-decoration: none !important; + line-height: 1 !important; + transition: var(--standard-transition); - &::before { + &::before, + &::after { content: ""; position: absolute; top: -7px; left: -10px; bottom: -7px; right: -10px; - border-radius: 5px; - background: var(--text-color); + border-radius: 6px; z-index: -1; + transition: var(--standard-transition); + } + + &::before { + background: var(--text-color); opacity: 0; - transition: 0.2s ease; + } + + &::after { + opacity: 0.05; + box-shadow: 0 0 0 10px transparent; } &:hover { &::before { - opacity: 0.05!important; - border-radius: 5px; + opacity: 0.05 !important; + border-radius: 6px; background: var(--text-color); } } &:focus, &:active { &::before { - opacity: 0.1!important; + opacity: 0.1 !important; border-radius: 5px; background: var(--text-color); } + + &::after { + box-shadow: 0 0 0 5px var(--text-color); + } } &--green { - color: var(--green)!important; + color: var(--green) !important; } &--orange { - color: var(--orange)!important; + color: var(--orange) !important; } &--red { - color: var(--red)!important; + color: var(--red) !important; } } &__badge { - margin-left: 1rem!important; + margin-left: 1rem !important; &::before { top: -5px; @@ -234,5 +255,12 @@ background: var(--link-color); opacity: 0.05; } + + &::after { + top: -5px; + left: -8px; + bottom: -5px; + right: -8px; + } } } diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index f454f396daf0e..e2f0cb86c17a7 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -1796,7 +1796,7 @@ function expandTextArea(button,id) { parent.innerHTML = ""; var textArea = parent.childNodes[0]; textArea.name = field.name; - textArea.innerText = value; + textArea.value = value; layoutUpdateCallback.call(); }
${%Progress}: diff --git a/core/src/main/resources/lib/hudson/projectView.jelly b/core/src/main/resources/lib/hudson/projectView.jelly index 0eff0e94e3975..cb32a417ce362 100644 --- a/core/src/main/resources/lib/hudson/projectView.jelly +++ b/core/src/main/resources/lib/hudson/projectView.jelly @@ -73,9 +73,6 @@ THE SOFTWARE. - - -
- -