Merge branch 'master' into web-fragments

This commit is contained in:
Vincent Latombe 2025-01-24 15:41:06 +01:00 committed by GitHub
commit 005e5599b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 304 additions and 456 deletions

View File

@ -91,11 +91,6 @@ THE SOFTWARE.
<artifactId>guava</artifactId>
<version>33.4.0-jre</version>
</dependency>
<dependency>
<groupId>com.sun.solaris</groupId>
<artifactId>embedded_su4j</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.txw2</groupId>
<artifactId>txw2</artifactId>
@ -131,11 +126,6 @@ THE SOFTWARE.
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>io.jenkins.stapler</groupId>
<artifactId>jenkins-stapler-support</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>

View File

@ -116,10 +116,6 @@ THE SOFTWARE.
<artifactId>bridge-method-annotation</artifactId>
<version>${bridge-method-injector.version}</version>
</dependency>
<dependency>
<groupId>com.sun.solaris</groupId>
<artifactId>embedded_su4j</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.txw2</groupId>
<artifactId>txw2</artifactId>
@ -166,10 +162,6 @@ THE SOFTWARE.
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>io.jenkins.stapler</groupId>
<artifactId>jenkins-stapler-support</artifactId>
</dependency>
<dependency>
<!-- needed by Jelly -->
<groupId>jakarta.servlet.jsp.jstl</groupId>

View File

@ -1,180 +0,0 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* 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 hudson.os;
import static hudson.util.jna.GNUCLibrary.LIBC;
import com.sun.solaris.EmbeddedSu;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.FilePath;
import hudson.Launcher.LocalLauncher;
import hudson.Util;
import hudson.model.Computer;
import hudson.model.TaskListener;
import hudson.remoting.Callable;
import hudson.remoting.Launcher;
import hudson.remoting.LocalChannel;
import hudson.remoting.VirtualChannel;
import hudson.remoting.Which;
import hudson.slaves.Channels;
import hudson.util.ArgumentListBuilder;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.Collections;
/**
* Executes {@link Callable} as the super user, by forking a new process and executing the closure in there
* if necessary.
*
* <p>
* A best effort is made to execute the closure as root, but we may still end up executing the closure
* in the non-root privilege, so the closure should expect that and handle it gracefully.
*
* <p>
* Still very much experimental. Subject to change. <b>Don't use it.</b>
*
* @author Kohsuke Kawaguchi
*/
public abstract class SU {
private SU() { // not meant to be instantiated
}
/**
* Returns a {@link VirtualChannel} that's connected to the privilege-escalated environment.
*
* @param listener
* What this method is doing (such as what process it's invoking) will be sent here.
* @return
* Never null. This may represent a channel to a separate JVM, or just {@link LocalChannel}.
* Close this channel and the SU environment will be shut down.
*/
public static VirtualChannel start(final TaskListener listener, final String rootUsername, final String rootPassword) throws IOException, InterruptedException {
if (File.pathSeparatorChar == ';') // on Windows
return newLocalChannel(); // TODO: perhaps use RunAs to run as an Administrator?
String os = Util.fixNull(System.getProperty("os.name"));
if (os.equals("Linux"))
return new UnixSu() {
@Override
protected String sudoExe() {
return "sudo";
}
@SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "TODO needs triage")
@Override
protected Process sudoWithPass(ArgumentListBuilder args) throws IOException {
args.prepend(sudoExe(), "-S");
listener.getLogger().println("$ " + String.join(" ", args.toList()));
ProcessBuilder pb = new ProcessBuilder(args.toCommandArray());
Process p = pb.start();
// TODO: use -p to detect prompt
// TODO: detect if the password didn't work
try (PrintStream ps = new PrintStream(p.getOutputStream(), false, Charset.defaultCharset())) {
ps.println(rootPassword);
ps.println(rootPassword);
ps.println(rootPassword);
}
return p;
}
}.start(listener, rootPassword);
if (os.equals("SunOS"))
return new UnixSu() {
@Override
protected String sudoExe() {
return "/usr/bin/pfexec";
}
@SuppressFBWarnings(value = "COMMAND_INJECTION", justification = "TODO needs triage")
@Override
protected Process sudoWithPass(ArgumentListBuilder args) throws IOException {
listener.getLogger().println("Running with embedded_su");
ProcessBuilder pb = new ProcessBuilder(args.prepend(sudoExe()).toCommandArray());
return EmbeddedSu.startWithSu(rootUsername, rootPassword, pb);
}
// in solaris, pfexec never asks for a password, so username==null means
// we won't be using password. this helps disambiguate empty password
}.start(listener, rootUsername == null ? null : rootPassword);
// TODO: Mac?
// unsupported platform, take a chance
return newLocalChannel();
}
private static LocalChannel newLocalChannel() {
return FilePath.localChannel;
}
/**
* Starts a new privilege-escalated environment, execute a closure, and shut it down.
*/
public static <V, T extends Throwable> V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable<V, T> closure) throws T, IOException, InterruptedException {
VirtualChannel ch = start(listener, rootUsername, rootPassword);
try {
return ch.call(closure);
} finally {
ch.close();
ch.join(3000); // give some time for orderly shutdown, but don't block forever.
}
}
private abstract static class UnixSu {
protected abstract String sudoExe();
protected abstract Process sudoWithPass(ArgumentListBuilder args) throws IOException;
VirtualChannel start(TaskListener listener, String rootPassword) throws IOException, InterruptedException {
final int uid = LIBC.geteuid();
if (uid == 0) // already running as root
return newLocalChannel();
String javaExe = System.getProperty("java.home") + "/bin/java";
File agentJar = Which.jarFile(Launcher.class);
ArgumentListBuilder args = new ArgumentListBuilder().add(javaExe);
if (agentJar.isFile())
args.add("-jar").add(agentJar);
else // in production code this never happens, but during debugging this is convenient
args.add("-cp").add(agentJar).add(hudson.remoting.Launcher.class.getName());
if (Util.fixEmptyAndTrim(rootPassword) == null) {
// try sudo, in the hope that the user has the permission to do so without password
return new LocalLauncher(listener).launchChannel(
args.prepend(sudoExe()).toCommandArray(),
listener.getLogger(), null, Collections.emptyMap());
} else {
// try sudo with the given password. Also run in pfexec so that we can elevate the privileges
Process proc = sudoWithPass(args);
return Channels.forProcess(args.toStringWithQuote(), Computer.threadPoolForRemoting, proc,
listener.getLogger());
}
}
}
}

View File

@ -5814,7 +5814,6 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
*
* @since 2.222
*/
@Restricted(Beta.class)
public static final Permission MANAGE = new Permission(PERMISSIONS, "Manage",
Messages._Jenkins_Manage_Description(),
ADMINISTER,

View File

@ -0,0 +1,39 @@
/*
* The MIT License
*
* Copyright (c) 2018, CloudBees, Inc.
*
* 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.security.stapler;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Explicitly tell Jenkins the annotated type is to be accessible by Stapler, i.e. getters and fields with this (return) type can be invoked.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StaplerAccessibleType {}

View File

@ -0,0 +1,39 @@
/*
* The MIT License
*
* Copyright (c) 2018, CloudBees, Inc.
*
* 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.security.stapler;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Explicitly tell Jenkins the annotated element is to be dispatched by Stapler, if possible.
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StaplerDispatchable {}

View File

@ -0,0 +1,43 @@
/*
* The MIT License
*
* Copyright (c) 2019 CloudBees, Inc.
*
* 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.security.stapler;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Lists the view names that should be considered fragments and should not be directly dispatched.
*
* @since 1.1
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StaplerFragments {
String[] value() default {};
}

View File

@ -0,0 +1,39 @@
/*
* The MIT License
*
* Copyright (c) 2018, CloudBees, Inc.
*
* 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.security.stapler;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Explicitly tell Jenkins the annotated element is not to be dispatched by Stapler.
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StaplerNotDispatchable {}

View File

@ -0,0 +1,43 @@
/*
* The MIT License
*
* Copyright (c) 2019 CloudBees, Inc.
*
* 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.security.stapler;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Lists the dispatchable views of a class.
*
* @since 1.1
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StaplerViews {
String[] value() default {};
}

View File

@ -28,11 +28,9 @@ THE SOFTWARE.
<!-- no need for additional breadcrumb here as we're on an index page already including breadcrumb -->
<l:main-panel>
<div class="jenkins-app-bar">
<div class="jenkins-app-bar__content jenkins-build-caption" data-status-url="${rootURL}/${it.url}statusIcon">
<div class="jenkins-app-bar__content jenkins-build-caption">
<l:icon src="${h.getUserAvatar(it, '96x96')}" class="jenkins-avatar" />
<h1>
<span class="icon-lg">
<l:icon src="${h.getUserAvatar(it, '48x48')}"/>
</span>
${it.fullName}
</h1>
</div>

View File

@ -31,7 +31,7 @@ THE SOFTWARE.
<l:header />
<l:side-panel>
<l:tasks>
<l:task contextMenu="false" href="${rootURL}/${it.url}/" icon="symbol-person" title="${%Status}"/>
<l:task contextMenu="false" href="${rootURL}/${it.url}/" icon="symbol-person-circle" title="${%Status}"/>
<l:task href="${rootURL}/${it.url}/builds" icon="symbol-build-history" title="${%Builds}"/>
<t:actions actions="${it.propertyActions}"/>
<t:actions actions="${it.transientActions}"/>

View File

@ -52,7 +52,7 @@ THE SOFTWARE.
<tr>
<td class="jenkins-table__cell--tight jenkins-table__icon">
<div class="jenkins-table__cell__button-wrapper">
<l:icon src="${h.getUserAvatar(user,'32x32')}" />
<l:icon src="${h.getUserAvatar(user, '64x64')}" class="jenkins-avatar" />
</div>
</td>
<td>

View File

@ -35,7 +35,7 @@
.token-list .token-list-item {
min-height: inherit;
padding: 8px 10px;
font-size: 0.875rem;
font-size: var(--font-size-sm);
line-height: 26px;
}
.token-list .token-list-item.legacy-token {

View File

@ -48,7 +48,7 @@ THE SOFTWARE.
</div>
<input value="${attrs.value}"
id="${attrs.id}"
class="jenkins-search__input"
class="jenkins-input jenkins-search__input"
placeholder="${attrs.placeholder ?: '%Search'}"
type="search"
autofocus="${attrs.autofocus == 'true' ? 'true' : null}"

View File

@ -1,24 +0,0 @@
package hudson.os;
import hudson.util.StreamTaskListener;
import java.io.File;
import java.nio.file.Files;
import jenkins.security.MasterToSlaveCallable;
/**
* @author Kohsuke Kawaguchi
*/
public class SUTester {
public static void main(String[] args) throws Throwable {
SU.execute(StreamTaskListener.fromStdout(), "kohsuke", "bogus", new TouchingCallable());
}
private static class TouchingCallable extends MasterToSlaveCallable<Object, Throwable> {
@Override
public Object call() throws Throwable {
System.out.println("Touching /tmp/x");
Files.newOutputStream(new File("/tmp/x").toPath()).close();
return null;
}
}
}

View File

@ -73,9 +73,9 @@ THE SOFTWARE.
</issueManagement>
<properties>
<revision>2.494</revision>
<revision>2.495</revision>
<changelist>-SNAPSHOT</changelist>
<project.build.outputTimestamp>2025-01-14T13:40:38Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2025-01-21T13:51:35Z</project.build.outputTimestamp>
<!-- configuration for patch tracker plugin -->
<project.patchManagement.system>github</project.patchManagement.system>
@ -98,7 +98,7 @@ THE SOFTWARE.
<spotless.check.skip>false</spotless.check.skip>
<!-- Make sure to keep the jetty-ee9-maven-plugin version in war/pom.xml in sync with the Jetty release in Winstone: -->
<winstone.version>8.4</winstone.version>
<node.version>20.18.1</node.version>
<node.version>20.18.2</node.version>
</properties>
<!--

View File

@ -2,7 +2,7 @@ import { createElementFromHtml } from "@/util/dom";
import makeKeyboardNavigable from "@/util/keyboard";
import { xmlEscape } from "@/util/security";
const SELECTED_CLASS = "jenkins-search__results-item--selected";
const SELECTED_CLASS = "jenkins-dropdown__item--selected";
function init() {
const searchBarInputs = document.querySelectorAll(".jenkins-search__input");
@ -16,7 +16,7 @@ function init() {
);
searchWrapper.appendChild(searchResultsContainer);
const searchResults = createElementFromHtml(
`<div class="jenkins-search__results"></div>`,
`<div class="jenkins-dropdown"></div>`,
);
searchResultsContainer.appendChild(searchResults);
@ -35,9 +35,9 @@ function init() {
results.forEach((item, index) => {
container.appendChild(
createElementFromHtml(
`<a class="${index === 0 ? SELECTED_CLASS : ""}" href="${
`<a class="jenkins-dropdown__item ${index === 0 ? SELECTED_CLASS : ""}" href="${
item.url
}"><div>${item.icon}</div>${xmlEscape(item.label)}</a>`,
}"><div class="jenkins-dropdown__item__icon">${item.icon}</div>${xmlEscape(item.label)}</a>`,
),
);
});

View File

@ -151,7 +151,7 @@ pre {
word-wrap: break-word;
margin: 0 0 var(--section-padding);
padding: 0.8rem 1rem;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
background-color: var(--pre-background);
color: var(--pre-color);
font-family: var(--font-family-mono);
@ -253,7 +253,7 @@ pre.console {
.changeset-message {
padding: 0.8rem 1rem;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
background-color: var(--pre-background);
pre {
@ -386,7 +386,7 @@ img.icon-help {
.comboBoxList {
overflow-y: scroll;
color: var(--text-color);
border-radius: 10px;
border-radius: var(--form-input-border-radius);
box-shadow: 0 10px 20px rgba(black, 0.15);
margin-top: 8px;
margin-left: 3px;
@ -407,7 +407,7 @@ img.icon-help {
position: absolute;
inset: 0;
background: var(--text-color);
border-radius: 10px;
border-radius: var(--form-input-border-radius);
opacity: 0;
transition: var(--standard-transition);
z-index: -1;
@ -683,7 +683,7 @@ table.progress-bar.red td.progress-bar-done {
/* ========================= logRecords.jelly ================== */
.logrecord-container {
border-radius: 10px;
border-radius: var(--form-input-border-radius);
overflow: hidden;
margin-bottom: var(--section-padding);

View File

@ -4,7 +4,7 @@
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
strong {
font-weight: var(--font-bold-weight);

View File

@ -108,6 +108,11 @@
width: 2rem !important;
height: 2rem !important;
}
img {
width: 2.375rem;
height: 2.375rem;
}
}
.bottom-sticker,

View File

@ -0,0 +1,8 @@
.jenkins-avatar {
&[src] {
border-radius: 100px;
outline: 1px solid color-mix(in sRGB, var(--text-color) 10%, transparent);
background: color-mix(in sRGB, var(--text-color) 5%, transparent);
outline-offset: -1px;
}
}

View File

@ -26,7 +26,7 @@
justify-content: center;
color: var(--text-color);
font-weight: normal;
font-size: 0.875rem;
font-size: var(--font-size-sm);
padding: 0.2rem 0.4rem;
& > a {

View File

@ -15,12 +15,11 @@
outline: none;
margin: 0;
padding: 0.5rem 0.9rem;
font-size: 0.875rem;
font-size: var(--font-size-sm);
font-weight: normal;
text-decoration: none !important;
background: transparent;
color: var(--text-color) !important;
border-radius: 0.66rem;
cursor: pointer;
min-height: 2.25rem;
white-space: nowrap;

View File

@ -87,6 +87,10 @@
input {
background: transparent !important;
--input-border: transparent;
--input-border-hover: transparent;
border-radius: inherit;
&::before,
@ -121,7 +125,7 @@
&__heading {
font-weight: var(--font-bold-weight);
font-size: 0.875rem;
font-size: var(--font-size-sm);
margin: 0;
padding: 0.75rem 0.75rem 0.625rem;
color: var(--text-color-secondary);
@ -180,6 +184,14 @@
width: 1.25rem;
height: 1.25rem;
}
&[src] {
border-radius: 100px;
outline: 1px solid
color-mix(in sRGB, var(--text-color) 10%, transparent);
background: color-mix(in sRGB, var(--text-color) 5%, transparent);
outline-offset: -1px;
}
}
&__description {
@ -199,7 +211,7 @@
}
&__info {
font-size: 0.875rem;
font-size: var(--font-size-sm);
margin: 0;
padding: 0 14px;
line-height: 46px;

View File

@ -1,8 +1,9 @@
$jenkins-dialog-padding: 1.3rem;
.jenkins-dialog {
border-radius: 0.6rem;
border-radius: var(--form-input-border-radius);
border: none;
background-color: var(--card-background);
box-shadow: var(--dialog-box-shadow);
animation: jenkins-dialog-animate-in 0.25s cubic-bezier(0, 0.68, 0.5, 1.5);
overflow: hidden;
@ -10,6 +11,7 @@ $jenkins-dialog-padding: 1.3rem;
display: flex;
flex-direction: column;
gap: $jenkins-dialog-padding;
outline: none;
&::backdrop {
background: var(--dialog-backdrop-background);
@ -48,8 +50,6 @@ $jenkins-dialog-padding: 1.3rem;
flex-direction: row-reverse;
.jenkins-button {
font-size: 0.9rem;
padding: 0.7rem 0.6rem;
min-width: 100px;
}
}
@ -68,16 +68,7 @@ $jenkins-dialog-padding: 1.3rem;
right: $jenkins-dialog-padding - 0.5rem;
aspect-ratio: 1;
padding: 0;
&::before,
&::after {
border-radius: 100%;
outline: none;
}
&::after {
backdrop-filter: contrast(0.9) blur(5px);
}
border-radius: 100%;
}
}

View File

@ -1,5 +1,6 @@
@use "app-bar";
@use "alert";
@use "app-bar";
@use "avatar";
@use "badges";
@use "breadcrumbs";
@use "buttons";

View File

@ -6,7 +6,7 @@
gap: 1rem;
min-height: 15rem;
background: var(--button-background);
border-radius: 0.66rem;
border-radius: var(--form-input-border-radius);
font-size: var(--font-size-base);
margin-bottom: var(--section-padding);
font-weight: var(--font-bold-weight);

View File

@ -11,7 +11,7 @@
grid-template-columns: auto 1fr;
grid-gap: 1.5ch;
padding: 0.8rem;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
font-weight: var(--font-bold-weight);
line-height: 1.66;
color: var(--text-color);

View File

@ -184,7 +184,7 @@
.jenkins-button {
justify-content: flex-start;
gap: 0.75rem;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
margin: 0 !important;
padding: 0.5rem 0.9rem !important;
min-height: 2.25rem !important;

View File

@ -42,7 +42,7 @@ $background-outset: 0.7rem;
}
.jenkins-search__input {
padding-left: 2.8rem;
padding-left: 2.6rem;
}
}
}
@ -66,7 +66,7 @@ $background-outset: 0.7rem;
width: 100%;
cursor: pointer;
font-weight: normal !important;
font-size: 0.875rem;
font-size: var(--font-size-sm);
color: var(--text-color) !important;
background: transparent;
outline: none;

View File

@ -13,7 +13,7 @@ $skip-link-box-shadow: 0 0 50px -15px var(--yellow);
$skip-link-box-shadow;
color: var(--text-color) !important;
padding: $skip-link-block-padding $skip-link-inline-padding;
border-radius: 0.66rem;
border-radius: var(--form-input-border-radius);
outline: none;
text-decoration: none !important;
transition:

View File

@ -2,7 +2,7 @@
position: relative;
display: inline-flex;
align-items: center;
font-size: 0.875rem;
font-size: var(--font-size-sm);
font-weight: var(--font-bold-weight);
margin: 0;

View File

@ -39,7 +39,7 @@
padding-bottom: calc((var(--table-padding) * 0.9) + 2px);
padding-left: 1.6rem;
font-weight: var(--font-bold-weight);
font-size: 0.875rem;
font-size: var(--font-size-sm);
&[align="center"] {
text-align: center;

View File

@ -39,7 +39,7 @@
background: var(--tabs-item-background);
color: var(--tabs-item-foreground);
font-weight: var(--font-bold-weight);
font-size: 0.875rem;
font-size: var(--font-size-sm);
transition: var(--standard-transition);
cursor: pointer;

View File

@ -37,7 +37,7 @@
font-size: 0.8rem;
font-weight: normal;
color: var(--text-color);
border-radius: 0.66rem;
border-radius: var(--form-input-border-radius);
cursor: pointer;
min-height: 36px;
white-space: nowrap;

View File

@ -4,7 +4,7 @@
position: relative;
border: 2px dashed var(--input-border);
padding: 1rem;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
margin-bottom: 1rem;
margin-top: 1rem;
transition:

View File

@ -10,19 +10,7 @@
position: relative;
&__input {
appearance: none;
background: var(--item-background--hover);
border: none;
outline: none;
border-radius: 0.625rem;
width: 100%;
margin: 0;
padding: 0 0.5rem 0 var(--search-bar-height);
line-height: 1;
box-shadow:
0 0 0 2px transparent,
0 0 0 12px transparent;
transition: var(--standard-transition);
padding: 0 0.25rem 0 calc(var(--search-bar-height) * 0.9);
height: var(--search-bar-height);
&::placeholder {
@ -60,18 +48,8 @@
}
&:not(:disabled) {
&:hover {
background: var(--item-background--active);
}
&:active,
&:focus {
outline: none;
background: var(--item-background--active);
box-shadow:
0 0 0 2px var(--focus-input-border),
0 0 0 7px var(--focus-input-glow);
&::-webkit-search-cancel-button {
opacity: 0.5;
pointer-events: all;
@ -82,22 +60,12 @@
&:active,
&:focus {
outline: none;
background: var(--item-background--active);
box-shadow:
0 0 0 2px var(--focus-input-border),
0 0 0 7px var(--focus-input-glow);
&::-webkit-search-cancel-button {
opacity: 1;
pointer-events: all;
transform: scale(1);
}
}
&:disabled {
cursor: not-allowed;
}
}
&__icon {
@ -110,10 +78,10 @@
pointer-events: none;
svg {
width: 45%;
height: 45%;
max-width: 1.1rem;
max-height: 1.1rem;
width: 1rem;
height: 1rem;
max-width: 1rem;
max-height: 1rem;
grid-column-start: 1;
grid-row-start: 1;
place-self: center center;
@ -199,7 +167,7 @@
content: "";
position: absolute;
inset: 0;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
z-index: -1;
backdrop-filter: blur(20px);
box-shadow: 0 0 var(--section-padding) var(--background);
@ -242,6 +210,7 @@
height: 1px; // Setting to 0 caused the items not to render initially in Chrome
opacity: 0;
transition: var(--standard-transition);
background: color-mix(in sRGB, var(--background) 85%, transparent);
backdrop-filter: var(--dropdown-backdrop-filter);
visibility: collapse;
scale: 95%;
@ -254,135 +223,6 @@
visibility: visible;
translate: 0 0.3125rem;
}
a {
position: relative;
display: flex;
align-items: center;
gap: 0.7rem;
padding: 0.5rem 0.7rem;
font-size: 0.875rem;
border-radius: 10px;
color: var(--text-color);
font-weight: 500;
text-decoration: none;
z-index: 0;
line-height: 1;
min-height: 2.25rem;
transition: background var(--standard-transition);
div {
display: flex;
align-items: center;
justify-content: center;
width: 1.125rem;
height: 1.125rem;
svg,
img {
width: 100%;
height: 100%;
}
}
&::before,
&::after {
position: absolute;
content: "";
inset: 0;
z-index: -1;
border-radius: 10px;
transition: var(--standard-transition);
pointer-events: none;
}
&::before {
background-color: transparent;
}
&::after {
box-shadow: 0 0 0 0.66rem transparent;
}
&:hover,
&:focus {
&::before {
background-color: var(--item-background--hover);
}
}
&:active,
&:focus {
outline: none !important;
z-index: 1;
&::before {
background-color: var(--item-background--active);
}
&::after {
box-shadow: 0 0 0 0.33rem var(--item-box-shadow--focus);
}
}
&:focus-visible {
&::after {
box-shadow: 0 0 0 0.33rem var(--text-color);
}
}
}
.jenkins-search__results {
position: relative;
display: flex;
justify-content: flex-start;
flex-direction: column;
gap: 0.2rem;
padding: 0.4rem;
& > div {
position: relative;
margin-top: -0.25rem;
a {
padding-left: 2.6rem;
color: var(--text-color-secondary);
}
&::before {
content: "";
position: absolute;
top: 0.4rem;
left: 1.1rem + 0.625rem;
bottom: 0.3rem;
width: 0.125rem;
background: currentColor;
border-radius: 100vmax;
opacity: 0.05;
}
&:empty {
display: none;
}
}
}
&:hover {
.jenkins-search__results-item--selected {
background: transparent;
}
}
}
.jenkins-search__results-item--selected {
background: var(--item-background--hover);
animation: pulse 1s ease-in-out forwards;
@keyframes pulse {
50% {
background: var(--item-background--active);
}
}
}
.jenkins-search__results__no-results-label {

View File

@ -9,5 +9,5 @@
background-color: var(--very-light-grey);
padding: var(--form-input-padding);
margin-top: 0.5rem;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
}

View File

@ -57,7 +57,7 @@ $min-button-size: 36px;
justify-content: center;
aspect-ratio: 1;
height: $min-button-size;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
font-weight: var(--btn-link-font-weight);
font-size: var(--btn-font-size);
background: var(--button-background--hover);

View File

@ -182,7 +182,7 @@
bottom: 6px;
width: 2px;
background: var(--text-color-secondary);
border-radius: 10px;
border-radius: var(--form-input-border-radius);
opacity: 0.3;
}
}

View File

@ -136,7 +136,7 @@
input {
padding: 0.6rem 0.75rem;
border-radius: 0.66rem;
border-radius: var(--form-input-border-radius);
font-size: 0.95rem;
@media (width <= 600px) {
@ -171,7 +171,7 @@
position: absolute;
inset: calc(50% + 1px) 0;
height: 2px;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
background-color: var(--input-border);
}

View File

@ -38,7 +38,7 @@
.simple-page .safe-restarting {
padding: 10px 30px;
border-radius: 10px;
border-radius: var(--form-input-border-radius);
text-align: center;
margin-top: 2rem;
background-color: var(--alert-success-bg-color);

View File

@ -128,13 +128,13 @@ THE SOFTWARE.
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>678.v3ee58b_469476</version>
<version>686.v603d058a_e148</version>
</dependency>
<dependency>
<!-- Required by plugin-util-api -->
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>943.v8b_0d01a_7b_a_08</version>
<version>944.v5a_859593b_98a_</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -178,7 +178,7 @@ THE SOFTWARE.
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-test-harness</artifactId>
<version>2385.vfe86233d0d36</version>
<version>2388.vf1281b_a_6057b_</version>
<scope>test</scope>
<exclusions>
<exclusion>
@ -344,7 +344,7 @@ THE SOFTWARE.
<artifactItem>
<groupId>io.jenkins.plugins</groupId>
<artifactId>design-library</artifactId>
<version>353.v3b_c47f293f54</version>
<version>354.v87d9d5804b_c1</version>
<type>hpi</type>
<outputDirectory>${project.build.outputDirectory}/plugins</outputDirectory>
<destFileName>design-library.jpi</destFileName>

View File

@ -25,7 +25,9 @@
package jenkins.slaves.restarter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeFalse;
import hudson.Functions;
import hudson.model.Slave;
import hudson.slaves.DumbSlave;
import java.util.concurrent.atomic.AtomicBoolean;
@ -52,12 +54,24 @@ public class JnlpSlaveRestarterInstallerTest {
@Issue("JENKINS-19055")
@Test
public void tcpReconnection() throws Throwable {
// TODO Enable when test is reliable on Windows agents of ci.jenkins.io
// When builds switched from ACI containers to virtual machines, this test consistently failed
// When the test is run on local Windows computers, it passes
// Disable the test on ci.jenkins.io and friends when running Windows
// Do not disable for Windows developers generally
assumeFalse("TODO: Test fails on Windows VM", Functions.isWindows() && System.getenv("CI") != null);
reconnection(false);
}
@Issue("JENKINS-66446")
@Test
public void webSocketReconnection() throws Throwable {
// TODO Enable when test is reliable on Windows agents of ci.jenkins.io
// When builds switched from ACI containers to virtual machines, this test consistently failed
// When the test is run on local Windows computers, it passes
// Disable the test on ci.jenkins.io and friends when running Windows
// Do not disable for Windows developers generally
assumeFalse("TODO: Test fails on Windows VM", Functions.isWindows() && System.getenv("CI") != null);
reconnection(true);
}

View File

@ -46,7 +46,7 @@ THE SOFTWARE.
<host>localhost</host>
<!-- HTTP listener port -->
<port>8080</port>
<mina-sshd-api.version>2.14.0-138.v6341ee58e1df</mina-sshd-api.version>
<mina-sshd-api.version>2.14.0-143.v2b_362fc39576</mina-sshd-api.version>
<!-- Minimum Remoting version, which is tested for API compatibility, duplicated so that renovate only updates the latest remoting version property -->
<remoting.minimum.supported.version>3107.v665000b_51092</remoting.minimum.supported.version>
@ -352,7 +352,7 @@ THE SOFTWARE.
<!-- dependency of checks-api and plugin-util-api -->
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>943.v8b_0d01a_7b_a_08</version>
<version>944.v5a_859593b_98a_</version>
<type>hpi</type>
</artifactItem>
@ -413,7 +413,7 @@ THE SOFTWARE.
<!-- dependency of checks-api, junit, plugin-util-api, workflow-api, and workflow-support -->
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>678.v3ee58b_469476</version>
<version>686.v603d058a_e148</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
@ -441,14 +441,14 @@ THE SOFTWARE.
<!-- detached after 2.86 -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>command-launcher</artifactId>
<version>116.vd85919c54a_d6</version>
<version>118.v72741845c17a_</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
<!-- detached after 2.112 -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jdk-tool</artifactId>
<version>80.v8a_dee33ed6f0</version>
<version>83.v417146707a_3d</version>
<type>hpi</type>
</artifactItem>
<artifactItem>