Merge branch 'master' into experimental-details-widget

This commit is contained in:
Tim Jacomb authored and GitHub committed 2025-02-14 18:48:06 +00:00
commit da4b90a034
96 files changed
+1011 -914

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@
[![Gitter](https://img.shields.io/gitter/room/jenkinsci/jenkins)](https://app.gitter.im/#/room/#jenkinsci_jenkins:gitter.im)
In a nutshell, Jenkins is the leading open-source automation server.
Built with Java, it provides over 1,800 [plugins](https://plugins.jenkins.io/) to support automating virtually anything,
Built with Java, it provides over 2,000 [plugins](https://plugins.jenkins.io/) to support automating virtually anything,
so that humans can spend their time doing things machines cannot.
# What to Use Jenkins for and When to Use It
+3 -8
View File
@@ -41,7 +41,7 @@ THE SOFTWARE.
<commons-fileupload2.version>2.0.0-M2</commons-fileupload2.version>
<groovy.version>2.4.21</groovy.version>
<jelly.version>1.1-jenkins-20250108</jelly.version>
<stapler.version>1942.v708e07325402</stapler.version>
<stapler.version>1948.v0f99403fe86a_</stapler.version>
</properties>
<dependencyManagement>
@@ -63,7 +63,7 @@ THE SOFTWARE.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>6.2.2</version>
<version>6.2.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -287,11 +287,6 @@ THE SOFTWARE.
<artifactId>localizer</artifactId>
<version>1.31</version>
</dependency>
<dependency>
<groupId>org.jvnet.robust-http-client</groupId>
<artifactId>robust-http-client</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jvnet.winp</groupId>
<artifactId>winp</artifactId>
@@ -342,7 +337,7 @@ THE SOFTWARE.
<!-- provided by jcl-over-slf4j -->
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.3.4</version>
<version>1.3.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
-4
View File
@@ -325,10 +325,6 @@ THE SOFTWARE.
<groupId>org.jvnet.localizer</groupId>
<artifactId>localizer</artifactId>
</dependency>
<dependency>
<groupId>org.jvnet.robust-http-client</groupId>
<artifactId>robust-http-client</artifactId>
</dependency>
<dependency>
<groupId>org.jvnet.winp</groupId>
<artifactId>winp</artifactId>
+1 -1
View File
@@ -1993,7 +1993,7 @@ public class Functions {
*/
public static @CheckForNull String getConsoleUrl(WithConsoleUrl withConsoleUrl) {
String consoleUrl = withConsoleUrl.getConsoleUrl();
return consoleUrl != null ? Stapler.getCurrentRequest().getContextPath() + '/' + consoleUrl : null;
return consoleUrl != null ? Stapler.getCurrentRequest2().getContextPath() + '/' + consoleUrl : null;
}
/**
@@ -70,7 +70,6 @@ import jenkins.security.stapler.StaplerAccessibleType;
import jenkins.util.JenkinsJVM;
import jenkins.util.SystemProperties;
import org.jenkinsci.Symbol;
import org.jvnet.robust_http_client.RetryableHttpStream;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;
@@ -346,10 +345,10 @@ public final class ProxyConfiguration extends AbstractDescribableImpl<ProxyConfi
public static InputStream getInputStream(URL url) throws IOException {
final ProxyConfiguration p = get();
if (p == null)
return new RetryableHttpStream(url);
return ((HttpURLConnection) url.openConnection()).getInputStream();
Proxy proxy = p.createProxy(url.getHost());
InputStream is = new RetryableHttpStream(url, proxy);
InputStream is = ((HttpURLConnection) url.openConnection(proxy)).getInputStream();
if (p.getUserName() != null) {
// Add an authenticator which provides the credentials for proxy authentication
Authenticator.setDefault(p.authenticator);
+13 -16
View File
@@ -92,6 +92,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HexFormat;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -115,7 +116,6 @@ import jenkins.model.Jenkins;
import jenkins.util.MemoryReductionUtil;
import jenkins.util.SystemProperties;
import jenkins.util.io.PathRemover;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.apache.tools.ant.BuildException;
@@ -635,7 +635,6 @@ public class Util {
* The stream will be closed by this method at the end of this method.
* @return
* 32-char wide string
* @see DigestUtils#md5Hex(InputStream)
*/
@NonNull
public static String getDigestOf(@NonNull InputStream source) throws IOException {
@@ -710,13 +709,7 @@ public class Util {
@NonNull
public static String toHexString(@NonNull byte[] data, int start, int len) {
StringBuilder buf = new StringBuilder();
for (int i = 0; i < len; i++) {
int b = data[start + i] & 0xFF;
if (b < 16) buf.append('0');
buf.append(Integer.toHexString(b));
}
return buf.toString();
return HexFormat.of().formatHex(data, start, len);
}
@NonNull
@@ -726,12 +719,7 @@ public class Util {
@NonNull
public static byte[] fromHexString(@NonNull String data) {
if (data.length() % 2 != 0)
throw new IllegalArgumentException("data must have an even number of hexadecimal digits");
byte[] r = new byte[data.length() / 2];
for (int i = 0; i < data.length(); i += 2)
r[i / 2] = (byte) Integer.parseInt(data.substring(i, i + 2), 16);
return r;
return HexFormat.of().parseHex(data);
}
/**
@@ -1992,9 +1980,18 @@ public class Util {
* Returns Hex string of SHA-256 Digest of passed input
*/
@Restricted(NoExternalUse.class)
public static String getHexOfSHA256DigestOf(byte[] input) throws IOException {
public static String getHexOfSHA256DigestOf(byte[] input) {
//get hex string of sha 256 of payload
byte[] payloadDigest = Util.getSHA256DigestOf(input);
return (payloadDigest != null) ? Util.toHexString(payloadDigest) : null;
}
/**
* Returns Hex string of SHA-256 Digest of passed string
*/
@Restricted(NoExternalUse.class)
public static String getHexOfSHA256DigestOf(String input) {
return getHexOfSHA256DigestOf(input.getBytes(StandardCharsets.UTF_8));
}
}
@@ -371,6 +371,11 @@ public final class CronTab {
* (e.g. Jun 31) date, or at least a date too rare to be useful. This addresses JENKINS-41864 and was added in 2.49
*/
public Calendar ceil(Calendar cal) {
if (cal.get(Calendar.SECOND) > 0 || cal.get(Calendar.MILLISECOND) > 0) {
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.MINUTE, 1);
}
Calendar twoYearsFuture = (Calendar) cal.clone();
twoYearsFuture.add(Calendar.YEAR, 2);
OUTER:
@@ -440,6 +445,8 @@ public final class CronTab {
* (e.g. Jun 31) date, or at least a date too rare to be useful. This addresses JENKINS-41864 and was added in 2.49
*/
public Calendar floor(Calendar cal) {
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Calendar twoYearsAgo = (Calendar) cal.clone();
twoYearsAgo.add(Calendar.YEAR, -2);
@@ -80,7 +80,7 @@ public interface ConsoleUrlProvider extends Describable<ConsoleUrlProvider> {
* @return the URL for the console for the specified build, relative to the web server root
*/
static @NonNull String getRedirectUrl(Run<?, ?> run) {
return Stapler.getCurrentRequest().getContextPath() + '/' + run.getConsoleUrl();
return Stapler.getCurrentRequest2().getContextPath() + '/' + run.getConsoleUrl();
}
static List<ConsoleUrlProvider> all() {
@@ -6,7 +6,7 @@ import java.util.logging.Logger;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerRequest2;
/**
* Configures check interval for computer retention.
@@ -56,7 +56,7 @@ public class GlobalComputerRetentionCheckIntervalConfiguration extends GlobalCon
}
@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException {
try {
final int interval = json.getInt("computerRetentionCheckInterval");
setComputerRetentionCheckInterval(interval);
@@ -67,7 +67,7 @@ public abstract class GlobalConfiguration extends Descriptor<GlobalConfiguration
@Override
public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException {
if (Util.isOverridden(GlobalConfiguration.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) {
return configure(StaplerRequest.fromStaplerRequest2(req), json);
return configure(req != null ? StaplerRequest.fromStaplerRequest2(req) : null, json);
} else {
return configureImpl(req, json);
}
@@ -974,6 +974,9 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
ClassFilterImpl.register();
LOGGER.info("Starting version " + getVersion());
// Sanity check that we can load the confidential store. Fail fast if we can't.
ConfidentialStore.get();
// initialization consists of ...
executeReactor(is,
pluginManager.initTasks(is), // loading and preparing plugins
@@ -1,5 +1,6 @@
package jenkins.security;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.FilePath;
import hudson.Util;
import hudson.util.Secret;
@@ -19,19 +20,35 @@ import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import jenkins.model.Jenkins;
import jenkins.util.SystemProperties;
/**
* Default portable implementation of {@link ConfidentialStore} that uses
* a directory inside $JENKINS_HOME.
*
* The master key is also stored in this same directory.
* <p>
* The master key is stored by default in <code>$JENKINS_HOME/secrets/master.key</code> but another location can be provided using the system property <code>jenkins.master.key.file</code>.
* <p>
* It is also possible to prevent the generation of the master key file using the system property <code>-Djenkins.master.key.readOnly</code>. In this case, the master key file must be provided or startup will fail.
*
* @author Kohsuke Kawaguchi
*/
// @MetaInfServices --- not annotated because this is the fallback implementation
public class DefaultConfidentialStore extends ConfidentialStore {
static final String MASTER_KEY_FILE_SYSTEM_PROPERTY = DefaultConfidentialStore.class.getName() + ".file";
static final String MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME = DefaultConfidentialStore.class.getName() + ".readOnly";
private final SecureRandom sr = new SecureRandom();
@NonNull
private static File getMasterKeyFile(File rootDir) {
var jenkinsMasterKey = SystemProperties.getString(MASTER_KEY_FILE_SYSTEM_PROPERTY);
if (jenkinsMasterKey != null) {
return new File(jenkinsMasterKey);
} else {
return new File(rootDir, "master.key");
}
}
/**
* Directory that stores individual keys.
*/
@@ -51,6 +68,10 @@ public class DefaultConfidentialStore extends ConfidentialStore {
}
public DefaultConfidentialStore(File rootDir) throws IOException, InterruptedException {
this(rootDir, getMasterKeyFile(rootDir));
}
protected DefaultConfidentialStore(File rootDir, File keyFile) throws IOException, InterruptedException {
this.rootDir = rootDir;
if (rootDir.mkdirs()) {
// protect this directory. but don't change the permission of the existing directory
@@ -58,11 +79,15 @@ public class DefaultConfidentialStore extends ConfidentialStore {
new FilePath(rootDir).chmod(0700);
}
TextFile masterSecret = new TextFile(new File(rootDir, "master.key"));
TextFile masterSecret = new TextFile(keyFile);
if (!masterSecret.exists()) {
// we are only going to use small number of bits (since export control limits AES key length)
// but let's generate a long enough key anyway
masterSecret.write(Util.toHexString(randomBytes(128)));
if (SystemProperties.getBoolean(MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME)) {
throw new IOException(masterSecret + " does not exist and system property " + MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME + " is set. You must provide a valid master key file.");
} else {
// we are only going to use small number of bits (since export control limits AES key length)
// but let's generate a long enough key anyway
masterSecret.write(Util.toHexString(randomBytes(128)));
}
}
this.masterKey = Util.toAes128Key(masterSecret.readTrim());
}
@@ -28,6 +28,7 @@ import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.BulkChange;
import hudson.Extension;
import hudson.Util;
import hudson.model.User;
import hudson.model.UserProperty;
import hudson.model.UserPropertyDescriptor;
@@ -39,7 +40,6 @@ import java.util.Objects;
import jenkins.model.Jenkins;
import jenkins.security.LastGrantedAuthoritiesProperty;
import jenkins.util.SystemProperties;
import org.apache.commons.codec.binary.Hex;
import org.jenkinsci.Symbol;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.DoNotUse;
@@ -103,7 +103,7 @@ public class UserSeedProperty extends UserProperty {
byte[] bytes = new byte[SEED_NUM_BYTES];
while (Objects.equals(newSeed, currentSeed)) {
RANDOM.nextBytes(bytes);
newSeed = new String(Hex.encodeHex(bytes));
newSeed = Util.toHexString(bytes);
}
this.seed = newSeed;
}
@@ -32,6 +32,7 @@ import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.PluginWrapper;
import hudson.ProxyConfiguration;
import hudson.Util;
import hudson.model.AsyncPeriodicWork;
import hudson.model.TaskListener;
import hudson.model.UsageStatistics;
@@ -51,7 +52,6 @@ import java.util.logging.Logger;
import jenkins.model.Jenkins;
import jenkins.util.SystemProperties;
import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
@@ -221,7 +221,7 @@ public abstract class Telemetry implements ExtensionPoint {
wrappedData.put("type", telemetry.getId());
wrappedData.put("payload", data);
String correlationId = ExtensionList.lookupSingleton(Correlator.class).getCorrelationId();
wrappedData.put("correlator", DigestUtils.sha256Hex(correlationId + telemetry.getId()));
wrappedData.put("correlator", Util.getHexOfSHA256DigestOf(correlationId + telemetry.getId()));
String body = wrappedData.toString();
if (LOGGER.isLoggable(Level.FINEST)) {
@@ -1,6 +1,7 @@
package jenkins.util;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Util;
import hudson.util.FormValidation;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -33,8 +34,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.output.TeeOutputStream;
import org.jvnet.hudson.crypto.CertificateUtil;
import org.jvnet.hudson.crypto.SignatureOutputStream;
@@ -221,10 +220,10 @@ public class JSONSignatureValidator {
// This approach might look unnecessarily clever, but short of having redundant Signature instances,
// there doesn't seem to be a better approach for this.
try {
if (signature.verify(Hex.decodeHex(providedSignature.toCharArray()))) {
if (signature.verify(Util.fromHexString(providedSignature))) {
return true;
}
} catch (SignatureException | DecoderException ignore) {
} catch (SignatureException | IllegalArgumentException ignore) {
// ignore
}
@@ -242,7 +241,7 @@ public class JSONSignatureValidator {
* Utility method supporting both possible digest formats: Base64 and Hex
*/
private boolean digestMatches(byte[] digest, String providedDigest) {
return providedDigest.equalsIgnoreCase(Hex.encodeHexString(digest)) || providedDigest.equalsIgnoreCase(Base64.getEncoder().encodeToString(digest));
return providedDigest.equalsIgnoreCase(Util.toHexString(digest)) || providedDigest.equalsIgnoreCase(Base64.getEncoder().encodeToString(digest));
}
@@ -0,0 +1,279 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
The MIT License
Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts, id:digerata, Yahoo! 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.
-->
<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
version="3.1">
<name>jenkins</name>
<servlet>
<servlet-name>Stapler</servlet-name>
<servlet-class>org.kohsuke.stapler.Stapler</servlet-class>
<init-param>
<param-name>default-encodings</param-name>
<param-value>text/html=UTF-8</param-value>
</init-param>
<init-param>
<param-name>diagnosticThreadName</param-name>
<param-value>false</param-value>
</init-param>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Stapler</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>suspicious-request-filter</filter-name>
<filter-class>jenkins.security.SuspiciousRequestFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>diagnostic-name-filter</filter-name>
<filter-class>org.kohsuke.stapler.DiagnosticThreadNameFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>hudson.util.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>uncaught-exception-filter</filter-name>
<filter-class>org.kohsuke.stapler.UncaughtExceptionFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>authentication-filter</filter-name>
<filter-class>hudson.security.HudsonFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>csrf-filter</filter-name>
<filter-class>hudson.security.csrf.CrumbFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>error-attribute-filter</filter-name>
<filter-class>jenkins.ErrorAttributeFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>plugins-filter</filter-name>
<filter-class>hudson.util.PluginServletFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<!--
The Headers filter allows us to override headers sent by the container
that may be in conflict with what we want. For example, Tomcat will set
Cache-Control: no-cache for any files behind the security-constraint
below. So if Hudson is on a public server, and you want to only allow
authorized users to access it, you may want to pay attention to this.
See: http://www.nabble.com/No-browser-caching-with-Hudson- -tf4601857.html
<filter>
<filter-name>change-headers-filter</filter-name>
<filter-class>hudson.ResponseHeaderFilter</filter-class>
<!- The value listed here is for 24 hours. Increase or decrease as you see
fit. Value is in seconds. Make sure to keep the public option ->
<init-param>
<param-name>Cache-Control</param-name>
<param-value>max-age=86400, public</param-value>
</init-param>
<!- It turns out that Tomcat just doesn't want to let
go of its cache option. If you override Cache-Control,
it starts to send Pragma: no-cache as a backup.
->
<init-param>
<param-name>Pragma</param-name>
<param-value>public</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.gif</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.png</url-pattern>
</filter-mapping>
-->
<filter-mapping>
<filter-name>suspicious-request-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>diagnostic-name-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>uncaught-exception-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>authentication-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>csrf-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>error-attribute-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>plugins-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<!-- Must be before WebAppMain in order to initialize the context before the first use of this class. -->
<listener-class>jenkins.util.SystemProperties$Listener</listener-class>
</listener>
<listener>
<listener-class>hudson.WebAppMain</listener-class>
</listener>
<listener>
<listener-class>jenkins.JenkinsHttpSessionListener</listener-class>
</listener>
<!--
JENKINS-1235 suggests containers interpret '*' as "all roles defined in web.xml"
as opposed to "all roles defined in the security realm", so we need to list some
common names in the hope that users will have at least one of those roles.
-->
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
<security-role>
<role-name>hudson</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>Hudson</web-resource-name>
<url-pattern>/loginEntry</url-pattern>
<!--http-method>GET</http-method-->
</web-resource-collection>
<auth-constraint>
<role-name>**</role-name>
</auth-constraint>
</security-constraint>
<!-- Disable TRACE method with security constraint (copied from jetty/webdefaults.xml) -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Disable TRACE</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>other</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<!-- no security constraint -->
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login</form-login-page>
<form-error-page>/loginError</form-error-page>
</form-login-config>
</login-config>
<!-- configure additional extension-content-type mappings -->
<mime-mapping>
<extension>xml</extension>
<mime-type>application/xml</mime-type>
</mime-mapping>
<!--mime-mapping> commenting out until this works out of the box with JOnAS. See http://www.nabble.com/Error-with-mime-type%2D-%27application-xslt%2Bxml%27-when-deploying-hudson-1.316-in-jonas-td24740489.html
<extension>xsl</extension>
<mime-type>application/xslt+xml</mime-type>
</mime-mapping-->
<mime-mapping>
<extension>log</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
<mime-mapping>
<extension>war</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
<extension>ear</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
<extension>rar</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
<extension>webm</extension>
<mime-type>video/webm</mime-type>
</mime-mapping>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/oops</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
<session-config>
<cookie-config>
<!-- See https://www.owasp.org/index.php/HttpOnly for the discussion of this topic in OWASP -->
<http-only>true</http-only>
</cookie-config>
<!-- Tracking mode is managed by WebAppMain.FORCE_SESSION_TRACKING_BY_COOKIE_PROP -->
</session-config>
</web-fragment>
@@ -38,7 +38,7 @@ THE SOFTWARE.
placeholder="${%Search available plugins}"
id="filter-box"
autofocus="true"
value="${request.getParameter('filter')}" />
value="${request2.getParameter('filter')}" />
</div>
<div class="jenkins-app-bar__controls">
<l:isAdmin>
@@ -43,7 +43,7 @@ THE SOFTWARE.
placeholder="${%Search installed plugins}"
id="filter-box"
autofocus="true"
value="${request.getParameter('filter')}"
value="${request2.getParameter('filter')}"
enabled="${!noPlugins}" />
</div>
</div>
@@ -41,7 +41,7 @@ THE SOFTWARE.
placeholder="${%Search plugin updates}"
id="filter-box"
autofocus="true"
value="${request.getParameter('filter')}"
value="${request2.getParameter('filter')}"
enabled="${!empty(list)}" />
</div>
<div class="jenkins-app-bar__controls">
@@ -31,7 +31,7 @@ THE SOFTWARE.
<h1>
${%JVM Memory Usage}
</h1>
<j:set var="type" value="${request.getParameter('type') ?: 'min'}" />
<j:set var="type" value="${request2.getParameter('type') ?: 'min'}" />
<div>
${%Timespan}:
<j:choose>
@@ -30,14 +30,14 @@ THE SOFTWARE.
<j:if test="${it.getPrimaryView() != null}">
<j:set var="it" value="${it.getPrimaryView()}"/>
</j:if>
<j:set var="submissionUrl" value="${request.getParameter('submissionUrl')}" defaultValue="submitDescription"/>
<j:set var="submissionUrl" value="${request2.getParameter('submissionUrl')}" defaultValue="submitDescription"/>
<j:invokeStatic className="hudson.Util" method="isSafeToRedirectTo" var="isSafeToRedirectTo">
<j:arg value="${submissionUrl}"/>
</j:invokeStatic>
<j:if test="${!isSafeToRedirectTo}">
<j:set var="submissionUrl" value="submitDescription"/>
</j:if>
<j:set var="initialDescription" value="${request.getParameter('description')}" defaultValue="${it.description}"/>
<j:set var="initialDescription" value="${request2.getParameter('description')}" defaultValue="${it.description}"/>
<l:ajax>
<form action="${submissionUrl}" method="post">
<table>
@@ -31,8 +31,8 @@ THE SOFTWARE.
<st:include page="sidepanel.jelly" />
<l:breadcrumb title="${%Changes}" />
<l:main-panel>
<j:set var="from" value="${request.getParameter('from')}"/>
<j:set var="to" value="${request.getParameter('to')}"/>
<j:set var="from" value="${request2.getParameter('from')}"/>
<j:set var="to" value="${request2.getParameter('to')}"/>
<j:set var="browser" value="${it.scm.effectiveBrowser}"/> <!-- for compatibility; newer project-changes.jelly override this -->
<h1>
@@ -111,7 +111,7 @@ div {
section(class: "empty-state-section") {
ul(class: "empty-state-section-list") {
li(class: "content-block") {
a(href: "${rootURL}/${app.securityRealm.loginUrl}?from=${request.requestURI}",
a(href: "${rootURL}/${app.securityRealm.loginUrl}?from=${request2.requestURI}",
class: "content-block__link") {
span(_("Log in to Jenkins"))
span(class: "trailing-icon") {
@@ -32,7 +32,7 @@ THE SOFTWARE.
<l:main-panel>
<f:form method="post" action="doCreateItem" name="config" class="jenkins-form">
<f:entry title="${%Name}" help="${requestScope.descriptor.getHelpFile('name')}">
<f:textbox name="name" value="${request.getParameter('name')}" clazz="required" checkMessage="${%Name is mandatory}"/>
<f:textbox name="name" value="${request2.getParameter('name')}" clazz="required" checkMessage="${%Name is mandatory}"/>
</f:entry>
<!-- main body of the configuration -->
@@ -40,7 +40,7 @@ THE SOFTWARE.
<st:include class="${requestScope.descriptor.clazz}" page="configure-entries.jelly" />
<f:bottomButtonBar>
<input type="hidden" name="type" value="${request.getParameter('mode')}"/>
<input type="hidden" name="type" value="${request2.getParameter('mode')}"/>
<f:submit value="${%Save}"/>
</f:bottomButtonBar>
@@ -30,7 +30,7 @@ THE SOFTWARE.
<j:invoke var="buildClass" on="${currentThread.contextClassLoader}" method="loadClass">
<j:arg value="hudson.model.Run" />
</j:invoke>
<j:set var="build" value="${request.findAncestorObject(buildClass)}" />
<j:set var="build" value="${request2.findAncestorObject(buildClass)}" />
<st:include page="sidepanel.jelly" it="${build}" />
<l:main-panel>
<t:buildCaption it="${build}">${title}</t:buildCaption>
@@ -40,7 +40,7 @@ THE SOFTWARE.
<l:main-panel>
<h1>${it.job.pronoun} ${it.job.displayName}</h1>
<p class="jenkins-description">${%description}</p>
<j:set var="delay" value="${request.getParameter('delay')}" />
<j:set var="delay" value="${request2.getParameter('delay')}" />
<f:form method="post" action="build${empty(delay)?'':'?delay='+delay}" name="parameters"
tableClass="parameters" class="jenkins-form">
<j:forEach var="parameterDefinition" items="${it.parameterDefinitions}">
@@ -20,7 +20,7 @@
<tr><td>
<div id="delete-error" style="display: none">
<pre>
${request.getAttribute('stackTraces')}
${request2.getAttribute('stackTraces')}
</pre>
</div>
</td></tr>
@@ -44,7 +44,7 @@ THE SOFTWARE.
</l:main-panel>
<l:header>
<!-- for screen resolution detection -->
<script id="screenResolution-script" data-use-secure-cookie="${request.secure}"/>
<script id="screenResolution-script" data-use-secure-cookie="${request2.secure}"/>
<st:adjunct includes="hudson.model.View.screen-resolution"/>
</l:header>
</l:layout>
@@ -27,7 +27,7 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
<j:set var="q" value="${request.getParameter('q')}"/>
<j:set var="q" value="${request2.getParameter('q')}"/>
<j:new var="h" className="hudson.Functions" /><!-- needed for printing title. -->
<l:layout title="${%Search for} '${q}'">
<l:main-panel>
@@ -48,7 +48,7 @@ THE SOFTWARE.
</j:forEach>
</ol>
<j:if test="${items.hasMoreResults()}">
<j:set var="max" value="${request.hasParameter('max')?request.getParameter('max'):100}"/>
<j:set var="max" value="${request2.hasParameter('max')?request2.getParameter('max'):100}"/>
<j:choose>
<j:when test="${max &gt; it.getMaxSearchSize()}">
<em>Only showing the first ${it.getMaxSearchSize()} results,
@@ -10,7 +10,7 @@ def f=namespace(lib.FormTagLib)
def l=namespace(lib.LayoutTagLib)
def st=namespace("jelly:stapler")
l.layout(permission:app.SYSTEM_READ, title:my.displayName, cssclass:request.getParameter('decorate'), type:"one-column") {
l.layout(permission:app.SYSTEM_READ, title:my.displayName, cssclass:request2.getParameter('decorate'), type:"one-column") {
l.main_panel {
l.app_bar(title: my.displayName)
@@ -34,13 +34,13 @@ THE SOFTWARE.
needed to generate a session if non exists,
without it we would add ";jsessionid=" to the url which will result in a 404
-->
<j:set var="_" value="${request.getSession()}"/>
<j:set var="_" value="${request2.getSession()}"/>
<x:doctype name="html"/>
<!-- in case of error we want to surround the form elements with an error hint -->
<j:set var="inputClass" value="${data.errorMessage!=null ? 'jenkins-input--error' : ''}"/>
<j:set var="simpleDecorator" value="${h.simplePageDecorator}"/>
<j:set var="simpleDecorators" value="${h.simplePageDecorators}"/>
<html lang="${request.getLocale().toLanguageTag()}">
<html lang="${request2.getLocale().toLanguageTag()}">
<head data-rooturl="${rootURL}" data-resurl="${resURL}" data-imagesurl="${imagesURL}" resURL="${resURL}">
<title>${%Register} - Jenkins</title>
<!-- we do not want bots on this page -->
@@ -65,7 +65,7 @@ THE SOFTWARE.
<h2>Request Headers</h2>
<table>
<j:forEach var="n" items="${request.getHeaderNames()}">
<j:forEach var="n" items="${request2.getHeaderNames()}">
<j:choose>
<j:when test="${it.isHeaderDangerous(n)}" >
<tr>
@@ -32,7 +32,7 @@ THE SOFTWARE.
<!-- get default/common page variable -->
${h.initPageVariables(context)}
<x:doctype name="html" />
<html lang="${request.getLocale().toLanguageTag()}">
<html lang="${request2.getLocale().toLanguageTag()}">
<head data-rooturl="${rootURL}" data-resurl="${resURL}" data-imagesurl="${imagesURL}" resURL="${resURL}">
<title>${%Starting Jenkins}</title>
<!-- we do not want bots on this page -->
@@ -32,7 +32,7 @@ THE SOFTWARE.
<!-- get default/common page variable -->
${h.initPageVariables(context)}
<x:doctype name="html" />
<html lang="${request.getLocale().toLanguageTag()}">
<html lang="${request2.getLocale().toLanguageTag()}">
<head data-rooturl="${rootURL}" data-resurl="${resURL}" data-imagesurl="${imagesURL}" resURL="${resURL}">
<title>${%Restarting Jenkins}</title>
<!-- we do not want bots on this page -->
@@ -37,7 +37,7 @@ THE SOFTWARE.
<st:include it="${requestScope.instance}" class="${requestScope.descriptor.clazz}" page="config.jelly" optional="true" />
<f:bottomButtonBar>
<input type="hidden" name="cloudDescriptorName" value="${request.getParameter('mode')}"/>
<input type="hidden" name="cloudDescriptorName" value="${request2.getParameter('mode')}"/>
<f:submit value="${%Save}"/>
</f:bottomButtonBar>
@@ -5,7 +5,7 @@
<l:main-panel>
<st:include page="client-scripts" />
<form action="${app.instance.securityRealm.authenticationGatewayUrl}" method="POST">
<input type="hidden" name="from" value="${request.getParameter('from')}" />
<input type="hidden" name="from" value="${request2.getParameter('from')}" />
<div class="plugin-setup-wizard bootstrap-3">
<div class="modal fade in" style="display: block;">
<div class="modal-dialog">
@@ -28,8 +28,8 @@ THE SOFTWARE.
This is the page designated by web.xml to handle 404 errors. Show a nice error message and suggest logging in if applicable.
Generally kept very similar to 'oops.jelly'.
-->
<st:statusCode value="${response.getStatus()}" />
${request.session.setAttribute('from', request.getAttribute('jakarta.servlet.error.request_uri'))}
<st:statusCode value="${response2.getStatus()}" />
${request2.session.setAttribute('from', request2.getAttribute('jakarta.servlet.error.request_uri'))}
<l:layout title="${%title(jakarta.servlet.error.message?:'Not Found')}" type="one-column">
<l:header />
<l:main-panel>
@@ -39,7 +39,7 @@ THE SOFTWARE.
</h1>
<div id="error-description" style="text-align: center">
<h2>${%title(jakarta.servlet.error.message?:'Not Found')}</h2>
<j:if test="${!request.getAttribute('jenkins.security.ResourceDomainRootAction.error')}">
<j:if test="${!request2.getAttribute('jenkins.security.ResourceDomainRootAction.error')}">
<p>
<j:choose>
<j:when test="${app.useSecurity}">
@@ -36,7 +36,7 @@ THE SOFTWARE.
<st:setHeader name="Referrer-Policy" value="same-origin" />
<st:setHeader name="Cross-Origin-Opener-Policy" value="same-origin" />
<x:doctype name="html" />
<st:statusCode value="${response.getStatus()}" />
<st:statusCode value="${response2.getStatus()}" />
<html>
<head>
<title>${%title(jakarta.servlet.error.message?:'Not Found')}</title>
@@ -29,7 +29,7 @@ THE SOFTWARE.
<st:setHeader name="Expires" value="0" />
<st:setHeader name="Cache-Control" value="no-cache,no-store,must-revalidate" />
<!-- needed for cli -->
<j:if test="${request.servletPath=='/' || request.servletPath==''}">
<j:if test="${request2.servletPath=='/' || request2.servletPath==''}">
${h.advertiseHeaders(response)}
<j:forEach var="pd" items="${h.pageDecorators}">
<st:include it="${pd}" page="httpHeaders.jelly" optional="true"/>
@@ -39,19 +39,19 @@ THE SOFTWARE.
needed to generate a session if non exists,
without it we would add ";jsessionid=" to the url which will result in a 404
-->
<j:set var="_" value="${request.getSession()}"/>
<j:set var="_" value="${request2.getSession()}"/>
<!-- get default/common page variable -->
${h.initPageVariables(context)}
<x:doctype name="html" />
<!-- needed for the redirect after login -->
<j:set var="from" value="${error ? request.session.getAttribute('from') : request.getParameter('from')}"/>
<j:set var="from" value="${error ? request2.session.getAttribute('from') : request2.getParameter('from')}"/>
<!-- in case of error we want to surround the form elements with an error hint -->
<j:set var="inputClass" value="${error ? 'jenkins-input--error' : ''}"/>
<j:set var="simpleDecorator" value="${h.simplePageDecorator}"/>
<j:set var="simpleDecorators" value="${h.simplePageDecorators}"/>
<!-- real deal starting here -->
<html lang="${request.getLocale().toLanguageTag()}">
<html lang="${request2.getLocale().toLanguageTag()}">
<head data-rooturl="${rootURL}" data-resurl="${resURL}" data-imagesurl="${imagesURL}" resURL="${resURL}">
<title>${%signIn} - Jenkins</title>
<!-- we do not want bots on this page -->
@@ -27,7 +27,7 @@ THE SOFTWARE.
<!--
This is the page designated by web.xml and UncaughtExceptionHandler to process an exception thrown by us.
-->
<st:statusCode value="${response.getStatus()}" />
<st:statusCode value="${response2.getStatus()}" />
<l:layout title="Jenkins" type="one-column">
<l:header />
<l:main-panel>
@@ -36,12 +36,12 @@ THE SOFTWARE.
</h1>
<div id="error-description">
<h2 style="text-align: center">${%problemHappened}</h2>
<p style="text-align: center">Logging ID=${request.getAttribute('jenkins.exception.id')}</p>
<p style="text-align: center">Logging ID=${request2.getAttribute('jenkins.exception.id')}</p>
</div>
<j:if test="${app.shouldShowStackTrace()}">
<p>${%checkJIRA} ${%vote} ${%pleaseReport} ${%stackTracePlease} ${%checkML}</p>
<h2>${%Stack trace}</h2>
<pre style="margin:2em; clear:both">${h.printThrowable(request.getAttribute('jakarta.servlet.error.exception'))}</pre>
<pre style="margin:2em; clear:both">${h.printThrowable(request2.getAttribute('jakarta.servlet.error.exception'))}</pre>
</j:if>
</l:main-panel>
</l:layout>
@@ -44,25 +44,25 @@ THE SOFTWARE.
<form action="projectRelationship" method="get">
<div class="jenkins-form-item">
<label class="jenkins-form-label" for="lhs">${%upstream project}:</label>
<f:combobox id="lhs" fillUrl="fillJobNameItems" name="lhs" value="${request.getParameter('lhs')}"/>
<f:combobox id="lhs" fillUrl="fillJobNameItems" name="lhs" value="${request2.getParameter('lhs')}"/>
</div>
<div class="jenkins-form-item">
<label class="jenkins-form-label" for="rhs">${%downstream project}:</label>
<f:combobox id="rhs" fillUrl="fillJobNameItems" name="rhs" value="${request.getParameter('rhs')}"/>
<f:combobox id="rhs" fillUrl="fillJobNameItems" name="rhs" value="${request2.getParameter('rhs')}"/>
</div>
<f:submit value="${%Compare}"/>
<j:if test="${!empty(request.getParameter('lhs')) and !empty(request.getParameter('rhs'))}">
<j:set var="jl" value="${app.getItemByFullName(request.getParameter('lhs'))}"/>
<j:set var="jr" value="${app.getItemByFullName(request.getParameter('rhs'))}"/>
<j:if test="${!empty(request2.getParameter('lhs')) and !empty(request2.getParameter('rhs'))}">
<j:set var="jl" value="${app.getItemByFullName(request2.getParameter('lhs'))}"/>
<j:set var="jr" value="${app.getItemByFullName(request2.getParameter('rhs'))}"/>
<j:choose>
<j:when test="${jl==null}">
<p class="error">No such project '${request.getParameter('lhs')}'</p>
<p class="error">No such project '${request2.getParameter('lhs')}'</p>
</j:when>
<j:when test="${jr==null}">
<p class="error">No such project '${request.getParameter('rhs')}'</p>
<p class="error">No such project '${request2.getParameter('rhs')}'</p>
</j:when>
<j:otherwise>
<table width="100%">
@@ -13,7 +13,7 @@
id="user-seed-property-reset-seed"
data-target-url="${descriptor.descriptorFullUrl}/renewSessionSeed"
data-confirm="${%resetSeed.confirmation}"
data-redirect-url="${request.contextPath}/"
data-redirect-url="${request2.contextPath}/"
data-confirm-title="${%resetSeed.confirmationTitle}">
${%resetSeed.button}
</button>
@@ -41,8 +41,8 @@ THE SOFTWARE.
</st:documentation>
<st:once>
<script type="text/javascript" src="${request.contextPath}/scripts/utilities.js"/>
<script type="text/javascript" src="${request.contextPath}/scripts/combobox.js"/>
<script type="text/javascript" src="${request2.contextPath}/scripts/utilities.js"/>
<script type="text/javascript" src="${request2.contextPath}/scripts/combobox.js"/>
</st:once>
<f:prepareDatabinding/>
@@ -81,7 +81,7 @@ THE SOFTWARE.
<td class="pane">
<div style="white-space: normal">
<j:choose>
<j:when test="${exeparent != null}">
<j:when test="${exe == null and exeparent != null }">
<j:choose>
<j:when test="${exeparentcanread}">
<a href="${rootURL}/${exeparent.url}"><l:breakable value="${exeparent.fullDisplayName}"/></a>
@@ -46,7 +46,7 @@ THE SOFTWARE.
</p>
<form action="script" method="post">
<textarea id="script" name="script" class="script">${request.getParameter('script')}</textarea>
<textarea id="script" name="script" class="script">${request2.getParameter('script')}</textarea>
<div align="right">
<f:submit value="${%Run}"/>
</div>
@@ -1,10 +1,16 @@
/**
* Use the `widget-refresh-reference` class on an element with `data-id` and `data-url` attributes.
* The content from the URL will be used to replace the element with the specified ID.
* Usually the URL content is an element with the same ID as specified here, to allow continuous updates.
* This is primarily used for sidepanel widgets, but not exclusively.
*/
Behaviour.specify(
".widget-refresh-reference",
"widget-refresh",
0,
function (e) {
var id = e.getAttribute("data-id");
var url = e.getAttribute("data-url");
let id = e.getAttribute("data-id");
let url = e.getAttribute("data-url");
refreshPart(id, url);
},
);
@@ -41,7 +41,7 @@ THE SOFTWARE.
<div id="breadcrumbBar" class="jenkins-breadcrumbs" aria-label="breadcrumb">
<ol class="jenkins-breadcrumbs__list" id="breadcrumbs">
<j:forEach var="anc" items="${request.ancestors}" indexVar="index">
<j:forEach var="anc" items="${request2.ancestors}" indexVar="index">
<j:if test="${h.isModel(anc.object) and anc.prev.url!=anc.url}">
<j:set var="mode" value="breadcrumbs" />
<l:breadcrumb title="${anc.object == app ? '%Dashboard' : anc.object.displayName}"
@@ -90,9 +90,9 @@ THE SOFTWARE.
<j:set var="layoutType" value="${attrs.type}"/>
</j:if>
<j:set var="_" value="${request.getSession()}"/>
<j:set var="_" value="${request2.getSession()}"/>
<j:set var="extensionsAvailable" value="${h.extensionsAvailable}"/>
<j:if test="${request.servletPath=='/' || request.servletPath==''}">
<j:if test="${request2.servletPath=='/' || request2.servletPath==''}">
${h.advertiseHeaders(response)}
<j:if test="${extensionsAvailable}">
<j:forEach var="pd" items="${h.pageDecorators}">
@@ -23,9 +23,9 @@ Behaviour.specify("a.task-link-no-confirm", "task-link", 0, function (el) {
headers: crumb.wrap({}),
}).then((rsp) => {
if (rsp.ok) {
notificationBar(success, notificationBar.SUCCESS);
notificationBar.show(success, notificationBar.SUCCESS);
} else {
notificationBar(failure, notificationBar.ERROR);
notificationBar.show(failure, notificationBar.ERROR);
}
});
ev.preventDefault();
-7
View File
@@ -239,13 +239,6 @@
<Class name="jenkins.util.xml.XMLUtils"/>
</Or>
</And>
<And>
<Bug pattern="INSECURE_COOKIE"/>
<Or>
<Class name="hudson.security.SecurityRealm"/>
<Class name="jenkins.model.Jenkins"/>
</Or>
</And>
<And>
<Bug pattern="LI_LAZY_INIT_STATIC"/>
<Class name="hudson.triggers.Trigger"/>
@@ -81,13 +81,16 @@ public class MarkupTextTest {
* Start/end tag nesting should be correct regardless of the order tags are added.
*/
@Test
public void adjacent() {
public void addMarkupInOrder() {
MarkupText text = new MarkupText("abcdef");
text.addMarkup(0, 3, "$", "$");
text.addMarkup(3, 6, "#", "#");
assertEquals("$abc$#def#", text.toString(false));
}
text = new MarkupText("abcdef");
@Test
public void addMarkupInReversedOrder() {
MarkupText text = new MarkupText("abcdef");
text.addMarkup(3, 6, "#", "#");
text.addMarkup(0, 3, "$", "$");
assertEquals("$abc$#def#", text.toString(false));
@@ -27,18 +27,22 @@ package hudson.scheduler;
import static java.util.Calendar.MONDAY;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import antlr.ANTLRException;
import java.text.DateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.function.Function;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
@@ -340,6 +344,24 @@ public class CronTabTest {
assertEquals("[35, 56]", times.toString());
}
@Test public void floorCeilMinuteGranularity() throws Exception {
var tab = new CronTab("*/5 * * * *");
assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 23), "2025-03-04T14:15:00", "2025-03-04T14:20:00");
assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 23), "2025-03-04T14:15:00", "2025-03-04T14:20:00");
assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 16, 0), "2025-03-04T14:15:00", "2025-03-04T14:20:00");
assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 19, 0), "2025-03-04T14:15:00", "2025-03-04T14:20:00");
assertFloorCeil(tab, new GregorianCalendar(2025, 2, 4, 14, 15, 0), "2025-03-04T14:15:00", "2025-03-04T14:15:00");
}
private static void assertFloorCeil(CronTab tab, Calendar now, String expectedFloor, String expectedCeil) {
Function<Calendar, String> fmt = c -> ZonedDateTime.ofInstant(c.toInstant(), c.getTimeZone().toZoneId()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
var nowFormatted = fmt.apply(now);
var nowClone = (Calendar) now.clone();
assertThat("floor of " + nowFormatted, fmt.apply(tab.floor(nowClone)), is(expectedFloor));
nowClone = (Calendar) now.clone();
assertThat("ceil of " + nowFormatted, fmt.apply(tab.ceil(nowClone)), is(expectedCeil));
}
@Issue("SECURITY-790")
@Test(timeout = 1000L) public void testLongMonths() throws Exception {
Calendar cal = Calendar.getInstance();
@@ -7,10 +7,14 @@ import static org.junit.Assert.assertTrue;
import hudson.FilePath;
import hudson.Functions;
import hudson.Util;
import hudson.util.TextFile;
import java.io.File;
import java.io.IOException;
import java.nio.charset.MalformedInputException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.SecureRandom;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -20,6 +24,8 @@ public class DefaultConfidentialStoreTest {
@Rule
public TemporaryFolder tmpRule = new TemporaryFolder();
private final SecureRandom sr = new SecureRandom();
@Test
public void roundtrip() throws Exception {
File tmp = new File(tmpRule.getRoot(), "tmp"); // let ConfidentialStore create a directory
@@ -27,20 +33,8 @@ public class DefaultConfidentialStoreTest {
DefaultConfidentialStore store = new DefaultConfidentialStore(tmp);
ConfidentialKey key = new ConfidentialKey("test") {};
// basic roundtrip
String str = "Hello world!";
store.store(key, str.getBytes(StandardCharsets.UTF_8));
assertEquals(str, new String(store.load(key), StandardCharsets.UTF_8));
// data storage should have some stuff
assertTrue(new File(tmp, "test").exists());
assertTrue(new File(tmp, "master.key").exists());
assertThrows(MalformedInputException.class, () -> Files.readString(tmp.toPath().resolve("test"), StandardCharsets.UTF_8)); // the data shouldn't be a plain text, obviously
if (!Functions.isWindows()) {
assertEquals(0700, new FilePath(tmp).mode() & 0777); // should be read only
}
roundTrip(store, key, tmp);
// if the master key changes, we should gracefully fail to load the store
new File(tmp, "master.key").delete();
@@ -49,4 +43,42 @@ public class DefaultConfidentialStoreTest {
assertNull(store2.load(key));
}
private static void roundTrip(DefaultConfidentialStore store, ConfidentialKey key, File tmp) throws IOException, InterruptedException {
// basic roundtrip
String str = "Hello world!";
store.store(key, str.getBytes(StandardCharsets.UTF_8));
assertEquals(str, new String(store.load(key), StandardCharsets.UTF_8));
// data storage should have some stuff
assertTrue(new File(tmp, "test").exists());
assertThrows(MalformedInputException.class, () -> Files.readString(tmp.toPath().resolve("test"), StandardCharsets.UTF_8)); // the data shouldn't be a plain text, obviously
if (!Functions.isWindows()) {
assertEquals(0700, new FilePath(tmp).mode() & 0777); // should be read only
}
}
@Test
public void masterKeyGeneratedBeforehand() throws IOException, InterruptedException {
File external = new File(tmpRule.getRoot(), "external");
File tmp = new File(tmpRule.getRoot(), "tmp");
var masterKeyFile = new File(external, "master.key");
new TextFile(masterKeyFile).write(Util.toHexString(randomBytes(128)));
System.setProperty(DefaultConfidentialStore.MASTER_KEY_FILE_SYSTEM_PROPERTY, masterKeyFile.getAbsolutePath());
System.setProperty(DefaultConfidentialStore.MASTER_KEY_READONLY_SYSTEM_PROPERTY_NAME, "true");
DefaultConfidentialStore store = new DefaultConfidentialStore(tmp);
ConfidentialKey key = new ConfidentialKey("test") {};
roundTrip(store, key, tmp);
// With this configuration, the master key file deletion is fatal
masterKeyFile.delete();
assertThrows(IOException.class, () -> new DefaultConfidentialStore(tmp));
}
private byte[] randomBytes(int size) {
byte[] random = new byte[size];
sr.nextBytes(random);
return random;
}
}
+8 -8
View File
@@ -24,28 +24,28 @@
},
"devDependencies": {
"@babel/cli": "7.26.4",
"@babel/core": "7.26.7",
"@babel/preset-env": "7.26.7",
"@eslint/js": "9.19.0",
"@babel/core": "7.26.8",
"@babel/preset-env": "7.26.8",
"@eslint/js": "9.20.0",
"babel-loader": "9.2.1",
"clean-webpack-plugin": "4.0.0",
"css-loader": "7.1.2",
"css-minimizer-webpack-plugin": "7.0.0",
"eslint": "9.19.0",
"eslint": "9.20.0",
"eslint-config-prettier": "10.0.1",
"eslint-formatter-checkstyle": "8.40.0",
"globals": "15.14.0",
"handlebars-loader": "1.7.3",
"mini-css-extract-plugin": "2.9.2",
"postcss": "8.5.1",
"postcss": "8.5.2",
"postcss-loader": "8.1.1",
"postcss-preset-env": "10.1.3",
"postcss-scss": "4.0.9",
"prettier": "3.4.2",
"sass": "1.83.4",
"prettier": "3.5.0",
"sass": "1.84.0",
"sass-loader": "16.0.4",
"style-loader": "4.0.0",
"stylelint": "16.14.0",
"stylelint": "16.14.1",
"stylelint-checkstyle-reporter": "1.0.0",
"stylelint-config-standard-scss": "14.0.0",
"webpack": "5.97.1",
+3 -3
View File
@@ -73,9 +73,9 @@ THE SOFTWARE.
</issueManagement>
<properties>
<revision>2.496</revision>
<revision>2.498</revision>
<changelist>-SNAPSHOT</changelist>
<project.build.outputTimestamp>2025-01-28T13:58:52Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2025-02-11T14:10:23Z</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.2</node.version>
<node.version>20.18.3</node.version>
</properties>
<!--
+1 -2
View File
@@ -183,13 +183,12 @@
}
li {
@include mixins.item;
@include mixins.item($border: false);
-webkit-touch-callout: none;
user-select: none;
padding: 0.75rem 1rem;
min-height: 68px;
cursor: pointer;
display: grid;
grid-template-columns: auto 1fr;
gap: 0.25rem 1rem;
+20 -5
View File
@@ -56,11 +56,17 @@
}
}
@mixin item {
@mixin item($border: true) {
position: relative;
appearance: none;
z-index: 0;
text-decoration: none !important;
border-radius: 0.66rem;
font-weight: normal;
border-radius: var(--form-input-border-radius);
cursor: pointer;
background: transparent;
outline: none;
border: none;
&::before,
&::after {
@@ -74,11 +80,12 @@
}
&::before {
background-color: transparent;
background-color: var(--item-background);
border: var(--jenkins-border--subtle);
}
&::after {
box-shadow: 0 0 0 0.66rem transparent;
box-shadow: 0 0 0 0.5rem transparent;
}
&:focus-visible {
@@ -102,7 +109,7 @@
}
&::after {
box-shadow: 0 0 0 0.33rem var(--item-box-shadow--focus);
box-shadow: 0 0 0 0.25rem var(--item-box-shadow--focus);
}
}
@@ -113,4 +120,12 @@
}
}
}
@if $border == false {
&:not(:hover, &:active, &:focus) {
&::before {
border-color: transparent;
}
}
}
}
+78 -17
View File
@@ -31,11 +31,12 @@ $semantics: (
:root,
.app-theme-picker__picker[data-theme="none"] {
// Font related properties
--font-family-sans: system-ui, "Segoe UI", roboto, "Noto Sans", oxygen,
ubuntu, cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", arial,
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
--font-family-mono: ui-monospace, sfmono-regular, sf mono, jetbrainsmono,
consolas, monospace;
--font-family-sans:
system-ui, "Segoe UI", roboto, "Noto Sans", oxygen, ubuntu, cantarell,
"Fira Sans", "Droid Sans", "Helvetica Neue", arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
--font-family-mono:
ui-monospace, sfmono-regular, sf mono, jetbrainsmono, consolas, monospace;
--font-size-base: 1rem; // 16px
--font-size-sm: 0.875rem; // 14px
--font-size-xs: 0.75rem; // 12px
@@ -80,6 +81,13 @@ $semantics: (
from var(--text-color) 96.8% 0.005 h / 0.8
);
// App bar
--bottom-app-bar-shadow: color-mix(
in sRGB,
var(--text-color-secondary) 7.5%,
transparent
);
// Alert call outs
--alert-success-text-color: var(--success-color);
--alert-success-bg-color: color-mix(
@@ -125,8 +133,41 @@ $semantics: (
// Typography
--text-color-secondary: var(--secondary);
// Borders
--jenkins-border-width: 1.5px;
--jenkins-border-color: color-mix(
in sRGB,
var(--text-color-secondary) 12%,
var(--card-background)
);
--jenkins-border-color--subtle: color-mix(
in sRGB,
currentColor 1.5%,
transparent
);
/* This is a harsher border - for dividers, content blocks and more */
--jenkins-border: var(--jenkins-border-width) solid
var(--jenkins-border-color);
/* This is a subtle border - for increasing contrast on elements, such as buttons, menu and more */
--jenkins-border--subtle: var(--jenkins-border-width) solid
var(--jenkins-border-color--subtle);
--jenkins-border--subtle-shadow: 0 0 0 1.5px
var(--jenkins-border-color--subtle);
@media (resolution <= 1x) {
--jenkins-border-width: 2px;
}
@media (prefers-contrast: more) {
--focus-input-border: var(--text-color);
--jenkins-border-color: var(--text-color);
--jenkins-border-color--subtle: var(--text-color);
}
// Table
--table-background: oklch(from var(--text-color-secondary) l c h / 0.1);
--table-background: oklch(from var(--text-color-secondary) l c h / 0.075);
--table-header-foreground: var(--text-color);
--table-body-background: var(--background);
--table-body-foreground: var(--text-color);
@@ -158,7 +199,9 @@ $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 rgb(255 255 255 / 0.1);
--command-palette-inset-shadow:
inset 0 0 2px 2px rgb(255 255 255 / 0.1),
var(--jenkins-border--subtle-shadow);
::backdrop {
--command-palette-backdrop-background: radial-gradient(
@@ -171,12 +214,14 @@ $semantics: (
// Tooltips
--tooltip-backdrop-filter: saturate(2) blur(20px);
--tooltip-color: var(--text-color);
--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);
--tooltip-box-shadow:
0 0 8px 2px rgb(0 0 50 / 0.05), var(--jenkins-border--subtle-shadow),
0 10px 50px rgb(0 0 20 / 0.1);
// Dropdowns
--dropdown-backdrop-filter: saturate(1.5) blur(20px);
--dropdown-box-shadow: 0 10px 30px rgb(0 0 20 / 0.2),
--dropdown-box-shadow:
var(--jenkins-border--subtle-shadow), 0 10px 30px rgb(0 0 20 / 0.1),
0 2px 10px rgb(0 0 20 / 0.05), inset 0 -1px 2px rgb(255 255 255 / 0.025);
// Dialogs
@@ -184,7 +229,8 @@ $semantics: (
--dialog-backdrop-background: hsl(240 10% 20% / 0.8);
}
--dialog-box-shadow: 0 10px 40px rgb(0 0 20 / 0.15),
--dialog-box-shadow:
var(--jenkins-border--subtle-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
@@ -219,12 +265,20 @@ $semantics: (
--card-border-color--active: oklch(
from var(--text-color-secondary) l c h / 0.5
);
--card-border-width: 2px;
--card-border-width: var(--jenkins-border-width);
@media (prefers-contrast: more) {
--card-border-color: var(--text-color);
}
// Tab bar
--tabs-background: oklch(from var(--text-color-secondary) l c h / 0.1);
--tabs-item-background: transparent;
--tabs-item-foreground: var(--text-color);
--tabs-item-foreground: color-mix(
in sRGB,
var(--text-color-secondary),
var(--text-color)
);
--tabs-item-background--hover: rgb(0 0 0 / 0.05);
--tabs-item-foreground--hover: var(--text-color);
--tabs-item-background--active: rgb(0 0 0 / 0.1);
@@ -268,14 +322,21 @@ $semantics: (
}
--form-label-font-weight: var(--font-bold-weight);
--form-input-padding: 0.625rem;
--form-input-padding: 0.5rem 0.625rem;
--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: rgb(0 0 0 / 0.05);
--form-input-glow: 0 0 0 0.5rem transparent;
--form-input-glow--focus: 0 0 0 0.25rem var(--focus-input-glow);
--pre-background: var(--button-background);
--pre-color: var(--text-color);
--selection-color: oklch(from var(--accent-color) l c h / 0.2);
@media (prefers-contrast: more) {
--input-border: var(--text-color) !important;
--input-border-hover: var(--text-color) !important;
--form-input-glow--focus: 0 0 0 4px
color-mix(in sRGB, var(--text-color), transparent);
}
// Animations
--standard-transition: 0.3s ease;
--elastic-transition: 0.3s cubic-bezier(0, 0.68, 0.5, 1.5);
+5 -12
View File
@@ -152,6 +152,7 @@ pre {
margin: 0 0 var(--section-padding);
padding: 0.8rem 1rem;
border-radius: var(--form-input-border-radius);
border: var(--jenkins-border--subtle);
background-color: var(--pre-background);
color: var(--pre-color);
font-family: var(--font-family-mono);
@@ -290,21 +291,13 @@ pre.console {
padding: 1rem;
margin: 1rem 0;
word-break: break-word;
border-radius: 6px;
border-radius: var(--form-input-border-radius);
background-color: var(--button-background);
border: var(--jenkins-border--subtle);
z-index: 0;
--section-padding: 0.8rem;
&::before {
content: "";
position: absolute;
inset: 0;
background: var(--text-color);
opacity: 0.05;
z-index: -1;
border-radius: inherit;
}
p:first-of-type {
margin-top: 0;
}
@@ -536,7 +529,7 @@ table.fingerprint-in-build td {
top: 0;
left: 10px;
bottom: 0;
width: 2px;
width: var(--jenkins-border-width);
background: var(--input-border);
border-radius: 2px;
transition: var(--standard-transition);
+6 -2
View File
@@ -2,8 +2,8 @@
.jenkins-alert {
font-size: var(--font-size-sm);
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
margin-bottom: var(--section-padding);
border: var(--jenkins-border-width) solid transparent;
border-radius: var(--form-input-border-radius);
strong {
@@ -52,4 +52,8 @@
color: var(--alert-danger-text-color);
}
}
@media (prefers-contrast: more) {
border-color: var(--text-color);
}
}
+1 -1
View File
@@ -151,7 +151,7 @@
top: -30px;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(#556, 0.075) 110%);
background: linear-gradient(transparent, var(--bottom-app-bar-shadow) 110%);
max-width: 100%;
height: 30px;
opacity: 0;
+1 -2
View File
@@ -30,7 +30,7 @@
padding: 0.2rem 0.4rem;
& > a {
@include mixins.item;
@include mixins.item($border: false);
display: inline-flex;
align-items: center;
@@ -40,7 +40,6 @@
margin: 0;
padding: 0;
color: var(--text-color);
text-decoration: none;
margin-right: 0 !important;
transition: var(--standard-transition);
+27 -118
View File
@@ -1,34 +1,24 @@
@use "../abstracts/mixins";
.jenkins-button {
--item-background: var(--button-background);
--item-background--hover: var(--button-background--hover);
--item-background--active: var(--button-background--active);
--item-box-shadow--focus: var(--button-box-shadow--focus);
@include mixins.item;
appearance: none;
display: inline-flex;
align-items: center;
justify-content: center;
border: none;
outline: none;
margin: 0;
padding: 0.5rem 0.9rem;
padding: 0.5rem 1rem;
font-size: var(--font-size-sm);
font-weight: normal;
text-decoration: none !important;
background: transparent;
color: var(--text-color) !important;
cursor: pointer;
min-height: 2.25rem;
min-height: 2.375rem;
white-space: nowrap;
gap: 1ch;
&::before {
background: var(--button-background);
}
svg {
width: 1.125rem;
height: 1.125rem;
@@ -42,118 +32,41 @@
}
.jenkins-button--primary {
--button-background: oklch(from var(--accent-color) l c h);
--button-background--hover: oklch(from var(--accent-color) l c h / 0.9);
--button-background--active: oklch(from var(--accent-color) l c h / 0.8);
--button-box-shadow--focus: oklch(from var(--accent-color) l c h / 0.4);
color: var(--button-color--primary) !important;
&::before {
background: var(--accent-color) !important;
}
&::after {
box-shadow: 0 0 0 0.66rem var(--accent-color);
opacity: 0;
}
&:not(:disabled) {
&:hover {
&::before {
opacity: 0.9;
}
}
&:active,
&:focus-visible {
&::before {
opacity: 0.8;
}
&::after {
box-shadow: 0 0 0 0.33rem var(--accent-color);
opacity: 0.2;
}
}
}
}
.jenkins-button--tertiary {
&::before {
background: transparent;
}
}
// Support for custom colors
// Modifier classes must include 'color' in name to work
.jenkins-button[class*="color"] {
background: transparent;
--button-background: oklch(from currentColor l c h / 0.1);
--button-background--hover: oklch(from currentColor l c h / 0.15);
--button-background--active: oklch(from currentColor l c h / 0.25);
--button-box-shadow--focus: oklch(from currentColor l c h / 0.125);
color: var(--color) !important;
&::before {
background: currentColor !important;
opacity: 0.1;
}
&::after {
box-shadow: 0 0 0 0.66rem currentColor;
opacity: 0;
}
&:not(:disabled) {
&:hover {
&::before {
opacity: 0.15;
}
}
&:active {
&::before {
opacity: 0.2;
}
&::after {
box-shadow: 0 0 0 0.33rem currentColor;
opacity: 0.1;
}
}
}
}
.jenkins-button--primary[class*="color"] {
background: transparent;
--button-background: oklch(from var(--color) l c h);
--button-background--hover: oklch(from var(--color) l c h / 0.9);
--button-background--active: oklch(from var(--color) l c h / 0.8);
--button-box-shadow--focus: oklch(from var(--color) l c h / 0.4);
color: var(--background) !important;
&::before {
background: var(--color) !important;
opacity: 1;
}
&::after {
box-shadow: 0 0 0 0.66rem var(--color);
opacity: 0;
}
&:not(:disabled) {
&:hover {
&::before {
opacity: 0.9;
}
}
&:active,
&:focus-visible {
&::before {
opacity: 0.8;
}
&::after {
box-shadow: 0 0 0 0.33rem var(--color);
opacity: 0.3;
}
}
}
}
.jenkins-button--tertiary[class*="color"] {
&::before {
opacity: 0;
.jenkins-button--tertiary {
--button-background: transparent !important;
&:not(:hover, &:active, &:focus) {
&::before {
border-color: transparent;
}
}
}
@@ -249,7 +162,7 @@
in sRGB,
var(--success-color) 10%,
transparent
);
) !important;
--button-background--hover: var(--button-background);
--button-background--active: var(--button-background);
@@ -352,13 +265,13 @@ $jenkins-split-button-border-radius: 0.2rem;
}
.stop-button-link {
--item-background: color-mix(in sRGB, var(--red) 15%, transparent);
--item-background--hover: color-mix(in sRGB, var(--red) 20%, transparent);
--item-background--active: color-mix(in sRGB, var(--red) 25%, transparent);
--item-box-shadow--focus: transparent;
@include mixins.item;
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
@@ -366,10 +279,6 @@ $jenkins-split-button-border-radius: 0.2rem;
height: 1rem;
border-radius: 0.25rem;
&::before {
background: color-mix(in sRGB, var(--red) 15%, transparent);
}
svg {
width: 87.5%;
height: 87.5%;
+11 -4
View File
@@ -28,14 +28,22 @@ $icon-size: 1.375rem;
}
&:not(:hover) {
.jenkins-card__unveil {
color: var(--text-color-secondary) !important;
.jenkins-card__unveil,
.jenkins-card__reveal {
color: var(--text-color-secondary);
}
}
@media (prefers-contrast: more) {
.jenkins-card__unveil,
.jenkins-card__reveal {
color: var(--text-color) !important;
}
}
&:hover {
.jenkins-card__reveal {
color: var(--text-color) !important;
color: var(--text-color);
}
}
@@ -69,7 +77,6 @@ $icon-size: 1.375rem;
width: 26px;
height: 26px;
border-radius: 0.33rem;
color: var(--text-color-secondary) !important;
transition:
scale var(--standard-transition),
opacity var(--standard-transition);
@@ -86,6 +86,7 @@
max-width: unset;
input {
padding: 0 0.5rem 0 45px;
background: transparent !important;
--input-border: transparent;
@@ -136,7 +137,7 @@
}
&__item {
@include mixins.item;
@include mixins.item($border: false);
--item-background--hover: color-mix(
in sRGB,
@@ -152,19 +153,15 @@
display: flex;
align-items: center;
justify-content: flex-start;
background: transparent;
padding: 0.75rem;
border-radius: 0.5rem;
cursor: pointer;
color: var(--text-color) !important;
transition: var(--standard-transition);
box-shadow: 0 0 0 10px transparent;
border: none;
outline: none;
&--hover {
&::before {
background-color: var(--item-background--hover);
border: var(--jenkins-border--subtle) !important;
}
}
+22 -17
View File
@@ -1,9 +1,10 @@
@use "../abstracts/mixins";
$dropdown-padding: 0.4rem;
$dropdown-border-radius: 1rem;
$dropdown-padding: 0.375rem;
.tippy-box[data-theme~="dropdown"] {
border-radius: 15px;
border-radius: $dropdown-border-radius;
box-shadow: var(--dropdown-box-shadow);
outline: none !important;
background: color-mix(in sRGB, var(--background) 85%, transparent);
@@ -76,22 +77,15 @@ $dropdown-padding: 0.4rem;
&__separator {
position: relative;
height: 0.125rem;
height: var(--jenkins-border-width);
margin: $dropdown-padding calc($dropdown-padding * -1);
border: none;
&::before {
content: "";
position: absolute;
inset: 0;
background-color: var(--text-color-secondary);
opacity: 0.1;
}
background-color: var(--jenkins-border-color);
}
&__heading {
color: var(--text-color-secondary) !important;
margin: $dropdown-padding 0.55rem;
margin: $dropdown-padding 0.65rem;
font-size: 0.8125rem;
font-weight: var(--font-bold-weight);
opacity: 0.8;
@@ -123,7 +117,7 @@ $dropdown-padding: 0.4rem;
--item-background--active: var(--button-background--active);
--item-box-shadow--focus: var(--button-box-shadow--focus);
@include mixins.item;
@include mixins.item($border: false);
appearance: none;
display: inline-flex;
@@ -138,7 +132,7 @@ $dropdown-padding: 0.4rem;
text-decoration: none !important;
background: transparent;
color: var(--text-color) !important;
border-radius: 0.66rem;
border-radius: calc($dropdown-border-radius - $dropdown-padding);
cursor: pointer;
min-height: 36px;
white-space: nowrap;
@@ -223,14 +217,25 @@ $dropdown-padding: 0.4rem;
&:hover {
.jenkins-dropdown__item--selected {
background: transparent;
&::before {
opacity: 0;
}
}
}
}
.jenkins-dropdown__item--selected {
background: var(--item-background--hover);
animation: pulse 1s ease-in-out forwards;
&::before {
background: var(--item-background--hover);
border: var(--jenkins-border--subtle) !important;
animation: pulse 1s ease-in-out forwards;
}
&:hover {
&::before {
opacity: 1 !important;
}
}
@keyframes pulse {
50% {
+1
View File
@@ -6,6 +6,7 @@
gap: 1rem;
min-height: 15rem;
background: var(--button-background);
border: var(--jenkins-border--subtle);
border-radius: var(--form-input-border-radius);
font-size: var(--font-size-base);
margin-bottom: var(--section-padding);
+2 -2
View File
@@ -36,8 +36,8 @@
inset: 0;
border-radius: inherit;
z-index: -1;
background: var(--background);
opacity: 0.3;
background: oklch(from var(--background) l c h / 0.3);
border: var(--jenkins-border--subtle);
}
@supports not (backdrop-filter: blur(15px)) {
@@ -12,8 +12,8 @@
outline: none;
border: none;
box-shadow:
0 0 0 10px transparent,
inset 0 0 0 0.125rem var(--input-border);
var(--form-input-glow),
inset 0 0 0 var(--jenkins-border-width) var(--input-border);
border-radius: 6px;
transition: var(--standard-transition);
cursor: pointer;
@@ -21,14 +21,14 @@
&:hover {
box-shadow:
0 0 0 10px transparent,
var(--form-input-glow),
inset 0 0 0 0.3125rem var(--input-border-hover);
}
&:active,
&:focus {
box-shadow:
0 0 0 5px var(--focus-input-glow),
0 0 0 4px var(--focus-input-glow),
inset 0 0 0 0.3125rem var(--focus-input-border);
}
@@ -61,19 +61,19 @@
&--all {
box-shadow:
0 0 0 10px transparent,
var(--form-input-glow),
inset 0 0 0 0.6875rem var(--focus-input-border);
&:hover {
box-shadow:
0 0 0 10px transparent,
var(--form-input-glow),
inset 0 0 0 1.375rem var(--focus-input-border);
}
&:active,
&:focus {
box-shadow:
0 0 0 5px var(--focus-input-glow),
0 0 0 4px var(--focus-input-glow),
inset 0 0 0 1.375rem var(--focus-input-border);
}
+3 -2
View File
@@ -1,7 +1,7 @@
@use "../abstracts/mixins";
.jenkins-section {
border-top: 2px solid var(--panel-border-color);
border-top: var(--jenkins-border);
padding: var(--section-padding) 0 0 0;
max-width: 1800px;
@@ -55,7 +55,7 @@
}
.jenkins-section__item a {
@include mixins.item;
@include mixins.item($border: false);
display: flex;
text-decoration: none;
@@ -90,6 +90,7 @@
border-radius: 100%;
pointer-events: none;
background: var(--item-background--active);
border: var(--jenkins-border--subtle);
}
img,
@@ -61,17 +61,11 @@ $background-outset: 0.7rem;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0.55rem $background-outset;
padding: 0.5rem $background-outset;
gap: 0.65rem;
width: 100%;
cursor: pointer;
font-weight: normal !important;
font-size: var(--font-size-sm);
color: var(--text-color) !important;
background: transparent;
outline: none;
border: none;
text-decoration: none;
color: var(--text-color);
margin: 0;
transition: opacity var(--standard-transition);
@@ -100,7 +94,7 @@ $background-outset: 0.7rem;
}
&--active {
font-weight: 500 !important;
font-weight: 450;
cursor: default;
svg * {
@@ -115,4 +109,10 @@ $background-outset: 0.7rem;
box-shadow: none !important;
}
}
&:not(:hover, &:active, &:focus, &--active) {
&::before {
border-color: transparent;
}
}
}
+2 -1
View File
@@ -19,7 +19,8 @@
&::before {
position: relative;
margin-right: 0.5lh;
opacity: 0.2;
opacity: 0.3;
border-color: var(--text-color-secondary);
}
&::after {
+23 -37
View File
@@ -6,10 +6,12 @@
position: relative;
width: 100%;
background: var(--table-background);
border-radius: calc(var(--table-border-radius) + 4px);
border: 4px solid var(--table-background);
border-bottom-width: 2px;
border-spacing: 0 2px;
border-radius: calc(
var(--table-border-radius) + (var(--card-border-width) * 2)
);
border: calc(var(--card-border-width) * 2) solid var(--table-background);
border-bottom-width: var(--card-border-width);
border-spacing: 0 var(--card-border-width);
background-clip: padding-box;
margin-bottom: var(--section-padding);
@@ -18,8 +20,8 @@
&::before {
content: "";
position: absolute;
inset: -4px -4px -2px;
border: var(--card-border-width) solid var(--table-border-color);
inset: -3px -3px -2px;
border: var(--jenkins-border--subtle);
border-radius: inherit;
pointer-events: none;
}
@@ -38,8 +40,8 @@
padding-top: calc(var(--table-padding) * 0.9);
padding-bottom: calc((var(--table-padding) * 0.9) + 2px);
padding-left: 1.6rem;
font-weight: var(--font-bold-weight);
font-size: var(--font-size-sm);
font-weight: var(--font-bold-weight);
&[align="center"] {
text-align: center;
@@ -257,7 +259,7 @@
&__button,
.sortheader,
&__link {
@include mixins.item;
@include mixins.item($border: false);
align-items: center;
justify-content: center;
@@ -283,39 +285,23 @@
}
&__badge {
@include mixins.item;
--item-background: color-mix(in sRGB, currentColor 5%, transparent);
--item-background--hover: color-mix(in sRGB, currentColor 10%, transparent);
--item-background--active: color-mix(
in sRGB,
currentColor 15%,
transparent
);
--item-box-shadow--focus: color-mix(in sRGB, currentColor 5%, transparent);
margin-left: 1rem !important;
border-radius: 13px;
&::before {
inset: -5px -8px;
border-radius: 13px;
background: currentColor;
opacity: 0.05;
}
&::before,
&::after {
inset: -5px -8px;
box-shadow: 0 0 0 10px currentColor;
opacity: 0;
}
&:hover {
&::before {
background: currentColor;
border-radius: 6px;
}
}
&:active,
&:focus {
&::before {
background: currentColor;
border-radius: 6px;
}
&::after {
box-shadow: 0 0 0 5px currentColor;
opacity: 0.025;
}
}
}
}
+36 -27
View File
@@ -1,3 +1,7 @@
@use "../abstracts/mixins";
$border-radius: 100px;
.tabBarFrame {
position: relative;
}
@@ -7,8 +11,8 @@
display: inline-flex;
align-items: center;
flex-wrap: wrap;
background: var(--tabs-background);
border-radius: var(--tabs-border-radius);
background: var(--button-background);
border-radius: $border-radius;
padding: 2px;
margin-bottom: var(--section-padding);
@@ -16,7 +20,7 @@
content: "";
position: absolute;
inset: 0;
border: var(--card-border-width) solid var(--tabs-border-color);
border: var(--jenkins-border--subtle);
border-radius: inherit;
pointer-events: none;
}
@@ -27,38 +31,28 @@
}
.tabBar .tab a {
position: relative;
@include mixins.item($border: false);
display: flex;
align-items: center;
justify-content: center;
min-width: 3rem;
text-decoration: none;
margin: 2px;
padding: 0.4rem 1.2rem;
border-radius: 100px;
background: var(--tabs-item-background);
min-height: 36px;
padding: 0 1.2rem;
border-radius: $border-radius;
color: var(--tabs-item-foreground);
font-weight: var(--font-bold-weight);
font-weight: normal;
font-size: var(--font-size-sm);
transition: var(--standard-transition);
cursor: pointer;
min-width: 3.75rem;
&:hover {
background: var(--tabs-item-background--hover);
color: var(--tabs-item-foreground--hover);
}
&:active,
&:focus {
outline: none;
background: var(--tabs-item-background--active);
color: var(--tabs-item-foreground--active);
&::before,
&::after {
inset: 2px;
}
}
.tabBar .tab .addTab svg {
width: 1.25rem;
height: 1.25rem;
width: 1.125rem;
height: 1.125rem;
}
.tabBar .tab [type="radio"] {
@@ -66,10 +60,25 @@
}
.tabBar .tab.active a {
background: var(--tabs-item-background--selected);
color: var(--tabs-item-foreground--selected);
z-index: 2;
cursor: default;
font-weight: 450;
color: var(--tabs-item-foreground--active);
&::before {
background-clip: padding-box;
background-color: var(--tabs-item-background--selected) !important;
border: var(--jenkins-border--subtle) !important;
}
&::after {
display: none;
}
&::before,
&::after {
inset: 0;
}
}
.jenkins-tab-pane__title {
+3 -3
View File
@@ -36,7 +36,7 @@
position: absolute;
inset: 0;
border-radius: 0.375rem;
border: 0.1rem solid var(--text-color-secondary);
border: var(--jenkins-border-width) solid var(--text-color-secondary);
opacity: 0.3;
mask-image: linear-gradient(
-45deg,
@@ -101,8 +101,8 @@
position: absolute;
inset: 0;
border-radius: 0.375rem;
border: 0.1rem solid var(--text-color-secondary);
opacity: 0.3;
border: var(--jenkins-border-width) solid var(--text-color-secondary);
opacity: 0.2;
}
svg {
+11 -11
View File
@@ -32,7 +32,7 @@
& + label {
&::before {
box-shadow:
0 0 0 5px var(--focus-input-glow),
var(--form-input-glow--focus),
inset 0 0 0 5px var(--focus-input-border);
}
}
@@ -44,7 +44,7 @@
& + label {
&::before {
box-shadow:
0 0 0 5px var(--focus-input-glow),
var(--form-input-glow--focus),
inset 0 0 0 12px var(--focus-input-border);
}
}
@@ -58,7 +58,7 @@
& + label {
&::before {
box-shadow:
0 0 0 5px var(--focus-input-glow),
var(--form-input-glow--focus),
inset 0 0 0 12px var(--focus-input-border);
}
}
@@ -71,7 +71,7 @@
&:focus {
&::before {
box-shadow:
0 0 0 5px var(--focus-input-glow),
var(--form-input-glow--focus),
inset 0 0 0 12px var(--focus-input-border);
}
}
@@ -80,7 +80,7 @@
& + label {
&::before {
box-shadow:
0 0 0 10px transparent,
var(--form-input-glow),
inset 0 0 0 12px var(--focus-input-border);
}
@@ -97,7 +97,7 @@
&::before {
opacity: 0.35 !important;
box-shadow:
0 0 0 10px transparent,
var(--form-input-glow),
inset 0 0 0 2px var(--input-border) !important;
}
}
@@ -106,7 +106,7 @@
& + label {
&::before {
box-shadow:
0 0 0 10px transparent,
var(--form-input-glow),
inset 0 0 0 12px var(--focus-input-border) !important;
}
@@ -138,8 +138,8 @@
transition: var(--standard-transition);
margin-right: 11px;
box-shadow:
0 0 0 10px transparent,
inset 0 0 0 2px var(--input-border);
var(--form-input-glow),
inset 0 0 0 var(--jenkins-border-width) var(--input-border);
background: var(--input-color);
}
@@ -171,7 +171,7 @@
&:hover {
&::before {
box-shadow:
0 0 0 10px transparent,
var(--form-input-glow),
inset 0 0 0 5px var(--input-border-hover);
}
}
@@ -180,7 +180,7 @@
&:focus {
&::before {
box-shadow:
0 0 0 5px var(--focus-input-glow),
var(--form-input-glow--focus),
inset 0 0 0 5px var(--focus-input-border);
}
}
+2 -3
View File
@@ -1,7 +1,7 @@
.CodeMirror {
display: block;
background: var(--input-color);
border: 2px solid var(--input-border);
border: var(--jenkins-border-width) solid var(--input-border);
border-radius: var(--form-input-border-radius);
width: 100%;
box-shadow: var(--form-input-glow);
@@ -48,8 +48,7 @@
}
.CodeMirror-gutter-text {
padding: var(--form-input-padding) calc(var(--form-input-padding) * 0.5)
var(--form-input-padding) var(--form-input-padding);
padding: 0.5rem calc(0.625rem * 0.5) 0.625rem 0.5rem;
color: var(--text-color-secondary);
}
}
+4 -4
View File
@@ -24,7 +24,6 @@
display: inline-flex;
align-items: center;
justify-content: center;
border: none;
outline: none;
margin: 0 1rem 0 0;
padding: 0.5rem 0.85rem 0.5rem 2.5rem;
@@ -34,7 +33,7 @@
padding: 0.5rem 0.85rem;
}
font-size: 0.8rem;
font-size: var(--font-size-sm);
font-weight: normal;
color: var(--text-color);
border-radius: var(--form-input-border-radius);
@@ -43,7 +42,8 @@
white-space: nowrap;
background: var(--button-background);
transition: var(--standard-transition);
box-shadow: 0 0 0 10px transparent;
box-shadow: var(--form-input-glow);
border: var(--jenkins-border--subtle);
&:hover {
background: var(--button-background--hover);
@@ -51,7 +51,7 @@
&:active {
background: var(--button-background--active);
box-shadow: 0 0 0 5px var(--button-box-shadow--focus);
box-shadow: 0 0 0 4px var(--button-box-shadow--focus);
}
}
+15 -8
View File
@@ -1,10 +1,11 @@
.jenkins-input {
display: block;
background: var(--input-color);
border: 2px solid var(--input-border);
border: var(--jenkins-border-width) solid var(--input-border);
padding: var(--form-input-padding);
border-radius: var(--form-input-border-radius);
width: 100%;
min-height: 2.375rem;
box-shadow: var(--form-input-glow);
// Set height transition to 0s as vertical resizing has a delay/lag otherwise
@@ -13,15 +14,21 @@
height 0s,
padding 0s;
&:hover {
border-color: var(--input-border-hover);
&:not(:disabled) {
&:hover {
border-color: var(--input-border-hover);
}
&:active,
&:focus {
outline: none;
border-color: var(--focus-input-border);
box-shadow: var(--form-input-glow--focus);
}
}
&:active,
&:focus {
outline: none;
border-color: var(--focus-input-border);
box-shadow: var(--form-input-glow--focus);
&:disabled {
cursor: not-allowed;
}
}
+8 -44
View File
@@ -1,3 +1,5 @@
@use "../abstracts/mixins";
.jenkins-form {
max-width: var(--form-item-max-width);
}
@@ -70,6 +72,8 @@
align-items: center;
background-color: var(--button-background);
border-radius: var(--form-input-border-radius);
outline: var(--jenkins-border--subtle);
outline-offset: calc(var(--jenkins-border-width) * -1);
padding: 0 1rem;
gap: 1.5rem;
@@ -89,12 +93,14 @@
}
.jenkins-help-button {
position: relative;
@include mixins.item;
--item-background: var(--button-background);
display: inline-flex;
justify-content: center;
align-items: center;
margin-left: 1ch;
color: var(--text-color) !important;
border-radius: 100%;
span {
@@ -110,47 +116,6 @@
mask-position: center;
mask-repeat: no-repeat;
}
&::before {
content: "";
position: absolute;
inset: 0;
background: var(--text-color-secondary);
opacity: 0.1;
border-radius: inherit;
transition: var(--standard-transition);
}
&::after {
content: "";
position: absolute;
inset: 0;
border: 1px solid
color-mix(in sRGB, var(--text-color-secondary), transparent);
box-shadow: var(--form-input-glow);
border-radius: inherit;
opacity: 0.1;
transition: var(--standard-transition);
}
&:hover {
&::before {
opacity: 0.2;
}
}
&:active,
&:focus {
outline: none;
&::before {
opacity: 0.3;
}
&::after {
box-shadow: 0 0 0 5px var(--text-color);
}
}
}
.jenkins-select-help {
@@ -170,7 +135,6 @@
gap: 0.45rem;
margin-left: 0.4rem;
font-size: 0.8rem;
font-weight: var(--font-bold-weight);
cursor: default;
svg {
+4 -5
View File
@@ -1,10 +1,9 @@
$jenkins-radio-size: 1.375rem;
$jenkins-radio-border-size: 0.125rem;
$jenkins-radio-border-size: 1.5px;
$jenkins-radio-border-hover-size: 0.3125rem;
$jenkins-radio-border-active-size: 0.5rem;
$jenkins-radio-border-checked-size: 0.4rem;
$jenkins-radio-glow-size: 0.625rem;
$jenkins-radio-glow-active-size: 0.3125rem;
$jenkins-radio-glow-size: 0.5rem;
.jenkins-radio-help-wrapper {
display: flex;
@@ -37,7 +36,7 @@ $jenkins-radio-glow-active-size: 0.3125rem;
&:active {
& + label::before {
box-shadow:
0 0 0 $jenkins-radio-glow-active-size var(--focus-input-glow),
var(--form-input-glow--focus),
inset 0 0 0 $jenkins-radio-border-active-size
var(--focus-input-border);
}
@@ -62,7 +61,7 @@ $jenkins-radio-glow-active-size: 0.3125rem;
&:active {
& + label::before {
box-shadow:
0 0 0 $jenkins-radio-glow-active-size var(--focus-input-glow),
var(--form-input-glow--focus),
inset 0 0 0 $jenkins-radio-border-active-size
var(--focus-input-border);
}
+1 -1
View File
@@ -153,7 +153,7 @@
--search-bar-height: 3rem;
width: 100%;
margin-block: -6px;
margin-block: -5px;
@media (min-width: breakpoints.$tablet-breakpoint) {
max-width: 50vw;
+15 -7
View File
@@ -8,26 +8,28 @@
top: 0;
right: 13px;
bottom: 0;
width: 12px;
width: 0.625rem;
background-color: currentColor;
mask-image: url("data:image/svg+xml;charset=UTF-8,%3c?xml version='1.0' encoding='UTF-8'?%3e%3csvg width='336px' height='192px' viewBox='0 0 336 192' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3e%3ctitle%3ePath%3c/title%3e%3cg id='Page-1' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3e%3cg id='arrow' transform='translate(0.000000, 0.000000)' fill='%23FF0000' fill-rule='nonzero'%3e%3cpath d='M7.02943725,7.02943725 C16.3053957,-2.24652118 31.2852799,-2.34214962 40.6788451,6.74255194 L40.9705627,7.02943725 L168,134.059 L295.029437,7.02943725 C304.305396,-2.24652118 319.28528,-2.34214962 328.678845,6.74255194 L328.970563,7.02943725 C338.246521,16.3053957 338.34215,31.2852799 329.257448,40.6788451 L328.970563,40.9705627 L184.970563,184.970563 C175.694604,194.246521 160.71472,194.34215 151.321155,185.257448 L151.029437,184.970563 L7.02943725,40.9705627 C-2.34314575,31.5979797 -2.34314575,16.4020203 7.02943725,7.02943725 Z' id='Path'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/svg%3e");
mask-size: contain;
mask-repeat: no-repeat;
mask-position: center;
pointer-events: none;
transition: translate var(--elastic-transition);
}
&__input {
appearance: none;
display: block;
border: 2px solid var(--input-border);
border: var(--jenkins-border-width) solid var(--input-border);
padding: var(--form-input-padding);
width: 100% !important; // TODO remove important after https://github.com/jenkinsci/credentials-plugin/pull/255
max-width: 100% !important; // TODO remove important after https://github.com/jenkinsci/credentials-plugin/pull/255
border-radius: var(--form-input-border-radius);
box-shadow: 0 0 0 10px transparent;
box-shadow: var(--form-input-glow);
transition: var(--standard-transition);
min-height: 38px;
cursor: pointer;
&:hover {
border-color: var(--input-border-hover);
@@ -37,27 +39,33 @@
&:focus {
outline: none;
border-color: var(--focus-input-border);
box-shadow: 0 0 0 5px var(--focus-input-glow);
box-shadow: var(--form-input-glow--focus);
}
&:disabled {
pointer-events: none;
}
}
&:hover {
&::after {
translate: 0 1px;
}
}
}
.jenkins-multi-select {
position: relative;
width: 100%;
border: 2px solid var(--input-border);
border: var(--jenkins-border-width) solid var(--input-border);
border-radius: var(--form-input-border-radius);
box-shadow: 0 0 0 10px transparent;
box-shadow: var(--form-input-glow);
transition: var(--standard-transition);
outline: none;
&:focus {
border-color: var(--focus-input-border);
box-shadow: 0 0 0 5px var(--focus-input-glow);
box-shadow: var(--form-input-glow--focus);
}
&:disabled {
+2 -1
View File
@@ -6,7 +6,8 @@
}
.textarea-preview {
background-color: var(--very-light-grey);
background-color: var(--button-background);
border: var(--jenkins-border--subtle);
padding: var(--form-input-padding);
margin-top: 0.5rem;
border-radius: var(--form-input-border-radius);
+17 -5
View File
@@ -69,6 +69,13 @@
&:active,
&:focus {
&::before {
box-shadow:
inset 0 0 0 1.5px
color-mix(in sRGB, var(--text-color-secondary) 9%, transparent),
var(--form-input-glow--focus);
}
&::after {
left: 20px;
width: 25px;
@@ -101,6 +108,7 @@
cursor: pointer;
line-height: 30px;
font-weight: var(--form-label-font-weight);
user-select: none;
&::before {
display: inline-block;
@@ -113,8 +121,9 @@
transition: var(--standard-transition);
margin-right: 1rem;
box-shadow:
inset 0 0 0 1px rgb(0 0 0 / 0.05),
0 0 0 10px transparent;
inset 0 0 0 1.5px
color-mix(in sRGB, var(--text-color-secondary) 9%, transparent),
var(--form-input-glow);
}
&::after {
@@ -132,7 +141,8 @@
mask-position: center;
border-radius: 100px;
transition: var(--standard-transition);
box-shadow: 0 1px 0 rgb(0 0 0 / 0.1);
box-shadow: 0 0 0 1.5px
color-mix(in sRGB, var(--text-color-secondary) 9%, transparent);
}
&:hover::before {
@@ -143,8 +153,10 @@
&:focus {
&::before {
box-shadow:
inset 0 0 0 1px rgb(0 0 0 / 0.05),
0 0 0 5px var(--focus-input-glow);
inset 0 0 0 1.5px
color-mix(in sRGB, var(--text-color-secondary) 9%, transparent),
0 0 0 4px
color-mix(in sRGB, var(--text-color-secondary) 25%, transparent);
}
&::after {
+17 -14
View File
@@ -7,15 +7,18 @@
pointer-events: none;
margin-bottom: var(--section-padding);
overflow: hidden;
mask-border-source: url("data:image/svg+xml,%3Csvg width='45' height='45' viewBox='0 0 45 45' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 22.5C0 15.5109 0 12.0163 1.14181 9.25975C2.66422 5.58433 5.58433 2.66422 9.25975 1.14181C12.0163 0 15.5109 0 22.5 0C29.4891 0 32.9837 0 35.7402 1.14181C39.4157 2.66422 42.3358 5.58433 43.8582 9.25975C45 12.0163 45 15.5109 45 22.5C45 29.4891 45 32.9837 43.8582 35.7402C42.3358 39.4157 39.4157 42.3358 35.7402 43.8582C32.9837 45 29.4891 45 22.5 45C15.5109 45 12.0163 45 9.25975 43.8582C5.58433 42.3358 2.66422 39.4157 1.14181 35.7402C0 32.9837 0 29.4891 0 22.5Z' fill='%23D9D9D9'/%3E%3C/svg%3E%0A");
mask-border-slice: 49% fill;
border-radius: 1rem;
&::before {
&::before,
&::after {
content: "";
position: absolute;
z-index: 1;
}
&::before {
width: 120%;
aspect-ratio: 1;
z-index: 1;
background: repeating-conic-gradient(
var(--background) 0deg,
rgb(100 100 100 / 0.25) 20deg
@@ -24,6 +27,12 @@
opacity: 0.25;
}
&::after {
inset: 0;
border: var(--jenkins-border--subtle);
border-radius: inherit;
}
img {
height: 7.5rem;
z-index: 1;
@@ -46,11 +55,8 @@
&::before {
background-color: var(--color);
background-image: radial-gradient(
at 40% 20%,
hsl(28 100% 74% / 1) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, hsl(28 100% 74% / 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%),
@@ -62,11 +68,8 @@
}
&::after {
background-image: radial-gradient(
at 40% 20%,
hsl(212 100% 74% / 1) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, hsl(212 100% 74% / 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%),
+1
View File
@@ -149,6 +149,7 @@
pre {
background: transparent;
border: none;
margin: 0;
padding: 0;
line-height: 1.75;
+1 -1
View File
@@ -1,6 +1,6 @@
@use "../abstracts/mixins";
$min-button-size: 36px;
$min-button-size: 2.375rem;
.jenkins-icon-size {
display: flex;
+1 -1
View File
@@ -94,7 +94,7 @@
}
.app-builds-container__item {
@include mixins.item;
@include mixins.item($border: false);
display: grid;
grid-template-columns: auto 1fr auto;
+4 -10
View File
@@ -45,11 +45,8 @@
}
&::before {
background-image: radial-gradient(
at 40% 20%,
var(--orange) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, var(--orange) 0, transparent 50%),
radial-gradient(at 80% 0%, var(--cyan) 0, transparent 50%),
radial-gradient(at 0% 50%, var(--light-pink) 0, transparent 50%),
radial-gradient(at 80% 50%, var(--light-red) 0, transparent 50%),
@@ -59,11 +56,8 @@
}
&::after {
background-image: radial-gradient(
at 40% 20%,
var(--light-cyan) 0,
transparent 50%
),
background-image:
radial-gradient(at 40% 20%, var(--light-cyan) 0, transparent 50%),
radial-gradient(at 80% 0%, var(--dark-orange) 0, transparent 50%),
radial-gradient(at 0% 50%, var(--light-blue) 0, transparent 50%),
radial-gradient(at 80% 50%, var(--light-green) 0, transparent 50%),
+6 -6
View File
@@ -118,7 +118,7 @@ THE SOFTWARE.
<!-- requireUpperBoundDeps via matrix-project and junit -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
<version>1369.v9b_98a_4e95b_2d</version>
<version>1373.vb_b_4a_a_c26fa_00</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
@@ -134,7 +134,7 @@ THE SOFTWARE.
<!-- Required by plugin-util-api -->
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>944.v5a_859593b_98a_</version>
<version>946.v2a_79d8a_4b_e14</version>
</dependency>
</dependencies>
</dependencyManagement>
@@ -218,19 +218,19 @@ THE SOFTWARE.
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>cloudbees-folder</artifactId>
<version>6.980.v5a_cc0cb_25881</version>
<version>6.982.vf165a_16c9507</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
<version>1405.vb_cda_74a_f8974</version>
<version>1408.va_622a_b_f5b_1b_1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>junit</artifactId>
<version>1312.v1a_235a_b_94a_31</version>
<version>1314.vd966e9a_88895</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -344,7 +344,7 @@ THE SOFTWARE.
<artifactItem>
<groupId>io.jenkins.plugins</groupId>
<artifactId>design-library</artifactId>
<version>354.v87d9d5804b_c1</version>
<version>355.v0f007356e15d</version>
<type>hpi</type>
<outputDirectory>${project.build.outputDirectory}/plugins</outputDirectory>
<destFileName>design-library.jpi</destFileName>
@@ -102,7 +102,7 @@ public class GlobalComputerRetentionCheckIntervalConfigurationTest {
JSONObject json = new JSONObject();
json.element("computerRetentionCheckInterval", 5);
try {
c.configure(Stapler.getCurrentRequest(), json);
c.configure(Stapler.getCurrentRequest2(), json);
} catch (Descriptor.FormException e) {
throw new RuntimeException(e);
}
@@ -121,7 +121,7 @@ public class GlobalComputerRetentionCheckIntervalConfigurationTest {
JSONObject json = new JSONObject();
json.element("computerRetentionCheckInterval", interval);
try {
c.configure(Stapler.getCurrentRequest(), json);
c.configure(Stapler.getCurrentRequest2(), json);
throw new RuntimeException("expected .configure() to throw");
} catch (Descriptor.FormException e) {
assertEquals(e.getMessage(), message);
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertTrue;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.ExtensionList;
import hudson.Util;
import hudson.model.UnprotectedRootAction;
import hudson.security.csrf.CrumbExclusion;
import jakarta.servlet.FilterChain;
@@ -31,7 +32,6 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.regex.Pattern;
import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Rule;
@@ -99,7 +99,7 @@ public class TelemetryTest {
.atMost(10, TimeUnit.SECONDS)
.until(() -> types, hasItem("test-data"));
//90ecf3ce1cd5ba1e5ad3cde7ad08a941e884f2e4d9bd463361715abab8efedc5
assertThat(correlators, hasItem(DigestUtils.sha256Hex(correlationId + "test-data")));
assertThat(correlators, hasItem(Util.getHexOfSHA256DigestOf(correlationId + "test-data")));
}
@Test
+11 -13
View File
@@ -309,14 +309,14 @@ THE SOFTWARE.
<!-- dependency of command-launcher, junit, matrix-project, and workflow-support -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
<version>1369.v9b_98a_4e95b_2d</version>
<version>1373.vb_b_4a_a_c26fa_00</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
<!-- detached after 1.577 -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>junit</artifactId>
<version>1312.v1a_235a_b_94a_31</version>
<version>1314.vd966e9a_88895</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
@@ -344,7 +344,7 @@ THE SOFTWARE.
<!-- dependency of junit -->
<groupId>io.jenkins.plugins</groupId>
<artifactId>checks-api</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
<type>hpi</type>
</artifactItem>
@@ -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>944.v5a_859593b_98a_</version>
<version>946.v2a_79d8a_4b_e14</version>
<type>hpi</type>
</artifactItem>
@@ -360,7 +360,7 @@ THE SOFTWARE.
<!-- dependency of junit and echarts-api -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
<version>2.17.0-379.v02de8ec9f64c</version>
<version>2.17.0-386.vcb_b_037da_0d62</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
@@ -462,7 +462,7 @@ THE SOFTWARE.
<!-- detached after 2.281 -->
<groupId>org.jenkins-ci.modules</groupId>
<artifactId>sshd</artifactId>
<version>3.330.vc866a_8389b_58</version>
<version>3.353.v2b_d33c46e970</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
@@ -497,7 +497,7 @@ THE SOFTWARE.
<!-- dependency of jdk-tool -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>apache-httpcomponents-client-4-api</artifactId>
<version>4.5.14-208.v438351942757</version>
<version>4.5.14-269.vfa_2321039a_83</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
@@ -525,7 +525,7 @@ THE SOFTWARE.
<!-- dependency of trilead-api -->
<groupId>io.jenkins.plugins</groupId>
<artifactId>gson-api</artifactId>
<version>2.11.0-109.v1ef91dd0829a_</version>
<version>2.12.1-113.v347686d6729f</version>
<type>hpi</type>
</artifactItem>
<artifactItem>
@@ -691,12 +691,10 @@ THE SOFTWARE.
<javax.xml.transform.TransformerFactory>com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl</javax.xml.transform.TransformerFactory>
</systemProperties>
<webApp>
<!-- Allows resources to be reloaded, and enable nicer console logging. -->
<extraClasspath>${project.basedir}/../core/src/main/resources,${project.basedir}/../core/target/classes,${project.build.directory}/support-log-formatter.jar</extraClasspath>
<!-- Allow resources to be reloaded and enable nicer console logging. -->
<extraClasspath>${project.basedir}/../core/src/main/resources,${project.build.directory}/support-log-formatter.jar</extraClasspath>
<contextPath>${contextPath}</contextPath>
<configurationDiscovered>false</configurationDiscovered>
<!-- see https://wiki.eclipse.org/Jetty/Howto/Avoid_slow_deployment -->
<webInfIncludeJarPattern>NONE</webInfIncludeJarPattern>
<webInfIncludeJarPattern>.*(jenkins-core|target/classes).*</webInfIncludeJarPattern>
</webApp>
</configuration>
</plugin>
+1 -250
View File
@@ -26,256 +26,7 @@ THE SOFTWARE.
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
version="3.1">
<display-name>Jenkins v${project.version}</display-name>
<description>Build management system</description>
<servlet>
<servlet-name>Stapler</servlet-name>
<servlet-class>org.kohsuke.stapler.Stapler</servlet-class>
<init-param>
<param-name>default-encodings</param-name>
<param-value>text/html=UTF-8</param-value>
</init-param>
<init-param>
<param-name>diagnosticThreadName</param-name>
<param-value>false</param-value>
</init-param>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Stapler</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>suspicious-request-filter</filter-name>
<filter-class>jenkins.security.SuspiciousRequestFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>diagnostic-name-filter</filter-name>
<filter-class>org.kohsuke.stapler.DiagnosticThreadNameFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>hudson.util.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>uncaught-exception-filter</filter-name>
<filter-class>org.kohsuke.stapler.UncaughtExceptionFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>authentication-filter</filter-name>
<filter-class>hudson.security.HudsonFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>csrf-filter</filter-name>
<filter-class>hudson.security.csrf.CrumbFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>error-attribute-filter</filter-name>
<filter-class>jenkins.ErrorAttributeFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>plugins-filter</filter-name>
<filter-class>hudson.util.PluginServletFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<!--
The Headers filter allows us to override headers sent by the container
that may be in conflict with what we want. For example, Tomcat will set
Cache-Control: no-cache for any files behind the security-constraint
below. So if Hudson is on a public server, and you want to only allow
authorized users to access it, you may want to pay attention to this.
See: http://www.nabble.com/No-browser-caching-with-Hudson- -tf4601857.html
<filter>
<filter-name>change-headers-filter</filter-name>
<filter-class>hudson.ResponseHeaderFilter</filter-class>
<!- The value listed here is for 24 hours. Increase or decrease as you see
fit. Value is in seconds. Make sure to keep the public option ->
<init-param>
<param-name>Cache-Control</param-name>
<param-value>max-age=86400, public</param-value>
</init-param>
<!- It turns out that Tomcat just doesn't want to let
go of its cache option. If you override Cache-Control,
it starts to send Pragma: no-cache as a backup.
->
<init-param>
<param-name>Pragma</param-name>
<param-value>public</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.gif</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>change-headers-filter</filter-name>
<url-pattern>*.png</url-pattern>
</filter-mapping>
-->
<filter-mapping>
<filter-name>suspicious-request-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>diagnostic-name-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>uncaught-exception-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>authentication-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>csrf-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>error-attribute-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>plugins-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<!-- Must be before WebAppMain in order to initialize the context before the first use of this class. -->
<listener-class>jenkins.util.SystemProperties$Listener</listener-class>
</listener>
<listener>
<listener-class>hudson.WebAppMain</listener-class>
</listener>
<listener>
<listener-class>jenkins.JenkinsHttpSessionListener</listener-class>
</listener>
<!--
JENKINS-1235 suggests containers interpret '*' as "all roles defined in web.xml"
as opposed to "all roles defined in the security realm", so we need to list some
common names in the hope that users will have at least one of those roles.
-->
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
<security-role>
<role-name>hudson</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>Hudson</web-resource-name>
<url-pattern>/loginEntry</url-pattern>
<!--http-method>GET</http-method-->
</web-resource-collection>
<auth-constraint>
<role-name>**</role-name>
</auth-constraint>
</security-constraint>
<!-- Disable TRACE method with security constraint (copied from jetty/webdefaults.xml) -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Disable TRACE</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>other</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<!-- no security constraint -->
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login</form-login-page>
<form-error-page>/loginError</form-error-page>
</form-login-config>
</login-config>
<!-- configure additional extension-content-type mappings -->
<mime-mapping>
<extension>xml</extension>
<mime-type>application/xml</mime-type>
</mime-mapping>
<!--mime-mapping> commenting out until this works out of the box with JOnAS. See http://www.nabble.com/Error-with-mime-type%2D-%27application-xslt%2Bxml%27-when-deploying-hudson-1.316-in-jonas-td24740489.html
<extension>xsl</extension>
<mime-type>application/xslt+xml</mime-type>
</mime-mapping-->
<mime-mapping>
<extension>log</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
<mime-mapping>
<extension>war</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
<extension>ear</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
<extension>rar</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
<mime-mapping>
<extension>webm</extension>
<mime-type>video/webm</mime-type>
</mime-mapping>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/oops</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
<session-config>
<cookie-config>
<!-- See https://www.owasp.org/index.php/HttpOnly for the discussion of this topic in OWASP -->
<http-only>true</http-only>
</cookie-config>
<!-- Tracking mode is managed by WebAppMain.FORCE_SESSION_TRACKING_BY_COOKIE_PROP -->
</session-config>
</web-app>
+129 -112
View File
@@ -42,7 +42,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.2":
"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.26.2":
version: 7.26.2
resolution: "@babel/code-frame@npm:7.26.2"
dependencies:
@@ -53,46 +53,47 @@ __metadata:
languageName: node
linkType: hard
"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.26.5":
version: 7.26.5
resolution: "@babel/compat-data@npm:7.26.5"
checksum: 10c0/9d2b41f0948c3dfc5de44d9f789d2208c2ea1fd7eb896dfbb297fe955e696728d6f363c600cd211e7f58ccbc2d834fe516bb1e4cf883bbabed8a32b038afc1a0
"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.26.5, @babel/compat-data@npm:^7.26.8":
version: 7.26.8
resolution: "@babel/compat-data@npm:7.26.8"
checksum: 10c0/66408a0388c3457fff1c2f6c3a061278dd7b3d2f0455ea29bb7b187fa52c60ae8b4054b3c0a184e21e45f0eaac63cf390737bc7504d1f4a088a6e7f652c068ca
languageName: node
linkType: hard
"@babel/core@npm:7.26.7":
version: 7.26.7
resolution: "@babel/core@npm:7.26.7"
"@babel/core@npm:7.26.8":
version: 7.26.8
resolution: "@babel/core@npm:7.26.8"
dependencies:
"@ampproject/remapping": "npm:^2.2.0"
"@babel/code-frame": "npm:^7.26.2"
"@babel/generator": "npm:^7.26.5"
"@babel/generator": "npm:^7.26.8"
"@babel/helper-compilation-targets": "npm:^7.26.5"
"@babel/helper-module-transforms": "npm:^7.26.0"
"@babel/helpers": "npm:^7.26.7"
"@babel/parser": "npm:^7.26.7"
"@babel/template": "npm:^7.25.9"
"@babel/traverse": "npm:^7.26.7"
"@babel/types": "npm:^7.26.7"
"@babel/parser": "npm:^7.26.8"
"@babel/template": "npm:^7.26.8"
"@babel/traverse": "npm:^7.26.8"
"@babel/types": "npm:^7.26.8"
"@types/gensync": "npm:^1.0.0"
convert-source-map: "npm:^2.0.0"
debug: "npm:^4.1.0"
gensync: "npm:^1.0.0-beta.2"
json5: "npm:^2.2.3"
semver: "npm:^6.3.1"
checksum: 10c0/fbd2cd9fc23280bdcaca556e558f715c0a42d940b9913c52582e8e3d24e391d269cb8a9cd6589172593983569021c379e28bba6b19ea2ee08674f6068c210a9d
checksum: 10c0/fafbd083ed3f79973ae2a11a69eee3f13b3226a1d4907abc2c6f2fea21adf4a7c20e00fe0eaa33f44a3666eeaf414edb07460ec031d478ee5f6088eb38b2a011
languageName: node
linkType: hard
"@babel/generator@npm:^7.26.5":
version: 7.26.5
resolution: "@babel/generator@npm:7.26.5"
"@babel/generator@npm:^7.26.8":
version: 7.26.8
resolution: "@babel/generator@npm:7.26.8"
dependencies:
"@babel/parser": "npm:^7.26.5"
"@babel/types": "npm:^7.26.5"
"@babel/parser": "npm:^7.26.8"
"@babel/types": "npm:^7.26.8"
"@jridgewell/gen-mapping": "npm:^0.3.5"
"@jridgewell/trace-mapping": "npm:^0.3.25"
jsesc: "npm:^3.0.2"
checksum: 10c0/3be79e0aa03f38858a465d12ee2e468320b9122dc44fc85984713e32f16f4d77ce34a16a1a9505972782590e0b8d847b6f373621f9c6fafa1906d90f31416cb0
checksum: 10c0/9467f197d285ac315d1fa419138d36a3bfd69ca4baf763e914acab12f5f38e5d231497f6528e80613b28e73bb28c66fcc50b250b1f277b1a4d38ac14b03e9674
languageName: node
linkType: hard
@@ -148,7 +149,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/helper-define-polyfill-provider@npm:^0.6.2, @babel/helper-define-polyfill-provider@npm:^0.6.3":
"@babel/helper-define-polyfill-provider@npm:^0.6.3":
version: 0.6.3
resolution: "@babel/helper-define-polyfill-provider@npm:0.6.3"
dependencies:
@@ -290,14 +291,14 @@ __metadata:
languageName: node
linkType: hard
"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.5, @babel/parser@npm:^7.26.7":
version: 7.26.7
resolution: "@babel/parser@npm:7.26.7"
"@babel/parser@npm:^7.26.8":
version: 7.26.8
resolution: "@babel/parser@npm:7.26.8"
dependencies:
"@babel/types": "npm:^7.26.7"
"@babel/types": "npm:^7.26.8"
bin:
parser: ./bin/babel-parser.js
checksum: 10c0/dcb08a4f2878ece33caffefe43b71488d753324bae7ca58d64bca3bc4af34dcfa1b58abdf9972516d76af760fceb25bb9294ca33461d56b31c5059ccfe32001f
checksum: 10c0/da04f26bae732a5b6790775a736b58c7876c28e62203c5097f043fd7273ef6debe5bfd7a4e670a6819f4549b215c7b9762c6358e44797b3c4d733defc8290781
languageName: node
linkType: hard
@@ -414,16 +415,16 @@ __metadata:
languageName: node
linkType: hard
"@babel/plugin-transform-async-generator-functions@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.9"
"@babel/plugin-transform-async-generator-functions@npm:^7.26.8":
version: 7.26.8
resolution: "@babel/plugin-transform-async-generator-functions@npm:7.26.8"
dependencies:
"@babel/helper-plugin-utils": "npm:^7.25.9"
"@babel/helper-plugin-utils": "npm:^7.26.5"
"@babel/helper-remap-async-to-generator": "npm:^7.25.9"
"@babel/traverse": "npm:^7.25.9"
"@babel/traverse": "npm:^7.26.8"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 10c0/e3fcb9fc3d6ab6cbd4fcd956b48c17b5e92fe177553df266ffcd2b2c1f2f758b893e51b638e77ed867941e0436487d2b8b505908d615c41799241699b520dec6
checksum: 10c0/f6fefce963fe2e6268dde1958975d7adbce65fba94ca6f4bc554c90da03104ad1dd2e66d03bc0462da46868498428646e30b03a218ef0e5a84bfc87a7e375cec
languageName: node
linkType: hard
@@ -921,14 +922,14 @@ __metadata:
languageName: node
linkType: hard
"@babel/plugin-transform-template-literals@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/plugin-transform-template-literals@npm:7.25.9"
"@babel/plugin-transform-template-literals@npm:^7.26.8":
version: 7.26.8
resolution: "@babel/plugin-transform-template-literals@npm:7.26.8"
dependencies:
"@babel/helper-plugin-utils": "npm:^7.25.9"
"@babel/helper-plugin-utils": "npm:^7.26.5"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 10c0/5144da6036807bbd4e9d2a8b92ae67a759543929f34f4db9b463448a77298f4a40bf1e92e582db208fe08ee116224806a3bd0bed75d9da404fc2c0af9e6da540
checksum: 10c0/205a938ded9554857a604416d369023a961334b6c20943bd861b45f0e5dbbeca1cf6fda1c2049126e38a0d18865993433fdc78eae3028e94836b3b643c08ba0d
languageName: node
linkType: hard
@@ -990,11 +991,11 @@ __metadata:
languageName: node
linkType: hard
"@babel/preset-env@npm:7.26.7":
version: 7.26.7
resolution: "@babel/preset-env@npm:7.26.7"
"@babel/preset-env@npm:7.26.8":
version: 7.26.8
resolution: "@babel/preset-env@npm:7.26.8"
dependencies:
"@babel/compat-data": "npm:^7.26.5"
"@babel/compat-data": "npm:^7.26.8"
"@babel/helper-compilation-targets": "npm:^7.26.5"
"@babel/helper-plugin-utils": "npm:^7.26.5"
"@babel/helper-validator-option": "npm:^7.25.9"
@@ -1008,7 +1009,7 @@ __metadata:
"@babel/plugin-syntax-import-attributes": "npm:^7.26.0"
"@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6"
"@babel/plugin-transform-arrow-functions": "npm:^7.25.9"
"@babel/plugin-transform-async-generator-functions": "npm:^7.25.9"
"@babel/plugin-transform-async-generator-functions": "npm:^7.26.8"
"@babel/plugin-transform-async-to-generator": "npm:^7.25.9"
"@babel/plugin-transform-block-scoped-functions": "npm:^7.26.5"
"@babel/plugin-transform-block-scoping": "npm:^7.25.9"
@@ -1051,7 +1052,7 @@ __metadata:
"@babel/plugin-transform-shorthand-properties": "npm:^7.25.9"
"@babel/plugin-transform-spread": "npm:^7.25.9"
"@babel/plugin-transform-sticky-regex": "npm:^7.25.9"
"@babel/plugin-transform-template-literals": "npm:^7.25.9"
"@babel/plugin-transform-template-literals": "npm:^7.26.8"
"@babel/plugin-transform-typeof-symbol": "npm:^7.26.7"
"@babel/plugin-transform-unicode-escapes": "npm:^7.25.9"
"@babel/plugin-transform-unicode-property-regex": "npm:^7.25.9"
@@ -1059,13 +1060,13 @@ __metadata:
"@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.9"
"@babel/preset-modules": "npm:0.1.6-no-external-plugins"
babel-plugin-polyfill-corejs2: "npm:^0.4.10"
babel-plugin-polyfill-corejs3: "npm:^0.10.6"
babel-plugin-polyfill-corejs3: "npm:^0.11.0"
babel-plugin-polyfill-regenerator: "npm:^0.6.1"
core-js-compat: "npm:^3.38.1"
core-js-compat: "npm:^3.40.0"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 10c0/77d2e46a4f133768c5c8a6b3fec49a7c85c6baec601991e63458921e889ff93911f447723c3a99a6a471ca654ea6dc2aaa7ed690f3e518ee80cea7820ab80ce3
checksum: 10c0/314ab8c6173d1f14e40cf22e1e646c429acfd45195e2ddbadca81956aa2a670e37e4446658db65f1a669f82ef115a4a018f78448bc10789cacdaf4e995680db5
languageName: node
linkType: hard
@@ -1091,39 +1092,39 @@ __metadata:
languageName: node
linkType: hard
"@babel/template@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/template@npm:7.25.9"
dependencies:
"@babel/code-frame": "npm:^7.25.9"
"@babel/parser": "npm:^7.25.9"
"@babel/types": "npm:^7.25.9"
checksum: 10c0/ebe677273f96a36c92cc15b7aa7b11cc8bc8a3bb7a01d55b2125baca8f19cae94ff3ce15f1b1880fb8437f3a690d9f89d4e91f16fc1dc4d3eb66226d128983ab
languageName: node
linkType: hard
"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.5, @babel/traverse@npm:^7.26.7":
version: 7.26.7
resolution: "@babel/traverse@npm:7.26.7"
"@babel/template@npm:^7.25.9, @babel/template@npm:^7.26.8":
version: 7.26.8
resolution: "@babel/template@npm:7.26.8"
dependencies:
"@babel/code-frame": "npm:^7.26.2"
"@babel/generator": "npm:^7.26.5"
"@babel/parser": "npm:^7.26.7"
"@babel/template": "npm:^7.25.9"
"@babel/types": "npm:^7.26.7"
debug: "npm:^4.3.1"
globals: "npm:^11.1.0"
checksum: 10c0/b23a36ce40d2e4970741431c45d4f92e3f4c2895c0a421456516b2729bd9e17278846e01ee3d9039b0adf5fc5a071768061c17fcad040e74a5c3e39517449d5b
"@babel/parser": "npm:^7.26.8"
"@babel/types": "npm:^7.26.8"
checksum: 10c0/90bc1085cbc090cbdd43af7b9dbb98e6bda96e55e0f565f17ebb8e97c2dfce866dc727ca02b8e08bd2662ba4fd3851907ba3c48618162c291221af17fb258213
languageName: node
linkType: hard
"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.5, @babel/types@npm:^7.26.7, @babel/types@npm:^7.4.4":
version: 7.26.7
resolution: "@babel/types@npm:7.26.7"
"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.5, @babel/traverse@npm:^7.26.8":
version: 7.26.8
resolution: "@babel/traverse@npm:7.26.8"
dependencies:
"@babel/code-frame": "npm:^7.26.2"
"@babel/generator": "npm:^7.26.8"
"@babel/parser": "npm:^7.26.8"
"@babel/template": "npm:^7.26.8"
"@babel/types": "npm:^7.26.8"
debug: "npm:^4.3.1"
globals: "npm:^11.1.0"
checksum: 10c0/0771d1ce0351628ad2e8dac56f0d59f706eb125c83fbcc039bde83088ba0a1477244ad5fb060802f90366cc4d7fa871e5009a292aef6205bcf83f2e01d1a0a5d
languageName: node
linkType: hard
"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.7, @babel/types@npm:^7.26.8, @babel/types@npm:^7.4.4":
version: 7.26.8
resolution: "@babel/types@npm:7.26.8"
dependencies:
"@babel/helper-string-parser": "npm:^7.25.9"
"@babel/helper-validator-identifier": "npm:^7.25.9"
checksum: 10c0/7810a2bca97b13c253f07a0863a628d33dbe76ee3c163367f24be93bfaf4c8c0a325f73208abaaa050a6b36059efc2950c2e4b71fb109c0f07fa62221d8473d4
checksum: 10c0/cd41ea47bb3d7baf2b3bf5e70e9c3a16f2eab699fab8575b2b31a7b1cb64166eb52c97124313863dde0581747bfc7a1810c838ad60b5b7ad1897d8004c7b95a9
languageName: node
linkType: hard
@@ -1669,6 +1670,15 @@ __metadata:
languageName: node
linkType: hard
"@eslint/core@npm:^0.11.0":
version: 0.11.0
resolution: "@eslint/core@npm:0.11.0"
dependencies:
"@types/json-schema": "npm:^7.0.15"
checksum: 10c0/1e0671d035c908175f445864a7864cf6c6a8b67a5dfba8c47b2ac91e2d3ed36e8c1f2fd81d98a73264f8677055559699d4adb0f97d86588e616fc0dc9a4b86c9
languageName: node
linkType: hard
"@eslint/eslintrc@npm:^3.2.0":
version: 3.2.0
resolution: "@eslint/eslintrc@npm:3.2.0"
@@ -1686,10 +1696,10 @@ __metadata:
languageName: node
linkType: hard
"@eslint/js@npm:9.19.0":
version: 9.19.0
resolution: "@eslint/js@npm:9.19.0"
checksum: 10c0/45dc544c8803984f80a438b47a8e578fae4f6e15bc8478a703827aaf05e21380b42a43560374ce4dad0d5cb6349e17430fc9ce1686fed2efe5d1ff117939ff90
"@eslint/js@npm:9.20.0":
version: 9.20.0
resolution: "@eslint/js@npm:9.20.0"
checksum: 10c0/10e7b5b9e628b5192e8fc6b0ecd27cf48322947e83e999ff60f9f9e44ac8d499138bcb9383cbfa6e51e780d53b4e76ccc2d1753b108b7173b8404fd484d37328
languageName: node
linkType: hard
@@ -2147,6 +2157,13 @@ __metadata:
languageName: node
linkType: hard
"@types/gensync@npm:^1.0.0":
version: 1.0.4
resolution: "@types/gensync@npm:1.0.4"
checksum: 10c0/1daeb1693196a85ee68b82f3fb30906a1cccede69d492b190de80ff20cec2d528d98cad866d733fd83cb171096dfe8c26c9c02c50ffb93e1113d48bd79daa556
languageName: node
linkType: hard
"@types/glob@npm:^7.1.1":
version: 7.2.0
resolution: "@types/glob@npm:7.2.0"
@@ -2653,15 +2670,15 @@ __metadata:
languageName: node
linkType: hard
"babel-plugin-polyfill-corejs3@npm:^0.10.6":
version: 0.10.6
resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6"
"babel-plugin-polyfill-corejs3@npm:^0.11.0":
version: 0.11.1
resolution: "babel-plugin-polyfill-corejs3@npm:0.11.1"
dependencies:
"@babel/helper-define-polyfill-provider": "npm:^0.6.2"
core-js-compat: "npm:^3.38.0"
"@babel/helper-define-polyfill-provider": "npm:^0.6.3"
core-js-compat: "npm:^3.40.0"
peerDependencies:
"@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0
checksum: 10c0/3a69220471b07722c2ae6537310bf26b772514e12b601398082965459c838be70a0ca70b0662f0737070654ff6207673391221d48599abb4a2b27765206d9f79
checksum: 10c0/025f754b6296d84b20200aff63a3c1acdd85e8c621781f2bd27fe2512d0060526192d02329326947c6b29c27cf475fbcfaaff8c51eab1d2bfc7b79086bb64229
languageName: node
linkType: hard
@@ -2993,7 +3010,7 @@ __metadata:
languageName: node
linkType: hard
"core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1":
"core-js-compat@npm:^3.40.0":
version: 3.40.0
resolution: "core-js-compat@npm:3.40.0"
dependencies:
@@ -3524,16 +3541,16 @@ __metadata:
languageName: node
linkType: hard
"eslint@npm:9.19.0":
version: 9.19.0
resolution: "eslint@npm:9.19.0"
"eslint@npm:9.20.0":
version: 9.20.0
resolution: "eslint@npm:9.20.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.2.0"
"@eslint-community/regexpp": "npm:^4.12.1"
"@eslint/config-array": "npm:^0.19.0"
"@eslint/core": "npm:^0.10.0"
"@eslint/core": "npm:^0.11.0"
"@eslint/eslintrc": "npm:^3.2.0"
"@eslint/js": "npm:9.19.0"
"@eslint/js": "npm:9.20.0"
"@eslint/plugin-kit": "npm:^0.2.5"
"@humanfs/node": "npm:^0.16.6"
"@humanwhocodes/module-importer": "npm:^1.0.1"
@@ -3569,7 +3586,7 @@ __metadata:
optional: true
bin:
eslint: bin/eslint.js
checksum: 10c0/3b0dfaeff6a831de086884a3e2432f18468fe37c69f35e1a0a9a2833d9994a65b6dd2a524aaee28f361c849035ad9d15e3841029b67d261d0abd62c7de6d51f5
checksum: 10c0/5eb2d9b5ed85a0b022871d19719417d110afb07a4abfedd856ad03d9a821def5f6bc31d7c407ca27f56e5e66e39375300fd2b877017245eb99c44060d6c983bd
languageName: node
linkType: hard
@@ -4379,14 +4396,14 @@ __metadata:
resolution: "jenkins-ui@workspace:."
dependencies:
"@babel/cli": "npm:7.26.4"
"@babel/core": "npm:7.26.7"
"@babel/preset-env": "npm:7.26.7"
"@eslint/js": "npm:9.19.0"
"@babel/core": "npm:7.26.8"
"@babel/preset-env": "npm:7.26.8"
"@eslint/js": "npm:9.20.0"
babel-loader: "npm:9.2.1"
clean-webpack-plugin: "npm:4.0.0"
css-loader: "npm:7.1.2"
css-minimizer-webpack-plugin: "npm:7.0.0"
eslint: "npm:9.19.0"
eslint: "npm:9.20.0"
eslint-config-prettier: "npm:10.0.1"
eslint-formatter-checkstyle: "npm:8.40.0"
globals: "npm:15.14.0"
@@ -4396,16 +4413,16 @@ __metadata:
jquery: "npm:3.7.1"
lodash: "npm:4.17.21"
mini-css-extract-plugin: "npm:2.9.2"
postcss: "npm:8.5.1"
postcss: "npm:8.5.2"
postcss-loader: "npm:8.1.1"
postcss-preset-env: "npm:10.1.3"
postcss-scss: "npm:4.0.9"
prettier: "npm:3.4.2"
sass: "npm:1.83.4"
prettier: "npm:3.5.0"
sass: "npm:1.84.0"
sass-loader: "npm:16.0.4"
sortablejs: "npm:1.15.6"
style-loader: "npm:4.0.0"
stylelint: "npm:16.14.0"
stylelint: "npm:16.14.1"
stylelint-checkstyle-reporter: "npm:1.0.0"
stylelint-config-standard-scss: "npm:14.0.0"
tippy.js: "npm:6.3.7"
@@ -6126,14 +6143,14 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:8.5.1, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.5.1":
version: 8.5.1
resolution: "postcss@npm:8.5.1"
"postcss@npm:8.5.2, postcss@npm:^8.4.33, postcss@npm:^8.4.38, postcss@npm:^8.5.1":
version: 8.5.2
resolution: "postcss@npm:8.5.2"
dependencies:
nanoid: "npm:^3.3.8"
picocolors: "npm:^1.1.1"
source-map-js: "npm:^1.2.1"
checksum: 10c0/c4d90c59c98e8a0c102b77d3f4cac190f883b42d63dc60e2f3ed840f16197c0c8e25a4327d2e9a847b45a985612317dc0534178feeebd0a1cf3eb0eecf75cae4
checksum: 10c0/3044d49bc725029ab62292e8bf9849741251b95f3b754e191bf8b4025414d40ec3b4ac05c5a563d4b50060b5c8e96683eb4d783d8d8fa3867eb7b763cbe66127
languageName: node
linkType: hard
@@ -6144,12 +6161,12 @@ __metadata:
languageName: node
linkType: hard
"prettier@npm:3.4.2":
version: 3.4.2
resolution: "prettier@npm:3.4.2"
"prettier@npm:3.5.0":
version: 3.5.0
resolution: "prettier@npm:3.5.0"
bin:
prettier: bin/prettier.cjs
checksum: 10c0/99e076a26ed0aba4ebc043880d0f08bbb8c59a4c6641cdee6cdadf2205bdd87aa1d7823f50c3aea41e015e99878d37c58d7b5f0e663bba0ef047f94e36b96446
checksum: 10c0/6c355d74c377f5622953229d92477e8b9779162e848db90fd7e06c431deb73585d31fafc4516cf5868917825b97b9ec7c87c8d8b8e03ccd9fc9c0b7699d1a650
languageName: node
linkType: hard
@@ -6423,9 +6440,9 @@ __metadata:
languageName: node
linkType: hard
"sass@npm:1.83.4":
version: 1.83.4
resolution: "sass@npm:1.83.4"
"sass@npm:1.84.0":
version: 1.84.0
resolution: "sass@npm:1.84.0"
dependencies:
"@parcel/watcher": "npm:^2.4.1"
chokidar: "npm:^4.0.0"
@@ -6436,7 +6453,7 @@ __metadata:
optional: true
bin:
sass: sass.js
checksum: 10c0/6f27f0eebfeb50222b14baaeef548ef58a05daf8abd9797e6c499334ed7ad40541767056c8693780d06ca83d8836348ea7396a923d3be439b133507993ca78be
checksum: 10c0/4af28c12416b6f1fec2423677cfa8c48af7fb7652a50bd076e0cdd1ea260f0330948ddd6075368a734b8d6cfa16c9af5518292181334f47a9471cb542599bc7b
languageName: node
linkType: hard
@@ -6789,9 +6806,9 @@ __metadata:
languageName: node
linkType: hard
"stylelint@npm:16.14.0":
version: 16.14.0
resolution: "stylelint@npm:16.14.0"
"stylelint@npm:16.14.1":
version: 16.14.1
resolution: "stylelint@npm:16.14.1"
dependencies:
"@csstools/css-parser-algorithms": "npm:^3.0.4"
"@csstools/css-tokenizer": "npm:^3.0.3"
@@ -6833,7 +6850,7 @@ __metadata:
write-file-atomic: "npm:^5.0.1"
bin:
stylelint: bin/stylelint.mjs
checksum: 10c0/a420db3b5fc6d1b7cd1fea0ca754283c42e28377c143d3e6ab951365d7162110e239e6927e5752283244853223cb01b5c50bbbc6eb8ddfe603bc731d89c47327
checksum: 10c0/cce94374dc721d491d955f548ee81ba835d4955fa37d58a11323454f9f3721e5644fa89a04c14f85bdfa12790bdd043a41be2001a99cb0bfe23b38eb933199d7
languageName: node
linkType: hard