diff options
10 files changed, 199 insertions, 6 deletions
diff --git a/build.gradle b/build.gradle index d82d69dd38b..b1ae15cdf06 100644 --- a/build.gradle +++ b/build.gradle @@ -329,15 +329,15 @@ subprojects { dependency 'org.sonarsource.javascript:sonar-javascript-plugin:10.25.0.33900' dependency 'org.sonarsource.php:sonar-php-plugin:3.48.0.13483' dependency 'org.sonarsource.plugins.cayc:sonar-cayc-plugin:2.4.0.2018' - dependency 'org.sonarsource.python:sonar-python-plugin:5.7.0.24163' + dependency 'org.sonarsource.python:sonar-python-plugin:5.8.0.24785' dependency 'org.sonarsource.rust:sonar-rust-plugin:1.0.3.786' - dependency 'com.sonarsource.python:sonar-python-enterprise-plugin:5.7.0.24163' + dependency 'com.sonarsource.python:sonar-python-enterprise-plugin:5.8.0.24785' dependency 'org.sonarsource.kotlin:sonar-kotlin-plugin:3.3.0.7402' dependency "org.sonarsource.api.plugin:sonar-plugin-api:$pluginApiVersion" dependency "org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures:$pluginApiVersion" dependency 'org.sonarsource.xml:sonar-xml-plugin:2.13.0.5938' - dependency 'org.sonarsource.iac:sonar-iac-plugin:1.48.0.15768' - dependency 'com.sonarsource.iac:sonar-iac-enterprise-plugin:1.48.0.15768' + dependency 'org.sonarsource.iac:sonar-iac-plugin:1.49.0.16030' + dependency 'com.sonarsource.iac:sonar-iac-enterprise-plugin:1.49.0.16030' dependency 'org.sonarsource.text:sonar-text-plugin:2.27.0.7705' dependency 'com.sonarsource.text:sonar-text-developer-plugin:2.27.0.7705' dependency 'com.sonarsource.text:sonar-text-enterprise-plugin:2.27.0.7705' diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202505/AddPublishedOnToScaVulnerabilityIssuesTest.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202505/AddPublishedOnToScaVulnerabilityIssuesTest.java index 562d12ee3c6..980dad49bea 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202505/AddPublishedOnToScaVulnerabilityIssuesTest.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202505/AddPublishedOnToScaVulnerabilityIssuesTest.java @@ -40,7 +40,7 @@ class AddPublishedOnToScaVulnerabilityIssuesTest { void execute_shouldAddColumn() throws SQLException { db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BIGINT, 64, true); + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BIGINT, null, true); } @Test @@ -48,6 +48,6 @@ class AddPublishedOnToScaVulnerabilityIssuesTest { db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BIGINT, 64, true); + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BIGINT, null, true); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202505/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202505/package-info.java new file mode 100644 index 00000000000..d54fbd7b504 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202505/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.server.platform.db.migration.version.v202505; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java index 0afe402240e..2fc281a3807 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java @@ -98,6 +98,9 @@ public class ComponentAction implements MeasuresWsAction { .setResponseExample(getClass().getResource("component-example.json")) .setSince("5.4") .setChangelog( + new Change("2025.4", format( + "The following SCA metrics are available on licensed enterprise/datacenter editions with SCA enabled: %s", + MeasuresWsModule.getNewScaMetricsInSonarQube202504())), new Change("2025.2", "The 'Execute Analysis' permission also allows to access the endpoint"), new Change("10.8", format("The following metrics are not deprecated anymore: %s", MeasuresWsModule.getUndeprecatedMetricsinSonarQube108())), diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java index 6e7e8fa2039..d7ecd83abbd 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java @@ -183,6 +183,9 @@ public class ComponentTreeAction implements MeasuresWsAction { .setHandler(this) .addPagingParams(100, MAX_SIZE) .setChangelog( + new Change("2025.4", format( + "The following SCA metrics are available on licensed enterprise/datacenter editions with SCA enabled: %s", + MeasuresWsModule.getNewScaMetricsInSonarQube202504())), new Change("10.8", format(NUMBER_OF_KEYS_LIMITED, 75)), new Change("10.8", "Portfolio project metrics now also include: 'contains_ai_code', 'reliability_rating_without_aica', " + "'reliability_rating_with_aica', 'software_quality_security_rating_without_aica', 'software_quality_security_rating_with_aica', " + diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java index b74cebf2f4c..fad22e62b68 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java @@ -22,6 +22,7 @@ package org.sonar.server.measure.ws; import java.util.stream.Collectors; import java.util.stream.Stream; import org.sonar.api.measures.CoreMetrics; +import org.sonar.core.metric.ScaMetrics; import org.sonar.core.metric.SoftwareQualitiesMetrics; import org.sonar.core.platform.Module; import org.sonar.server.telemetry.TelemetryPortfolioActivityGraphTypeProvider; @@ -119,4 +120,24 @@ public class MeasuresWsModule extends Module { public static String getUndeprecatedMetricsinSonarQube108() { return getDeprecatedMetricsInSonarQube104() + ", " + getDeprecatedMetricsInSonarQube105(); } + + public static String getNewScaMetricsInSonarQube202504() { + return Stream.of( + ScaMetrics.SCA_RATING_LICENSING_KEY, + ScaMetrics.SCA_RATING_VULNERABILITY_KEY, + ScaMetrics.SCA_RATING_ANY_ISSUE_KEY, + ScaMetrics.SCA_SEVERITY_LICENSING_KEY, + ScaMetrics.SCA_SEVERITY_VULNERABILITY_KEY, + ScaMetrics.SCA_SEVERITY_ANY_ISSUE_KEY, + ScaMetrics.SCA_COUNT_ANY_ISSUE_KEY, + ScaMetrics.NEW_SCA_RATING_LICENSING_KEY, + ScaMetrics.NEW_SCA_RATING_VULNERABILITY_KEY, + ScaMetrics.NEW_SCA_RATING_ANY_ISSUE_KEY, + ScaMetrics.NEW_SCA_SEVERITY_LICENSING_KEY, + ScaMetrics.NEW_SCA_SEVERITY_VULNERABILITY_KEY, + ScaMetrics.NEW_SCA_SEVERITY_ANY_ISSUE_KEY, + ScaMetrics.NEW_SCA_COUNT_ANY_ISSUE_KEY) + .map(e -> "'" + e + "'") + .collect(Collectors.joining(", ")); + } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java index 067b0f5ca39..92c69628fa4 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java @@ -87,6 +87,9 @@ public class SearchAction implements MeasuresWsAction { .setResponseExample(getClass().getResource("search-example.json")) .setHandler(this) .setChangelog( + new Change("2025.4", format( + "The following SCA metrics are available on licensed enterprise/datacenter editions with SCA enabled: %s", + MeasuresWsModule.getNewScaMetricsInSonarQube202504())), new Change("10.8", format("The following metrics are not deprecated anymore: %s", MeasuresWsModule.getUndeprecatedMetricsinSonarQube108())), new Change("10.8", String.format("Added new accepted values for the 'metricKeys' param: %s", MeasuresWsModule.getNewMetricsInSonarQube108())), diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java index bec33db5fd8..add8892067d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java @@ -109,6 +109,9 @@ public class SearchHistoryAction implements MeasuresWsAction { .setResponseExample(getClass().getResource("search_history-example.json")) .setSince("6.3") .setChangelog( + new Change("2025.4", format( + "The following SCA metrics are available on licensed enterprise/datacenter editions with SCA enabled: %s", + MeasuresWsModule.getNewScaMetricsInSonarQube202504())), new Change("10.8", String.format("The following metrics are not deprecated anymore: %s", MeasuresWsModule.getUndeprecatedMetricsinSonarQube108())), new Change("10.8", String.format("Added new accepted values for the 'metricKeys' param: %s", diff --git a/sonar-core/src/main/java/org/sonar/core/metric/ScaMetrics.java b/sonar-core/src/main/java/org/sonar/core/metric/ScaMetrics.java new file mode 100644 index 00000000000..92c73b53a51 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/metric/ScaMetrics.java @@ -0,0 +1,80 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.core.metric; + +import java.util.Map; +import java.util.Set; + +/** + * Normally SCA metrics are only available when using Enterprise Edition or up + * and when the appropriate license has been purchased. + * However, we need to list these metrics out in the Measures API documentation, + * so we have them defined in this core module and use them throughout the + * non-SCA-specific areas of SonarQube. + */ +public class ScaMetrics { + /** + * These string values of SCA severity metric threshold values are 1 less numerically than + * what's returned in measures, in order to support greater-than-or-equal comparisons. + */ + public static final Map<String, String> SCA_SEVERITY_SETTING_VALUE_TO_TEXT = Map.of( + "4", "info", + "9", "low", + "14", "medium", + "19", "high", + "24", "blocker"); + + // These must be kept in sync with SCA metrics! + // There's currently no way to do this in an automated fashion. + private static final String SCA_SEVERITY_PREFIX = "sca_severity"; + private static final String SCA_COUNT_PREFIX = "sca_count"; + private static final String SCA_RATING_PREFIX = "sca_rating"; + private static final String SCA_ISSUE_TYPE_ANY_ISSUE = "any_issue"; + private static final String SCA_ISSUE_TYPE_VULNERABILITY = "vulnerability"; + private static final String SCA_ISSUE_TYPE_LICENSING = "licensing"; + private static final String BASE_KEY_FORMAT = "%s_%s"; + private static final String NEW_KEY_FORMAT = "new_" + BASE_KEY_FORMAT; + public static final String NEW_SCA_RATING_LICENSING_KEY = String.format(NEW_KEY_FORMAT, SCA_RATING_PREFIX, SCA_ISSUE_TYPE_LICENSING); + public static final String NEW_SCA_RATING_VULNERABILITY_KEY = String.format(NEW_KEY_FORMAT, SCA_RATING_PREFIX, SCA_ISSUE_TYPE_VULNERABILITY); + public static final String NEW_SCA_RATING_ANY_ISSUE_KEY = String.format(NEW_KEY_FORMAT, SCA_RATING_PREFIX, SCA_ISSUE_TYPE_ANY_ISSUE); + public static final String NEW_SCA_SEVERITY_LICENSING_KEY = String.format(NEW_KEY_FORMAT, SCA_SEVERITY_PREFIX, SCA_ISSUE_TYPE_LICENSING); + public static final String NEW_SCA_SEVERITY_VULNERABILITY_KEY = String.format(NEW_KEY_FORMAT, SCA_SEVERITY_PREFIX, SCA_ISSUE_TYPE_VULNERABILITY); + public static final String NEW_SCA_SEVERITY_ANY_ISSUE_KEY = String.format(NEW_KEY_FORMAT, SCA_SEVERITY_PREFIX, SCA_ISSUE_TYPE_ANY_ISSUE); + public static final String NEW_SCA_COUNT_ANY_ISSUE_KEY = String.format(NEW_KEY_FORMAT, SCA_COUNT_PREFIX, SCA_ISSUE_TYPE_ANY_ISSUE); + public static final String SCA_RATING_LICENSING_KEY = String.format(BASE_KEY_FORMAT, SCA_RATING_PREFIX, SCA_ISSUE_TYPE_LICENSING); + public static final String SCA_RATING_VULNERABILITY_KEY = String.format(BASE_KEY_FORMAT, SCA_RATING_PREFIX, SCA_ISSUE_TYPE_VULNERABILITY); + public static final String SCA_RATING_ANY_ISSUE_KEY = String.format(BASE_KEY_FORMAT, SCA_RATING_PREFIX, SCA_ISSUE_TYPE_ANY_ISSUE); + public static final String SCA_SEVERITY_LICENSING_KEY = String.format(BASE_KEY_FORMAT, SCA_SEVERITY_PREFIX, SCA_ISSUE_TYPE_LICENSING); + public static final String SCA_SEVERITY_VULNERABILITY_KEY = String.format(BASE_KEY_FORMAT, SCA_SEVERITY_PREFIX, SCA_ISSUE_TYPE_VULNERABILITY); + public static final String SCA_SEVERITY_ANY_ISSUE_KEY = String.format(BASE_KEY_FORMAT, SCA_SEVERITY_PREFIX, SCA_ISSUE_TYPE_ANY_ISSUE); + public static final String SCA_COUNT_ANY_ISSUE_KEY = String.format(BASE_KEY_FORMAT, SCA_COUNT_PREFIX, SCA_ISSUE_TYPE_ANY_ISSUE); + public static final Set<String> NEW_SCA_METRICS_KEYS = Set.of( + NEW_SCA_COUNT_ANY_ISSUE_KEY, + NEW_SCA_SEVERITY_ANY_ISSUE_KEY, + NEW_SCA_SEVERITY_VULNERABILITY_KEY, + NEW_SCA_SEVERITY_LICENSING_KEY, + NEW_SCA_RATING_ANY_ISSUE_KEY, + NEW_SCA_RATING_VULNERABILITY_KEY, + NEW_SCA_RATING_LICENSING_KEY); + + private ScaMetrics() { + // constants only + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/metric/ScaMetricsTest.java b/sonar-core/src/test/java/org/sonar/core/metric/ScaMetricsTest.java new file mode 100644 index 00000000000..219c01f50e3 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/metric/ScaMetricsTest.java @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.core.metric; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ScaMetricsTest { + @Test + void newScaMetricsKeys_thenContainsExpectedKeys() { + assertThat(ScaMetrics.NEW_SCA_METRICS_KEYS).containsExactlyInAnyOrder( + ScaMetrics.NEW_SCA_COUNT_ANY_ISSUE_KEY, + ScaMetrics.NEW_SCA_SEVERITY_ANY_ISSUE_KEY, + ScaMetrics.NEW_SCA_SEVERITY_VULNERABILITY_KEY, + ScaMetrics.NEW_SCA_SEVERITY_LICENSING_KEY, + ScaMetrics.NEW_SCA_RATING_ANY_ISSUE_KEY, + ScaMetrics.NEW_SCA_RATING_VULNERABILITY_KEY, + ScaMetrics.NEW_SCA_RATING_LICENSING_KEY); + } + + @Test + void scaMetricKeys_thenHaveCorrectFormat() { + assertThat(ScaMetrics.NEW_SCA_RATING_LICENSING_KEY).isEqualTo("new_sca_rating_licensing"); + assertThat(ScaMetrics.NEW_SCA_RATING_VULNERABILITY_KEY).isEqualTo("new_sca_rating_vulnerability"); + assertThat(ScaMetrics.NEW_SCA_RATING_ANY_ISSUE_KEY).isEqualTo("new_sca_rating_any_issue"); + assertThat(ScaMetrics.NEW_SCA_SEVERITY_LICENSING_KEY).isEqualTo("new_sca_severity_licensing"); + assertThat(ScaMetrics.NEW_SCA_SEVERITY_VULNERABILITY_KEY).isEqualTo("new_sca_severity_vulnerability"); + assertThat(ScaMetrics.NEW_SCA_SEVERITY_ANY_ISSUE_KEY).isEqualTo("new_sca_severity_any_issue"); + assertThat(ScaMetrics.NEW_SCA_COUNT_ANY_ISSUE_KEY).isEqualTo("new_sca_count_any_issue"); + assertThat(ScaMetrics.SCA_RATING_LICENSING_KEY).isEqualTo("sca_rating_licensing"); + assertThat(ScaMetrics.SCA_RATING_VULNERABILITY_KEY).isEqualTo("sca_rating_vulnerability"); + assertThat(ScaMetrics.SCA_RATING_ANY_ISSUE_KEY).isEqualTo("sca_rating_any_issue"); + assertThat(ScaMetrics.SCA_SEVERITY_LICENSING_KEY).isEqualTo("sca_severity_licensing"); + assertThat(ScaMetrics.SCA_SEVERITY_VULNERABILITY_KEY).isEqualTo("sca_severity_vulnerability"); + assertThat(ScaMetrics.SCA_SEVERITY_ANY_ISSUE_KEY).isEqualTo("sca_severity_any_issue"); + assertThat(ScaMetrics.SCA_COUNT_ANY_ISSUE_KEY).isEqualTo("sca_count_any_issue"); + } +} |