This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push:
new b1466d866c [MNG-8685] Better support for CI systems (#2254)
b1466d866c is described below
commit b1466d866cc4b113a13eb539773edcb398d05db3
Author: Tamas Cservenak <[email protected]>
AuthorDate: Sun Apr 13 20:50:07 2025 +0200
[MNG-8685] Better support for CI systems (#2254)
Improve CI detection of Maven, make possible to propagate some options from
CI to Maven.
Changes:
* `InvokerRequest` carries new info: `Optional<CIInfo>`: if present, we run
on CI, if empty, not.
* `Parser` (creating `InvokerRequest`) already inspects env and assembles
invoker request, so make it detect CI as well
* `CIDetector` is a Java Service (this all happens early, no DI yet) that
can be extended (like adding CI specific detectors). Core had one
implementation that became the "generic" that is what Maven 4 had so far.
* Added "jenkins", "github", "teamcity", "circle" and "travis" support.
---
https://issues.apache.org/jira/browse/MNG-8685
---
.../org/apache/maven/api/cli/InvokerRequest.java | 18 ++++
.../org/apache/maven/api/cli/cisupport/CIInfo.java | 49 +++++++++++
.../maven/cling/invoker/BaseInvokerRequest.java | 11 ++-
.../org/apache/maven/cling/invoker/BaseParser.java | 23 +++++
.../apache/maven/cling/invoker/LookupInvoker.java | 23 ++---
.../maven/cling/invoker/cisupport/CIDetector.java | 35 ++++++++
.../cling/invoker/cisupport/CIDetectorHelper.java | 50 +++++++++++
.../cling/invoker/cisupport/CircleCIDetector.java | 46 ++++++++++
.../cling/invoker/cisupport/GenericCIDetector.java | 53 ++++++++++++
.../cling/invoker/cisupport/GithubCIDetector.java | 52 ++++++++++++
.../cling/invoker/cisupport/JenkinsCIDetector.java | 46 ++++++++++
.../invoker/cisupport/TeamcityCIDetector.java | 46 ++++++++++
.../cling/invoker/cisupport/TravisCIDetector.java | 52 ++++++++++++
.../maven/cling/invoker/mvn/MavenInvoker.java | 7 +-
.../cling/invoker/mvn/MavenInvokerRequest.java | 5 +-
.../maven/cling/invoker/mvn/MavenParser.java | 1 +
.../invoker/mvnenc/EncryptInvokerRequest.java | 5 +-
.../maven/cling/invoker/mvnenc/EncryptParser.java | 1 +
.../cling/invoker/mvnsh/ShellInvokerRequest.java | 5 +-
.../maven/cling/invoker/mvnsh/ShellParser.java | 1 +
...apache.maven.cling.invoker.cisupport.CIDetector | 6 ++
.../invoker/cisupport/CIDetectorHelperRunner.java | 34 ++++++++
.../invoker/cisupport/CIDetectorHelperTest.java | 97 ++++++++++++++++++++++
.../MavenITmng4461ArtifactUploadMonitorTest.java | 2 +-
.../MavenITmng4829ChecksumFailureWarningTest.java | 2 +-
...avenITmng6240PluginExtensionAetherProvider.java | 4 +-
.../main/java/org/apache/maven/it/Verifier.java | 13 +++
27 files changed, 661 insertions(+), 26 deletions(-)
diff --git
a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java
b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java
index e9b2a480ed..64003dc723 100644
---
a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java
+++
b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java
@@ -28,6 +28,7 @@
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Immutable;
import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.cli.cisupport.CIInfo;
import org.apache.maven.api.services.Lookup;
import org.apache.maven.api.services.MessageBuilderFactory;
@@ -182,6 +183,15 @@ default Optional<OutputStream> stdErr() {
@Nonnull
Optional<List<CoreExtensions>> coreExtensions();
+ /**
+ * Returns detected CI system, if any.
+ *
+ * @return an {@link Optional} containing the {@link CIInfo} collected
from CI system. or empty if CI not
+ * detected.
+ */
+ @Nonnull
+ Optional<CIInfo> ciInfo();
+
/**
* Returns the options associated with this invocation request.
*
@@ -189,4 +199,12 @@ default Optional<OutputStream> stdErr() {
*/
@Nonnull
Options options();
+
+ /**
+ * This method returns "verbose" option value derived from multiple
places: CLI options, but also CI detection,
+ * if applicable.
+ */
+ default boolean effectiveVerbose() {
+ return options().verbose().orElse(ciInfo().isPresent() &&
ciInfo().get().isVerbose());
+ }
}
diff --git
a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/cisupport/CIInfo.java
b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/cisupport/CIInfo.java
new file mode 100644
index 0000000000..ced54f8373
--- /dev/null
+++
b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/cisupport/CIInfo.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api.cli.cisupport;
+
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * CI support: this class contains gathered information and more from CI that
Maven process runs on.
+ *
+ * @since 4.0.0
+ */
+public interface CIInfo {
+ /**
+ * Short distinct name of CI system: "GH", "Jenkins", etc.
+ */
+ @Nonnull
+ String name();
+
+ /**
+ * May return a message that will be logged by Maven explaining why it was
detected (and possibly more).
+ */
+ @Nonnull
+ default String message() {
+ return "";
+ }
+
+ /**
+ * Some CI systems may allow running jobs in "debug" (or some equivalent)
mode.
+ */
+ default boolean isVerbose() {
+ return false;
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java
index caef621191..02960ecd54 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java
@@ -28,6 +28,7 @@
import org.apache.maven.api.cli.CoreExtensions;
import org.apache.maven.api.cli.InvokerRequest;
import org.apache.maven.api.cli.ParserRequest;
+import org.apache.maven.api.cli.cisupport.CIInfo;
import static java.util.Objects.requireNonNull;
@@ -42,6 +43,7 @@ public abstract class BaseInvokerRequest implements
InvokerRequest {
private final Path topDirectory;
private final Path rootDirectory;
private final List<CoreExtensions> coreExtensions;
+ private final CIInfo ciInfo;
@SuppressWarnings("ParameterNumber")
public BaseInvokerRequest(
@@ -54,7 +56,8 @@ public BaseInvokerRequest(
@Nonnull Map<String, String> systemProperties,
@Nonnull Path topDirectory,
@Nullable Path rootDirectory,
- @Nullable List<CoreExtensions> coreExtensions) {
+ @Nullable List<CoreExtensions> coreExtensions,
+ @Nullable CIInfo ciInfo) {
this.parserRequest = requireNonNull(parserRequest);
this.parsingFailed = parsingFailed;
this.cwd = requireNonNull(cwd);
@@ -66,6 +69,7 @@ public BaseInvokerRequest(
this.topDirectory = requireNonNull(topDirectory);
this.rootDirectory = rootDirectory;
this.coreExtensions = coreExtensions;
+ this.ciInfo = ciInfo;
}
@Override
@@ -117,4 +121,9 @@ public Optional<Path> rootDirectory() {
public Optional<List<CoreExtensions>> coreExtensions() {
return Optional.ofNullable(coreExtensions);
}
+
+ @Override
+ public Optional<CIInfo> ciInfo() {
+ return Optional.ofNullable(ciInfo);
+ }
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
index 8427203faf..e13f764769 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java
@@ -43,11 +43,13 @@
import org.apache.maven.api.cli.Options;
import org.apache.maven.api.cli.Parser;
import org.apache.maven.api.cli.ParserRequest;
+import org.apache.maven.api.cli.cisupport.CIInfo;
import org.apache.maven.api.cli.extensions.CoreExtension;
import org.apache.maven.api.cli.extensions.InputLocation;
import org.apache.maven.api.cli.extensions.InputSource;
import org.apache.maven.api.services.Interpolator;
import org.apache.maven.cling.internal.extension.io.CoreExtensionsStaxReader;
+import org.apache.maven.cling.invoker.cisupport.CIDetectorHelper;
import org.apache.maven.cling.props.MavenPropertiesLoader;
import org.apache.maven.cling.utils.CLIReportingUtils;
import org.apache.maven.properties.internal.EnvironmentUtils;
@@ -86,6 +88,9 @@ public LocalContext(ParserRequest parserRequest) {
@Nullable
public List<CoreExtensions> extensions;
+ @Nullable
+ public CIInfo ciInfo;
+
public Options options;
public Map<String, String> extraInterpolationSource() {
@@ -190,6 +195,9 @@ public InvokerRequest parseInvocation(ParserRequest
parserRequest) {
parserRequest.logger().error("Error reading core extensions
descriptor", e);
}
+ // CI detection
+ context.ciInfo = detectCI(context);
+
// only if not failed so far; otherwise we may have no options to
validate
if (!context.parsingFailed) {
validate(context);
@@ -500,4 +508,19 @@ protected List<CoreExtension>
validateCoreExtensionsDescriptorFromFile(
.collect(Collectors.joining(", ")))
.collect(Collectors.joining("; ")));
}
+
+ @Nullable
+ protected CIInfo detectCI(LocalContext context) {
+ List<CIInfo> detected = CIDetectorHelper.detectCI();
+ if (detected.isEmpty()) {
+ return null;
+ } else if (detected.size() > 1) {
+ // warn
+ context.parserRequest
+ .logger()
+ .warn("Multiple CI systems detected: "
+ +
detected.stream().map(CIInfo::name).collect(Collectors.joining(", ")));
+ }
+ return detected.get(0);
+ }
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java
index a5935320f4..c0b8c50b56 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java
@@ -46,6 +46,7 @@
import org.apache.maven.api.cli.InvokerRequest;
import org.apache.maven.api.cli.Logger;
import org.apache.maven.api.cli.Options;
+import org.apache.maven.api.cli.cisupport.CIInfo;
import org.apache.maven.api.cli.logging.AccumulatingLogger;
import org.apache.maven.api.services.BuilderProblem;
import org.apache.maven.api.services.Interpolator;
@@ -278,7 +279,7 @@ protected void configureLogging(C context) throws Exception
{
context.slf4jConfiguration =
Slf4jConfigurationFactory.getConfiguration(context.loggerFactory);
context.loggerLevel = Slf4jConfiguration.Level.INFO;
- if (mavenOptions.verbose().orElse(false)) {
+ if (context.invokerRequest.effectiveVerbose()) {
context.loggerLevel = Slf4jConfiguration.Level.DEBUG;
} else if (mavenOptions.quiet().orElse(false)) {
context.loggerLevel = Slf4jConfiguration.Level.ERROR;
@@ -465,7 +466,7 @@ protected void showVersion(C context) {
InvokerRequest invokerRequest = context.invokerRequest;
if (invokerRequest.options().quiet().orElse(false)) {
writer.accept(CLIReportingUtils.showVersionMinimal());
- } else if (invokerRequest.options().verbose().orElse(false)) {
+ } else if (invokerRequest.effectiveVerbose()) {
writer.accept(CLIReportingUtils.showVersion(
ProcessHandle.current().info().commandLine().orElse(null),
describe(context.terminal)));
@@ -493,9 +494,8 @@ protected String describe(Terminal terminal) {
}
protected void preCommands(C context) throws Exception {
- Options mavenOptions = context.invokerRequest.options();
- boolean verbose = mavenOptions.verbose().orElse(false);
- boolean version = mavenOptions.showVersion().orElse(false);
+ boolean verbose = context.invokerRequest.effectiveVerbose();
+ boolean version =
context.invokerRequest.options().showVersion().orElse(false);
if (verbose || version) {
showVersion(context);
}
@@ -726,11 +726,11 @@ protected boolean mayDisableInteractiveMode(C context,
boolean proposedInteracti
if
(context.invokerRequest.options().nonInteractive().orElse(false)) {
return false;
} else {
- boolean runningOnCI = isRunningOnCI(context);
- if (runningOnCI) {
+ if (context.invokerRequest.ciInfo().isPresent()) {
+ CIInfo ci = context.invokerRequest.ciInfo().get();
context.logger.info(
- "Making this build non-interactive, because the
environment variable CI equals \"true\"."
- + " Disable this detection by removing
that variable or adding --force-interactive.");
+ "Making this build non-interactive, because CI
detected. Disable this detection by adding --force-interactive.");
+ context.logger.info("Detected CI system: '" + ci.name() +
"': " + ci.message());
return false;
}
}
@@ -935,10 +935,5 @@ protected int calculateDegreeOfConcurrency(String
threadConfiguration) {
}
}
- protected boolean isRunningOnCI(C context) {
- String ciEnv =
context.protoSession.getSystemProperties().get("env.CI");
- return ciEnv != null && !"false".equals(ciEnv);
- }
-
protected abstract int execute(C context) throws Exception;
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CIDetector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CIDetector.java
new file mode 100644
index 0000000000..5d056d05d4
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CIDetector.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.Optional;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * Service interface to detect CI system process runs on, if any.
+ *
+ * @since 4.0.0
+ */
+public interface CIDetector {
+ /**
+ * Returns non-empty optional with CI information, if CI is detected,
empty otherwise.
+ */
+ Optional<CIInfo> detectCI();
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelper.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelper.java
new file mode 100644
index 0000000000..6c95755eb8
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelper.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.ServiceLoader;
+import java.util.stream.Collectors;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * CI detector helper: it uses service discovery to discover {@link
CIDetector}s. If resulting list has more than
+ * one element, it will remove the {@link GenericCIDetector} result, assuming
a more specific one is also present.
+ */
+public final class CIDetectorHelper {
+ private CIDetectorHelper() {}
+
+ public static List<CIInfo> detectCI() {
+ ArrayList<CIInfo> result =
ServiceLoader.load(CIDetector.class).stream()
+ .map(ServiceLoader.Provider::get)
+ .map(CIDetector::detectCI)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(Collectors.toCollection(ArrayList::new));
+
+ if (result.size() > 1) {
+ // remove generic
+ result.removeIf(c -> GenericCIDetector.NAME.equals(c.name()));
+ }
+ return result;
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CircleCIDetector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CircleCIDetector.java
new file mode 100644
index 0000000000..95c47a382b
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/CircleCIDetector.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.Optional;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * Circle CI support.
+ */
+public class CircleCIDetector implements CIDetector {
+ public static final String NAME = "CircleCI";
+
+ private static final String CIRCLECI = "CIRCLECI";
+
+ @Override
+ public Optional<CIInfo> detectCI() {
+ String ciEnv = System.getenv(CIRCLECI);
+ if ("true".equals(ciEnv)) {
+ return Optional.of(new CIInfo() {
+ @Override
+ public String name() {
+ return NAME;
+ }
+ });
+ }
+ return Optional.empty();
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/GenericCIDetector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/GenericCIDetector.java
new file mode 100644
index 0000000000..4b12406ff2
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/GenericCIDetector.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.Optional;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * Generic CI support. This offers same support as Maven 3 always had. Is also
special, as code will reject this
+ * detector result IF there are also any other returned via discovered
services.
+ */
+public class GenericCIDetector implements CIDetector {
+ public static final String NAME = "Generic";
+
+ private static final String CI = "CI";
+
+ @Override
+ public Optional<CIInfo> detectCI() {
+ String ciEnv = System.getenv(CI);
+ if (ciEnv != null && !"false".equals(ciEnv)) {
+ return Optional.of(new CIInfo() {
+ @Override
+ public String name() {
+ return NAME;
+ }
+
+ @Override
+ public String message() {
+ return "Environment variable " + CI
+ + " is set and its value is not \"false\". Disable
this detection by removing that variable or by setting it to \"false\"";
+ }
+ });
+ }
+ return Optional.empty();
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/GithubCIDetector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/GithubCIDetector.java
new file mode 100644
index 0000000000..67ed91a226
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/GithubCIDetector.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.Optional;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * GitHub CI support.
+ */
+public class GithubCIDetector implements CIDetector {
+ public static final String NAME = "GitHub";
+
+ private static final String GITHUB_ACTIONS = "GITHUB_ACTIONS";
+ private static final String RUNNER_DEBUG = "RUNNER_DEBUG";
+
+ @Override
+ public Optional<CIInfo> detectCI() {
+ String ciEnv = System.getenv(GITHUB_ACTIONS);
+ if ("true".equals(ciEnv)) {
+ return Optional.of(new CIInfo() {
+ @Override
+ public String name() {
+ return NAME;
+ }
+
+ @Override
+ public boolean isVerbose() {
+ return "1".equals(System.getenv(RUNNER_DEBUG));
+ }
+ });
+ }
+ return Optional.empty();
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/JenkinsCIDetector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/JenkinsCIDetector.java
new file mode 100644
index 0000000000..4bb3029ab6
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/JenkinsCIDetector.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.Optional;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * Jenkins CI support.
+ */
+public class JenkinsCIDetector implements CIDetector {
+ public static final String NAME = "Jenkins";
+
+ private static final String WORKSPACE = "WORKSPACE";
+
+ @Override
+ public Optional<CIInfo> detectCI() {
+ String workspace = System.getenv(WORKSPACE);
+ if (workspace != null && !workspace.trim().isEmpty()) {
+ return Optional.of(new CIInfo() {
+ @Override
+ public String name() {
+ return NAME;
+ }
+ });
+ }
+ return Optional.empty();
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/TeamcityCIDetector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/TeamcityCIDetector.java
new file mode 100644
index 0000000000..ed14de34dc
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/TeamcityCIDetector.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.Optional;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * TeamCity CI support.
+ */
+public class TeamcityCIDetector implements CIDetector {
+ public static final String NAME = "TeamCity";
+
+ private static final String TEAMCITY_VERSION = "TEAMCITY_VERSION";
+
+ @Override
+ public Optional<CIInfo> detectCI() {
+ String ciEnv = System.getenv(TEAMCITY_VERSION);
+ if (ciEnv != null && !ciEnv.trim().isEmpty()) {
+ return Optional.of(new CIInfo() {
+ @Override
+ public String name() {
+ return NAME;
+ }
+ });
+ }
+ return Optional.empty();
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/TravisCIDetector.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/TravisCIDetector.java
new file mode 100644
index 0000000000..2e43e7e747
--- /dev/null
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/cisupport/TravisCIDetector.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.Optional;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+/**
+ * Travis CI support.
+ */
+public class TravisCIDetector implements CIDetector {
+ public static final String NAME = "Travis";
+
+ private static final String TRAVIS = "TRAVIS";
+ private static final String TRAVIS_DEBUG_MODE = "TRAVIS_DEBUG_MODE";
+
+ @Override
+ public Optional<CIInfo> detectCI() {
+ String ciEnv = System.getenv(TRAVIS);
+ if ("true".equals(ciEnv)) {
+ return Optional.of(new CIInfo() {
+ @Override
+ public String name() {
+ return NAME;
+ }
+
+ @Override
+ public boolean isVerbose() {
+ return "true".equals(System.getenv(TRAVIS_DEBUG_MODE));
+ }
+ });
+ }
+ return Optional.empty();
+ }
+}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
index 1365de51e1..44b435712e 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java
@@ -362,8 +362,7 @@ protected ExecutionListener
determineExecutionListener(MavenContext context) {
protected TransferListener determineTransferListener(MavenContext context,
boolean noTransferProgress) {
boolean quiet = context.invokerRequest.options().quiet().orElse(false);
boolean logFile =
context.invokerRequest.options().logFile().isPresent();
- boolean runningOnCI = isRunningOnCI(context);
- boolean quietCI = runningOnCI
+ boolean quietCI = context.invokerRequest.ciInfo().isPresent()
&&
!context.invokerRequest.options().forceInteractive().orElse(false);
TransferListener delegate;
@@ -373,7 +372,7 @@ protected TransferListener
determineTransferListener(MavenContext context, boole
SimplexTransferListener simplex = new SimplexTransferListener(new
ConsoleMavenTransferListener(
context.invokerRequest.messageBuilderFactory(),
context.terminal.writer(),
- context.invokerRequest.options().verbose().orElse(false)));
+ context.invokerRequest.effectiveVerbose()));
context.closeables.add(simplex);
delegate = simplex;
} else {
@@ -485,7 +484,7 @@ protected int doExecute(MavenContext context,
MavenExecutionRequest request) thr
context.logger.error("To see the full stack trace of the
errors, re-run Maven with the '"
+ MessageUtils.builder().strong("-e") + "' switch");
}
- if (!context.invokerRequest.options().verbose().orElse(false)) {
+ if (!context.invokerRequest.effectiveVerbose()) {
context.logger.error("Re-run Maven using the '"
+ MessageUtils.builder().strong("-X") + "' switch to
enable verbose output");
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvokerRequest.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvokerRequest.java
index 2df07aec03..baa03a079d 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvokerRequest.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvokerRequest.java
@@ -25,6 +25,7 @@
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.cli.CoreExtensions;
import org.apache.maven.api.cli.ParserRequest;
+import org.apache.maven.api.cli.cisupport.CIInfo;
import org.apache.maven.api.cli.mvn.MavenOptions;
import org.apache.maven.cling.invoker.BaseInvokerRequest;
@@ -48,6 +49,7 @@ public MavenInvokerRequest(
Path topDirectory,
Path rootDirectory,
List<CoreExtensions> coreExtensions,
+ CIInfo ciInfo,
MavenOptions options) {
super(
parserRequest,
@@ -59,7 +61,8 @@ public MavenInvokerRequest(
systemProperties,
topDirectory,
rootDirectory,
- coreExtensions);
+ coreExtensions,
+ ciInfo);
this.options = requireNonNull(options);
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java
index fd030ba185..a8238d90ee 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java
@@ -123,6 +123,7 @@ protected MavenInvokerRequest
getInvokerRequest(LocalContext context) {
context.topDirectory,
context.rootDirectory,
context.extensions,
+ context.ciInfo,
(MavenOptions) context.options);
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvokerRequest.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvokerRequest.java
index f2847b624f..059aecd904 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvokerRequest.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvokerRequest.java
@@ -25,6 +25,7 @@
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.cli.CoreExtensions;
import org.apache.maven.api.cli.ParserRequest;
+import org.apache.maven.api.cli.cisupport.CIInfo;
import org.apache.maven.api.cli.mvnenc.EncryptOptions;
import org.apache.maven.cling.invoker.BaseInvokerRequest;
@@ -45,6 +46,7 @@ public EncryptInvokerRequest(
Path topDirectory,
Path rootDirectory,
List<CoreExtensions> coreExtensions,
+ CIInfo ciInfo,
EncryptOptions options) {
super(
parserRequest,
@@ -56,7 +58,8 @@ public EncryptInvokerRequest(
systemProperties,
topDirectory,
rootDirectory,
- coreExtensions);
+ coreExtensions,
+ ciInfo);
this.options = requireNonNull(options);
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java
index 9a1da7ddbd..378f81f383 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java
@@ -50,6 +50,7 @@ protected EncryptInvokerRequest
getInvokerRequest(LocalContext context) {
context.topDirectory,
context.rootDirectory,
context.extensions,
+ context.ciInfo,
(EncryptOptions) context.options);
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvokerRequest.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvokerRequest.java
index 5a841a9658..0b2fdf31f9 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvokerRequest.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvokerRequest.java
@@ -25,6 +25,7 @@
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.cli.CoreExtensions;
import org.apache.maven.api.cli.ParserRequest;
+import org.apache.maven.api.cli.cisupport.CIInfo;
import org.apache.maven.api.cli.mvnsh.ShellOptions;
import org.apache.maven.cling.invoker.BaseInvokerRequest;
@@ -45,6 +46,7 @@ public ShellInvokerRequest(
Path topDirectory,
Path rootDirectory,
List<CoreExtensions> coreExtensions,
+ CIInfo ciInfo,
ShellOptions options) {
super(
parserRequest,
@@ -56,7 +58,8 @@ public ShellInvokerRequest(
systemProperties,
topDirectory,
rootDirectory,
- coreExtensions);
+ coreExtensions,
+ ciInfo);
this.options = requireNonNull(options);
}
diff --git
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java
index 5c91146f1f..31c87e2f90 100644
---
a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java
+++
b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java
@@ -49,6 +49,7 @@ protected ShellInvokerRequest getInvokerRequest(LocalContext
context) {
context.topDirectory,
context.rootDirectory,
context.extensions,
+ context.ciInfo,
(ShellOptions) context.options);
}
diff --git
a/impl/maven-cli/src/main/resources/META-INF/services/org.apache.maven.cling.invoker.cisupport.CIDetector
b/impl/maven-cli/src/main/resources/META-INF/services/org.apache.maven.cling.invoker.cisupport.CIDetector
new file mode 100644
index 0000000000..d7051280e9
--- /dev/null
+++
b/impl/maven-cli/src/main/resources/META-INF/services/org.apache.maven.cling.invoker.cisupport.CIDetector
@@ -0,0 +1,6 @@
+org.apache.maven.cling.invoker.cisupport.CircleCIDetector
+org.apache.maven.cling.invoker.cisupport.GenericCIDetector
+org.apache.maven.cling.invoker.cisupport.GithubCIDetector
+org.apache.maven.cling.invoker.cisupport.JenkinsCIDetector
+org.apache.maven.cling.invoker.cisupport.TeamcityCIDetector
+org.apache.maven.cling.invoker.cisupport.TravisCIDetector
diff --git
a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelperRunner.java
b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelperRunner.java
new file mode 100644
index 0000000000..2a8cfd1ef0
--- /dev/null
+++
b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelperRunner.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.util.List;
+
+import org.apache.maven.api.cli.cisupport.CIInfo;
+
+public class CIDetectorHelperRunner {
+ public static void main(String[] args) {
+ List<CIInfo> detect = CIDetectorHelper.detectCI();
+ if (detect.isEmpty()) {
+ System.out.print("NONE;");
+ } else {
+ detect.forEach(d -> System.out.print(d.name() + (d.isVerbose() ?
"+VERBOSE" : "") + ";"));
+ }
+ }
+}
diff --git
a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelperTest.java
b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelperTest.java
new file mode 100644
index 0000000000..8be4e40b7c
--- /dev/null
+++
b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/cisupport/CIDetectorHelperTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.cling.invoker.cisupport;
+
+import java.nio.file.FileSystems;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.impl.util.Os;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class CIDetectorHelperTest {
+ private static final Set<String> ALL =
+ Set.of("CIRCLECI", "CI", "WORKSPACE", "GITHUB_ACTIONS",
"TEAMCITY_VERSION", "TRAVIS");
+
+ @Test
+ void none() throws Exception {
+ assertEquals("NONE;", runner(Map.of()));
+ }
+
+ @Test
+ void generic() throws Exception {
+ assertEquals(GenericCIDetector.NAME + ";", runner(Map.of("CI",
"true")));
+ }
+
+ @Test
+ void jenkins() throws Exception {
+ assertEquals(JenkinsCIDetector.NAME + ";", runner(Map.of("CI", "true",
"WORKSPACE", "foobar")));
+ }
+
+ @Test
+ void circleci() throws Exception {
+ assertEquals(CircleCIDetector.NAME + ";", runner(Map.of("CIRCLECI",
"true")));
+ }
+
+ @Test
+ void teamcity() throws Exception {
+ assertEquals(TeamcityCIDetector.NAME + ";",
runner(Map.of("TEAMCITY_VERSION", "1.2.3")));
+ }
+
+ @Test
+ void github() throws Exception {
+ assertEquals(GithubCIDetector.NAME + ";", runner(Map.of("CI", "true",
"GITHUB_ACTIONS", "true")));
+ }
+
+ @Test
+ void githubDebug() throws Exception {
+ assertEquals(
+ GithubCIDetector.NAME + "+VERBOSE;",
+ runner(Map.of("CI", "true", "GITHUB_ACTIONS", "true",
"RUNNER_DEBUG", "1")));
+ }
+
+ @Test
+ void travis() throws Exception {
+ assertEquals(TravisCIDetector.NAME + ";", runner(Map.of("TRAVIS",
"true")));
+ }
+
+ @Test
+ void travisDebug() throws Exception {
+ assertEquals(
+ TravisCIDetector.NAME + "+VERBOSE;", runner(Map.of("TRAVIS",
"true", "TRAVIS_DEBUG_MODE", "true")));
+ }
+
+ private static String runner(Map<String, String> add) throws Exception {
+ String separator = FileSystems.getDefault().getSeparator();
+ String classpath = System.getProperty("java.class.path");
+ String path =
+ System.getProperty("java.home") + separator + "bin" +
separator + (Os.IS_WINDOWS ? "java.exe" : "java");
+ ProcessBuilder processBuilder =
+ new ProcessBuilder(path, "-cp", classpath,
CIDetectorHelperRunner.class.getName());
+ processBuilder.environment().putAll(add);
+ ALL.stream()
+ .filter(s -> !add.containsKey(s))
+ .forEach(k -> processBuilder.environment().remove(k));
+ Process process = processBuilder.start();
+ process.waitFor();
+ return new String(process.getInputStream().readAllBytes());
+ }
+}
diff --git
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4461ArtifactUploadMonitorTest.java
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4461ArtifactUploadMonitorTest.java
index 2917116f3b..12df894678 100644
---
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4461ArtifactUploadMonitorTest.java
+++
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4461ArtifactUploadMonitorTest.java
@@ -45,7 +45,7 @@ public void testit() throws Exception {
Verifier verifier = newVerifier(testDir.getAbsolutePath());
verifier.setAutoclean(false);
verifier.deleteDirectory("target");
- verifier.setEnvironmentVariable("CI", "false");
+ verifier.removeCIEnvironmentVariables();
verifier.addCliArgument("validate");
verifier.execute();
verifier.verifyErrorFreeLog();
diff --git
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4829ChecksumFailureWarningTest.java
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4829ChecksumFailureWarningTest.java
index 414bc60811..f341dee54c 100644
---
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4829ChecksumFailureWarningTest.java
+++
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4829ChecksumFailureWarningTest.java
@@ -51,7 +51,7 @@ public void testit() throws Exception {
verifier.deleteArtifacts("org.apache.maven.its.mng4829");
verifier.addCliArgument("-s");
verifier.addCliArgument("settings.xml");
- verifier.setEnvironmentVariable("CI", "false");
+ verifier.removeCIEnvironmentVariables();
verifier.filterFile("settings-template.xml", "settings.xml");
verifier.addCliArgument("validate");
verifier.execute();
diff --git
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6240PluginExtensionAetherProvider.java
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6240PluginExtensionAetherProvider.java
index e413f2151b..b8ef04777d 100644
---
a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6240PluginExtensionAetherProvider.java
+++
b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6240PluginExtensionAetherProvider.java
@@ -54,13 +54,13 @@ public void
testPluginExtensionDependingOnMavenAetherProvider() throws Exception
File projectDir = new File(testDir, "project");
Verifier verifier = newVerifier(pluginDir.getAbsolutePath());
- verifier.setEnvironmentVariable("CI", "false");
+ verifier.removeCIEnvironmentVariables();
verifier.addCliArgument("install");
verifier.execute();
verifier.verifyErrorFreeLog();
verifier = newVerifier(projectDir.getAbsolutePath());
- verifier.setEnvironmentVariable("CI", "false");
+ verifier.removeCIEnvironmentVariables();
verifier.addCliArgument("deploy");
verifier.execute();
verifier.verifyErrorFreeLog();
diff --git
a/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
b/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
index 04be2c6dbf..0b0dd2a1ed 100644
---
a/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
+++
b/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
@@ -296,6 +296,19 @@ public Properties getSystemProperties() {
return systemProperties;
}
+ /**
+ * This method renders all env variables that are used for CI detection
(by all known detector) to not trigger.
+ */
+ public void removeCIEnvironmentVariables() {
+ environmentVariables.putAll(Map.of(
+ "CIRCLECI", "",
+ "CI", "false",
+ "GITHUB_ACTIONS", "",
+ "WORKSPACE", "",
+ "TEAMCITY_VERSION", "",
+ "TRAVIS", ""));
+ }
+
public void setEnvironmentVariable(String key, String value) {
if (value != null) {
environmentVariables.put(key, value);