aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine
diff options
context:
space:
mode:
authorMichal Duda <michal.duda@sonarsource.com>2021-03-01 17:48:43 +0100
committersonartech <sonartech@sonarsource.com>2021-03-04 20:12:49 +0000
commit4c007c151c20a92ed5d76ce5ac04bae53919586e (patch)
tree46ebcf58d5bc7949c513d54b9ebb1feae5df8f1c /sonar-scanner-engine
parent4558e5786f367160a219fd8bbc1f9872e51ea661 (diff)
downloadsonarqube-4c007c151c20a92ed5d76ce5ac04bae53919586e.tar.gz
sonarqube-4c007c151c20a92ed5d76ce5ac04bae53919586e.zip
SONAR-14525 include CI usage information in telemetry
Diffstat (limited to 'sonar-scanner-engine')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfiguration.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationImpl.java9
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java7
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AppVeyor.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AwsCodeBuild.java54
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AzureDevops.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bamboo.java50
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/BitbucketPipelines.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bitrise.java57
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Buildkite.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CircleCi.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CirrusCi.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/DroneCi.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GitlabCi.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java8
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/SemaphoreCi.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/TravisCi.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java42
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java6
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java18
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java14
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java64
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.java60
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java70
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java16
26 files changed, 455 insertions, 63 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfiguration.java
index 8b8ee783a7d..5b57c38015f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfiguration.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfiguration.java
@@ -29,6 +29,11 @@ import java.util.Optional;
public interface CiConfiguration {
/**
+ * Name of the CI environment
+ */
+ String getCiName();
+
+ /**
* The revision that triggered the analysis. It should
* be the revision as seen by end-user, but not the necessarily
* the effective revision of the clone on disk (merge commit with
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationImpl.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationImpl.java
index f7baa5741f5..9ac6bd86573 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationImpl.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationImpl.java
@@ -25,16 +25,23 @@ import javax.annotation.Nullable;
import static org.apache.commons.lang.StringUtils.defaultIfBlank;
public class CiConfigurationImpl implements CiConfiguration {
+ private final String ciName;
@Nullable
private final String scmRevision;
- public CiConfigurationImpl(@Nullable String scmRevision) {
+ public CiConfigurationImpl(@Nullable String scmRevision, String ciName) {
this.scmRevision = defaultIfBlank(scmRevision, null);
+ this.ciName = ciName;
}
@Override
public Optional<String> getScmRevision() {
return Optional.ofNullable(scmRevision);
}
+
+ @Override
+ public String getCiName() {
+ return ciName;
+ }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java
index be8f5c1f84d..ea84fbcb918 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/CiConfigurationProvider.java
@@ -57,10 +57,15 @@ public class CiConfigurationProvider extends ProviderAdapter {
return new EmptyCiConfiguration();
}
- private static class EmptyCiConfiguration implements CiConfiguration {
+ static class EmptyCiConfiguration implements CiConfiguration {
@Override
public Optional<String> getScmRevision() {
return Optional.empty();
}
+
+ @Override
+ public String getCiName() {
+ return "undetected";
+ }
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AppVeyor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AppVeyor.java
index 2444e4475fa..863221c7b6e 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AppVeyor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AppVeyor.java
@@ -26,7 +26,7 @@ import org.sonar.scanner.ci.CiVendor;
/**
* Support of https://www.appveyor.com
- *
+ * <p>
* Environment variables: https://www.appveyor.com/docs/environment-variables/
*/
public class AppVeyor implements CiVendor {
@@ -50,6 +50,6 @@ public class AppVeyor implements CiVendor {
@Override
public CiConfiguration loadConfiguration() {
String revision = system.envVariable("APPVEYOR_REPO_COMMIT");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AwsCodeBuild.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AwsCodeBuild.java
new file mode 100644
index 00000000000..5f57825ddc4
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AwsCodeBuild.java
@@ -0,0 +1,54 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.ci.vendors;
+
+import org.sonar.api.utils.System2;
+import org.sonar.scanner.ci.CiConfiguration;
+import org.sonar.scanner.ci.CiConfigurationImpl;
+import org.sonar.scanner.ci.CiVendor;
+
+public class AwsCodeBuild implements CiVendor {
+ private final System2 system;
+
+ public AwsCodeBuild(System2 system) {
+ this.system = system;
+ }
+
+ @Override
+ public String getName() {
+ return "AwsCodeBuild";
+ }
+
+
+ @Override
+ public boolean isDetected() {
+ return environmentVariableIsPresent("CODEBUILD_BUILD_ID") &&
+ environmentVariableIsPresent("CODEBUILD_START_TIME");
+ }
+
+ @Override
+ public CiConfiguration loadConfiguration() {
+ return new CiConfigurationImpl(null, getName());
+ }
+
+ private boolean environmentVariableIsPresent(String key) {
+ return system.envVariable(key) != null;
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AzureDevops.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AzureDevops.java
index 3610691fbdb..0e2d2b09697 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AzureDevops.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/AzureDevops.java
@@ -28,7 +28,7 @@ import static org.apache.commons.lang.StringUtils.isBlank;
/**
* Support of https://azure.microsoft.com/en-us/services/devops/
- *
+ * <p>
* Environment variables: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables
*/
public class AzureDevops implements CiVendor {
@@ -55,6 +55,6 @@ public class AzureDevops implements CiVendor {
if (isBlank(revision)) {
revision = system.envVariable("BUILD_SOURCEVERSION");
}
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bamboo.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bamboo.java
new file mode 100644
index 00000000000..98e856d2858
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bamboo.java
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.ci.vendors;
+
+import org.sonar.api.utils.System2;
+import org.sonar.scanner.ci.CiConfiguration;
+import org.sonar.scanner.ci.CiConfigurationImpl;
+import org.sonar.scanner.ci.CiVendor;
+
+public class Bamboo implements CiVendor {
+ private final System2 system;
+
+ public Bamboo(System2 system) {
+ this.system = system;
+ }
+
+ @Override
+ public String getName() {
+ return "Bamboo";
+ }
+
+
+ @Override
+ public boolean isDetected() {
+ return system.envVariable("bamboo_buildNumber") != null;
+ }
+
+ @Override
+ public CiConfiguration loadConfiguration() {
+ String revision = system.envVariable("bamboo_planRepository_revision");
+ return new CiConfigurationImpl(revision, getName());
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/BitbucketPipelines.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/BitbucketPipelines.java
index c4f96476ce7..798166a8102 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/BitbucketPipelines.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/BitbucketPipelines.java
@@ -49,6 +49,6 @@ public class BitbucketPipelines implements CiVendor {
@Override
public CiConfiguration loadConfiguration() {
String revision = system.envVariable("BITBUCKET_COMMIT");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bitrise.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bitrise.java
new file mode 100644
index 00000000000..9fec71f4efc
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Bitrise.java
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.ci.vendors;
+
+import java.util.Optional;
+import org.sonar.api.utils.System2;
+import org.sonar.scanner.ci.CiConfiguration;
+import org.sonar.scanner.ci.CiConfigurationImpl;
+import org.sonar.scanner.ci.CiVendor;
+
+public class Bitrise implements CiVendor {
+
+ private final System2 system2;
+
+ public Bitrise(System2 system2) {
+ this.system2 = system2;
+ }
+
+ @Override
+ public String getName() {
+ return "Bitrise";
+ }
+
+ @Override
+ public boolean isDetected() {
+ return environmentVariableIsTrue("CI") && environmentVariableIsTrue("BITRISE_IO");
+ }
+
+ @Override
+ public CiConfiguration loadConfiguration() {
+ String revision = system2.envVariable("BITRISE_GIT_COMMIT");
+ return new CiConfigurationImpl(revision, getName());
+ }
+
+ private boolean environmentVariableIsTrue(String key) {
+ return Optional.ofNullable(system2.envVariable(key))
+ .map(Boolean::parseBoolean)
+ .orElse(false);
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Buildkite.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Buildkite.java
index c230293ec19..4f6105e1e19 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Buildkite.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Buildkite.java
@@ -26,7 +26,7 @@ import org.sonar.scanner.ci.CiVendor;
/**
* Support of https://buildkite.com
- *
+ * <p>
* Environment variables: https://buildkite.com/docs/pipelines/environment-variables
*/
public class Buildkite implements CiVendor {
@@ -50,6 +50,6 @@ public class Buildkite implements CiVendor {
@Override
public CiConfiguration loadConfiguration() {
String revision = system.envVariable("BUILDKITE_COMMIT");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CircleCi.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CircleCi.java
index c67807851ad..0070768b6f6 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CircleCi.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CircleCi.java
@@ -26,7 +26,7 @@ import org.sonar.scanner.ci.CiVendor;
/**
* Support of https://circleci.com
- *
+ * <p>
* Environment variables: https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables
*/
public class CircleCi implements CiVendor {
@@ -50,6 +50,6 @@ public class CircleCi implements CiVendor {
@Override
public CiConfiguration loadConfiguration() {
String revision = system.envVariable("CIRCLE_SHA1");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CirrusCi.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CirrusCi.java
index 1b252d0581c..e794a2eb102 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CirrusCi.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/CirrusCi.java
@@ -29,7 +29,7 @@ import static org.apache.commons.lang.StringUtils.isEmpty;
/**
* Support https://cirrus-ci.org/
- *
+ * <p>
* Environment variables are documented at https://cirrus-ci.org/guide/writing-tasks/#environment-variables
*/
public class CirrusCi implements CiVendor {
@@ -57,6 +57,6 @@ public class CirrusCi implements CiVendor {
if (isEmpty(revision)) {
Loggers.get(getClass()).warn("Missing environment variable " + PROPERTY_COMMIT);
}
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/DroneCi.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/DroneCi.java
index a4ccc6e31df..53b84bff6ab 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/DroneCi.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/DroneCi.java
@@ -26,7 +26,7 @@ import org.sonar.scanner.ci.CiVendor;
/**
* Support https://drone.io
- *
+ * <p>
* Environment variables are documented at https://docs.drone.io/reference/environ/
*/
public class DroneCi implements CiVendor {
@@ -49,6 +49,6 @@ public class DroneCi implements CiVendor {
@Override
public CiConfiguration loadConfiguration() {
String revision = system.envVariable("DRONE_COMMIT_SHA");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java
index de9d81460b5..e0c5940abaa 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GithubActions.java
@@ -30,7 +30,7 @@ import static org.apache.commons.lang.StringUtils.isEmpty;
/**
* Support of https://github.com/features/actions
- *
+ * <p>
* Environment variables: https://developer.github.com/actions/creating-github-actions/accessing-the-runtime-environment/#environment-variables
*/
public class GithubActions implements CiVendor {
@@ -59,6 +59,6 @@ public class GithubActions implements CiVendor {
if (isEmpty(revision)) {
Loggers.get(getClass()).warn("Missing environment variable " + PROPERTY_COMMIT);
}
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GitlabCi.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GitlabCi.java
index 68b860cd717..995af3afba8 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GitlabCi.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/GitlabCi.java
@@ -47,6 +47,6 @@ public class GitlabCi implements CiVendor {
@Override
public CiConfiguration loadConfiguration() {
String revision = system.envVariable("CI_COMMIT_SHA");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java
index db3d61727dd..2581809f79e 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java
@@ -62,7 +62,7 @@ public class Jenkins implements CiVendor {
// https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project
String revision = system.envVariable("ghprbActualCommit");
if (StringUtils.isNotBlank(revision)) {
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
revision = system.envVariable("GIT_COMMIT");
@@ -71,14 +71,14 @@ public class Jenkins implements CiVendor {
if (StringUtils.isNotBlank(system.envVariable("CHANGE_ID"))) {
String jenkinsGitPrSha1 = getJenkinsGitPrSha1();
if (StringUtils.isNotBlank(jenkinsGitPrSha1)) {
- return new CiConfigurationImpl(jenkinsGitPrSha1);
+ return new CiConfigurationImpl(jenkinsGitPrSha1, getName());
}
}
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
revision = system.envVariable("SVN_COMMIT");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
private String getJenkinsGitPrSha1() {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/SemaphoreCi.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/SemaphoreCi.java
index 94b178ec626..d9428997036 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/SemaphoreCi.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/SemaphoreCi.java
@@ -49,6 +49,6 @@ public class SemaphoreCi implements CiVendor {
@Override
public CiConfiguration loadConfiguration() {
String revision = system.envVariable("SEMAPHORE_GIT_SHA");
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/TravisCi.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/TravisCi.java
index 63027665b61..8b24d0d33b5 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/TravisCi.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/TravisCi.java
@@ -28,7 +28,7 @@ import static org.apache.commons.lang.StringUtils.isBlank;
/**
* Support of https://travis-ci.com
- *
+ * <p>
* Environment variables: https://docs.travis-ci.com/user/environment-variables/
*/
public class TravisCi implements CiVendor {
@@ -58,6 +58,6 @@ public class TravisCi implements CiVendor {
revision = system.envVariable("TRAVIS_PULL_REQUEST_SHA");
}
- return new CiConfigurationImpl(revision);
+ return new CiConfigurationImpl(revision, getName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java
index 0c8e49da4d7..525d3c6d8f8 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ContextPropertiesPublisher.java
@@ -20,46 +20,55 @@
package org.sonar.scanner.report;
import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
-import java.util.function.Function;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.annotation.Nonnull;
import org.sonar.api.batch.scm.ScmProvider;
import org.sonar.core.config.CorePropertyDefinitions;
+import org.sonar.scanner.ci.CiConfiguration;
import org.sonar.scanner.config.DefaultConfiguration;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
import org.sonar.scanner.repository.ContextPropertiesCache;
import org.sonar.scanner.scm.ScmConfiguration;
+import static org.sonar.core.config.CorePropertyDefinitions.SONAR_ANALYSIS_DETECTEDCI;
import static org.sonar.core.config.CorePropertyDefinitions.SONAR_ANALYSIS_DETECTEDSCM;
public class ContextPropertiesPublisher implements ReportPublisherStep {
private final ContextPropertiesCache cache;
private final DefaultConfiguration config;
private final ScmConfiguration scmConfiguration;
+ private final CiConfiguration ciConfiguration;
- public ContextPropertiesPublisher(ContextPropertiesCache cache, DefaultConfiguration config, ScmConfiguration scmConfiguration) {
+ public ContextPropertiesPublisher(ContextPropertiesCache cache, DefaultConfiguration config, ScmConfiguration scmConfiguration,
+ CiConfiguration ciConfiguration) {
this.cache = cache;
this.config = config;
this.scmConfiguration = scmConfiguration;
+ this.ciConfiguration = ciConfiguration;
}
@Override
public void publish(ScannerReportWriter writer) {
- MapEntryToContextPropertyFunction transformer = new MapEntryToContextPropertyFunction();
-
- // properties defined programmatically by plugins
- Stream<ScannerReport.ContextProperty> fromCache = Stream.concat(cache.getAll().entrySet().stream(), Stream.of(constructScmInfo())).map(transformer);
-
+ List<Map.Entry<String, String>> properties = new ArrayList<>(cache.getAll().entrySet());
+ properties.add(constructScmInfo());
+ properties.add(constructCiInfo());
// properties that are automatically included to report so that
// they can be included to webhook payloads
- Stream<ScannerReport.ContextProperty> fromSettings = config.getProperties().entrySet().stream()
+ properties.addAll(config.getProperties().entrySet()
+ .stream()
.filter(e -> e.getKey().startsWith(CorePropertyDefinitions.SONAR_ANALYSIS))
- .map(transformer);
+ .collect(Collectors.toList()));
- writer.writeContextProperties(Stream.concat(fromCache, fromSettings).collect(Collectors.toList()));
+ writer.writeContextProperties(properties
+ .stream()
+ .map(e -> ScannerReport.ContextProperty.newBuilder()
+ .setKey(e.getKey())
+ .setValue(e.getValue())
+ .build())
+ .collect(Collectors.toList()));
}
private Map.Entry<String, String> constructScmInfo() {
@@ -71,12 +80,7 @@ public class ContextPropertiesPublisher implements ReportPublisherStep {
}
}
- private static final class MapEntryToContextPropertyFunction implements Function<Map.Entry<String, String>, ScannerReport.ContextProperty> {
- private final ScannerReport.ContextProperty.Builder builder = ScannerReport.ContextProperty.newBuilder();
-
- @Override
- public ScannerReport.ContextProperty apply(@Nonnull Map.Entry<String, String> input) {
- return builder.clear().setKey(input.getKey()).setValue(input.getValue()).build();
- }
+ private Map.Entry<String, String> constructCiInfo() {
+ return new AbstractMap.SimpleEntry<>(SONAR_ANALYSIS_DETECTEDCI, ciConfiguration.getCiName());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
index 8ee1267d4d0..300d15568d9 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
@@ -46,8 +46,11 @@ import org.sonar.scanner.bootstrap.MetricProvider;
import org.sonar.scanner.bootstrap.PostJobExtensionDictionnary;
import org.sonar.scanner.ci.CiConfigurationProvider;
import org.sonar.scanner.ci.vendors.AppVeyor;
+import org.sonar.scanner.ci.vendors.AwsCodeBuild;
import org.sonar.scanner.ci.vendors.AzureDevops;
+import org.sonar.scanner.ci.vendors.Bamboo;
import org.sonar.scanner.ci.vendors.BitbucketPipelines;
+import org.sonar.scanner.ci.vendors.Bitrise;
import org.sonar.scanner.ci.vendors.Buildkite;
import org.sonar.scanner.ci.vendors.CircleCi;
import org.sonar.scanner.ci.vendors.CirrusCi;
@@ -286,8 +289,11 @@ public class ProjectScanContainer extends ComponentContainer {
// CI
new CiConfigurationProvider(),
AppVeyor.class,
+ AwsCodeBuild.class,
AzureDevops.class,
+ Bamboo.class,
BitbucketPipelines.class,
+ Bitrise.class,
Buildkite.class,
CircleCi.class,
CirrusCi.class,
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java
index 2dec5954336..4eb8a6e13a9 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationImplTest.java
@@ -27,9 +27,19 @@ public class CiConfigurationImplTest {
@Test
public void getScmRevision() {
- assertThat(new CiConfigurationImpl(null).getScmRevision()).isEmpty();
- assertThat(new CiConfigurationImpl("").getScmRevision()).isEmpty();
- assertThat(new CiConfigurationImpl(" ").getScmRevision()).isEmpty();
- assertThat(new CiConfigurationImpl("a7bdf2d").getScmRevision()).hasValue("a7bdf2d");
+ assertThat(new CiConfigurationImpl(null, "test").getScmRevision()).isEmpty();
+ assertThat(new CiConfigurationImpl("", "test").getScmRevision()).isEmpty();
+ assertThat(new CiConfigurationImpl(" ", "test").getScmRevision()).isEmpty();
+ assertThat(new CiConfigurationImpl("a7bdf2d", "test").getScmRevision()).hasValue("a7bdf2d");
+ }
+
+ @Test
+ public void getNam_for_undetected_ci() {
+ assertThat(new CiConfigurationProvider.EmptyCiConfiguration().getCiName()).isEqualTo("undetected");
+ }
+
+ @Test
+ public void getName_for_detected_ci() {
+ assertThat(new CiConfigurationImpl(null, "test").getCiName()).isEqualTo("test");
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java
index b99ff837499..e980d53de97 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/CiConfigurationProviderTest.java
@@ -28,8 +28,8 @@ import static org.assertj.core.api.Assertions.catchThrowable;
public class CiConfigurationProviderTest {
- private MapSettings cli = new MapSettings();
- private CiConfigurationProvider underTest = new CiConfigurationProvider();
+ private final MapSettings cli = new MapSettings();
+ private final CiConfigurationProvider underTest = new CiConfigurationProvider();
@Test
public void empty_configuration_if_no_ci_vendors() {
@@ -40,21 +40,21 @@ public class CiConfigurationProviderTest {
@Test
public void empty_configuration_if_no_ci_detected() {
- CiConfiguration ciConfiguration = underTest.provide(cli.asConfig(), new CiVendor[] {new DisabledCiVendor("vendor1"), new DisabledCiVendor("vendor2")});
+ CiConfiguration ciConfiguration = underTest.provide(cli.asConfig(), new CiVendor[]{new DisabledCiVendor("vendor1"), new DisabledCiVendor("vendor2")});
assertThat(ciConfiguration.getScmRevision()).isEmpty();
}
@Test
public void configuration_defined_by_ci_vendor() {
- CiConfiguration ciConfiguration = underTest.provide(cli.asConfig(), new CiVendor[] {new DisabledCiVendor("vendor1"), new EnabledCiVendor("vendor2")});
+ CiConfiguration ciConfiguration = underTest.provide(cli.asConfig(), new CiVendor[]{new DisabledCiVendor("vendor1"), new EnabledCiVendor("vendor2")});
assertThat(ciConfiguration.getScmRevision()).hasValue(EnabledCiVendor.SHA);
}
@Test
public void fail_if_multiple_ci_vendor_are_detected() {
- Throwable thrown = catchThrowable(() -> underTest.provide(cli.asConfig(), new CiVendor[] {new EnabledCiVendor("vendor1"), new EnabledCiVendor("vendor2")}));
+ Throwable thrown = catchThrowable(() -> underTest.provide(cli.asConfig(), new CiVendor[]{new EnabledCiVendor("vendor1"), new EnabledCiVendor("vendor2")}));
assertThat(thrown)
.isInstanceOf(MessageException.class)
@@ -64,7 +64,7 @@ public class CiConfigurationProviderTest {
@Test
public void empty_configuration_if_auto_configuration_is_disabled() {
cli.setProperty("sonar.ci.autoconfig.disabled", true);
- CiConfiguration ciConfiguration = underTest.provide(cli.asConfig(), new CiVendor[] {new EnabledCiVendor("vendor1")});
+ CiConfiguration ciConfiguration = underTest.provide(cli.asConfig(), new CiVendor[]{new EnabledCiVendor("vendor1")});
assertThat(ciConfiguration.getScmRevision()).isEmpty();
}
@@ -112,7 +112,7 @@ public class CiConfigurationProviderTest {
@Override
public CiConfiguration loadConfiguration() {
- return new CiConfigurationImpl(SHA);
+ return new CiConfigurationImpl(SHA, name);
}
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java
new file mode 100644
index 00000000000..f9094a34bd2
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/AwsCodeBuildTest.java
@@ -0,0 +1,64 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.ci.vendors;
+
+import javax.annotation.Nullable;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.scanner.ci.CiVendor;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AwsCodeBuildTest {
+
+ private final System2 system = mock(System2.class);
+ private final CiVendor underTest = new AwsCodeBuild(system);
+
+ @Test
+ public void getName() {
+ assertThat(underTest.getName()).isEqualTo("AwsCodeBuild");
+ }
+
+ @Test
+ public void isDetected() {
+ assertThat(underTest.isDetected()).isFalse();
+
+ setEnvVariable("CODEBUILD_BUILD_ID", "51");
+ assertThat(underTest.isDetected()).isFalse();
+
+ setEnvVariable("CODEBUILD_BUILD_ID", "52");
+ setEnvVariable("CODEBUILD_START_TIME", "some-time");
+ assertThat(underTest.isDetected()).isTrue();
+ }
+
+ @Test
+ public void loadConfiguration() {
+ setEnvVariable("CODEBUILD_BUILD_ID", "51");
+ setEnvVariable("CODEBUILD_START_TIME", "some-time");
+
+ assertThat(underTest.loadConfiguration().getScmRevision()).isEmpty();
+ }
+
+ private void setEnvVariable(String key, @Nullable String value) {
+ when(system.envVariable(key)).thenReturn(value);
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.java
new file mode 100644
index 00000000000..330b538d718
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BambooTest.java
@@ -0,0 +1,60 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.ci.vendors;
+
+import javax.annotation.Nullable;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.scanner.ci.CiVendor;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class BambooTest {
+
+ private final System2 system = mock(System2.class);
+ private final CiVendor underTest = new Bamboo(system);
+
+ @Test
+ public void getName() {
+ assertThat(underTest.getName()).isEqualTo("Bamboo");
+ }
+
+ @Test
+ public void isDetected() {
+ assertThat(underTest.isDetected()).isFalse();
+
+ setEnvVariable("bamboo_buildNumber", "41");
+ assertThat(underTest.isDetected()).isTrue();
+ }
+
+ @Test
+ public void loadConfiguration() {
+ setEnvVariable("bamboo_buildNumber", "41");
+ setEnvVariable("bamboo_planRepository_revision", "42109719-93c9-4d47-9d7c-b3b0b87b6985");
+
+ assertThat(underTest.loadConfiguration().getScmRevision()).hasValue("42109719-93c9-4d47-9d7c-b3b0b87b6985");
+ }
+
+ private void setEnvVariable(String key, @Nullable String value) {
+ when(system.envVariable(key)).thenReturn(value);
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java
new file mode 100644
index 00000000000..b80440866b6
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/BitriseTest.java
@@ -0,0 +1,70 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.ci.vendors;
+
+import javax.annotation.Nullable;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.scanner.ci.CiVendor;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class BitriseTest {
+
+ private final System2 system = mock(System2.class);
+ private final CiVendor underTest = new Bitrise(system);
+
+ @Test
+ public void getName() {
+ assertThat(underTest.getName()).isEqualTo("Bitrise");
+ }
+
+ @Test
+ public void isDetected() {
+
+ assertThat(underTest.isDetected()).isFalse();
+
+ setEnvVariable("CI", "true");
+ assertThat(underTest.isDetected()).isFalse();
+
+ setEnvVariable("CI", "true");
+ setEnvVariable("BITRISE_IO", "false");
+ assertThat(underTest.isDetected()).isFalse();
+
+ setEnvVariable("CI", "true");
+ setEnvVariable("BITRISE_IO", "true");
+ assertThat(underTest.isDetected()).isTrue();
+ }
+
+ @Test
+ public void loadConfiguration() {
+ setEnvVariable("CI", "true");
+ setEnvVariable("BITRISE_IO", "true");
+ setEnvVariable("BITRISE_GIT_COMMIT", "abd12fc");
+
+ assertThat(underTest.loadConfiguration().getScmRevision()).hasValue("abd12fc");
+ }
+
+ private void setEnvVariable(String key, @Nullable String value) {
+ when(system.envVariable(key)).thenReturn(value);
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java
index db450a00657..0dd340f5b3f 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ContextPropertiesPublisherTest.java
@@ -25,9 +25,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
+import org.sonar.scanner.ci.CiConfiguration;
import org.sonar.scanner.config.DefaultConfiguration;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
@@ -40,19 +39,18 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ContextPropertiesPublisherTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
private final ScannerReportWriter writer = mock(ScannerReportWriter.class);
private final ContextPropertiesCache cache = new ContextPropertiesCache();
private final DefaultConfiguration config = mock(DefaultConfiguration.class);
private final Map<String, String> props = new HashMap<>();
private final ScmConfiguration scmConfiguration = mock(ScmConfiguration.class);
- private final ContextPropertiesPublisher underTest = new ContextPropertiesPublisher(cache, config, scmConfiguration);
+ private final CiConfiguration ciConfiguration = mock(CiConfiguration.class);
+ private final ContextPropertiesPublisher underTest = new ContextPropertiesPublisher(cache, config, scmConfiguration, ciConfiguration);
@Before
public void prepareMock() {
when(config.getProperties()).thenReturn(props);
+ when(ciConfiguration.getCiName()).thenReturn("undetected");
}
@Test
@@ -65,7 +63,8 @@ public class ContextPropertiesPublisherTest {
List<ScannerReport.ContextProperty> expected = Arrays.asList(
newContextProperty("foo1", "bar1"),
newContextProperty("foo2", "bar2"),
- newContextProperty("sonar.analysis.detectedscm", "undetected"));
+ newContextProperty("sonar.analysis.detectedscm", "undetected"),
+ newContextProperty("sonar.analysis.detectedci", "undetected"));
expectWritten(expected);
}
@@ -80,7 +79,8 @@ public class ContextPropertiesPublisherTest {
List<ScannerReport.ContextProperty> expected = Arrays.asList(
newContextProperty("sonar.analysis.revision", "ab45b3"),
newContextProperty("sonar.analysis.build.number", "B123"),
- newContextProperty("sonar.analysis.detectedscm", "undetected"));
+ newContextProperty("sonar.analysis.detectedscm", "undetected"),
+ newContextProperty("sonar.analysis.detectedci", "undetected"));
expectWritten(expected);
}