From: David Cho-Lerat Date: Mon, 3 Jul 2023 08:49:09 +0000 (+0200) Subject: SONAR-19650 Update code snippets to add vulnerability report stage to GitLab CI X-Git-Tag: 10.2.0.77647~460 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=dc8e73d5702a1c212c8d211f394a95fd481813d6;p=sonarqube.git SONAR-19650 Update code snippets to add vulnerability report stage to GitLab CI --- diff --git a/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx b/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx index 3de6a3ae682..fdb72ea1554 100644 --- a/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx @@ -255,7 +255,6 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender baseUrl={baseUrl} component={component} currentUser={currentUser} - mainBranchName={mainBranchName} willRefreshAutomatically={willRefreshAutomatically} /> )} diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/GitLabCITutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/GitLabCITutorial.tsx index ce390a784d7..86a8b46dc38 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/GitLabCITutorial.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/GitLabCITutorial.tsx @@ -36,12 +36,11 @@ export interface GitLabCITutorialProps { baseUrl: string; component: Component; currentUser: LoggedInUser; - mainBranchName: string; willRefreshAutomatically?: boolean; } export default function GitLabCITutorial(props: GitLabCITutorialProps) { - const { baseUrl, component, currentUser, willRefreshAutomatically, mainBranchName } = props; + const { baseUrl, component, currentUser, willRefreshAutomatically } = props; const [step, setStep] = React.useState(Steps.ENV_VARIABLES); @@ -64,7 +63,6 @@ export default function GitLabCITutorial(props: GitLabCITutorialProps) { Steps.YML} component={component} - mainBranchName={mainBranchName} onDone={() => setStep(Steps.ALL_SET)} onOpen={() => setStep(Steps.YML)} open={step === Steps.YML} diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx index 1b727795d95..e5eb3526f37 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx @@ -17,6 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +import { FlagMessage } from 'design-system'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import withAvailableFeatures, { @@ -25,7 +27,6 @@ import withAvailableFeatures, { import { ClipboardIconButton } from '../../../components/controls/clipboard'; import { GRADLE_SCANNER_VERSION } from '../../../helpers/constants'; import { translate } from '../../../helpers/l10n'; -import { Feature } from '../../../types/features'; import { Component } from '../../../types/types'; import CodeSnippet from '../../common/CodeSnippet'; import { withCLanguageFeature } from '../../hoc/withCLanguageFeature'; @@ -38,16 +39,17 @@ import { BuildTools, GradleBuildDSL, TutorialModes } from '../types'; import PipeCommand from './commands/PipeCommand'; export interface YmlFileStepProps extends WithAvailableFeaturesProps { - finished: boolean; component: Component; + finished: boolean; hasCLanguageFeature: boolean; onDone: () => void; onOpen: () => void; open: boolean; - mainBranchName: string; } -const mavenSnippet = () => ` +const mavenSnippet = (key: string, name: string) => ` + ${key} + ${name} true `; @@ -84,29 +86,30 @@ sonar.qualitygate.wait=true `; const snippetForBuildTool = { - [BuildTools.Maven]: mavenSnippet, - [BuildTools.Gradle]: gradleSnippet, [BuildTools.CFamily]: otherSnippet, + [BuildTools.Gradle]: gradleSnippet, + [BuildTools.Maven]: mavenSnippet, [BuildTools.Other]: otherSnippet, }; const filenameForBuildTool = { - [BuildTools.Maven]: 'pom.xml', - [BuildTools.Gradle]: GradleBuildDSL.Groovy, [BuildTools.CFamily]: 'sonar-project.properties', + [BuildTools.Gradle]: GradleBuildDSL.Groovy, + [BuildTools.Maven]: 'pom.xml', [BuildTools.Other]: 'sonar-project.properties', }; export function YmlFileStep(props: YmlFileStepProps) { - const { open, finished, mainBranchName, hasCLanguageFeature, component } = props; - const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); + const { component, hasCLanguageFeature, finished, open } = props; const [buildTool, setBuildTool] = React.useState(); const buildTools = [BuildTools.Maven, BuildTools.Gradle, BuildTools.DotNet]; + if (hasCLanguageFeature) { buildTools.push(BuildTools.CFamily); } + buildTools.push(BuildTools.Other); const renderForm = () => ( @@ -114,103 +117,122 @@ export function YmlFileStep(props: YmlFileStepProps) {
  1. {translate('onboarding.build')} + void} optionLabelKey="onboarding.build" options={buildTools} /> + {buildTool === BuildTools.CFamily && ( )}
  2. - {buildTool !== undefined && buildTool !== BuildTools.DotNet && ( -
  3. - + + {filenameForBuildTool[buildTool]} + + + + ), + }, + buildTool === BuildTools.Gradle + ? { + file2: ( + <> + {GradleBuildDSL.Kotlin} + + + + ), + } + : {} + )} + /> + + {buildTool === BuildTools.Gradle ? ( + + {(build) => ( + + )} + + ) : ( + )} - id={`onboarding.tutorial.with.gitlab_ci.project_key.${buildTool}.step2`} - values={Object.assign( - { - file: ( - <> - {filenameForBuildTool[buildTool]} - - - ), - }, - buildTool === BuildTools.Gradle - ? { - file2: ( +
  4. + )} + + {buildTool && ( +
  5. + {buildTool !== BuildTools.CFamily && ( + <> +
    + - {GradleBuildDSL.Kotlin} + + {translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')} + + ), - } - : {} - )} - /> - {buildTool === BuildTools.Gradle ? ( - - {(build) => ( - - )} - - ) : ( - +
    + +
    + +
    + + + {translate('onboarding.tutorial.with.gitlab_ci.yaml.premium')} + + +

    + {translate('onboarding.tutorial.with.gitlab_ci.yaml.baseconfig')} +

    + +

    {translate('onboarding.tutorial.with.gitlab_ci.yaml.existing')}

    + )} -
  6. - )} - {buildTool && ( -
  7. -
    - - - {translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')} - - - - ), - }} - /> -
    -
    - -
    -

    - {branchSupportEnabled - ? translate('onboarding.tutorial.with.gitlab_ci.yaml.baseconfig') - : translate('onboarding.tutorial.with.gitlab_ci.yaml.baseconfig.no_branches')} -

    -

    {translate('onboarding.tutorial.with.gitlab_ci.yaml.existing')}

  8. )} diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-it.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-it.tsx index 7d76c65e381..48caa3e9c53 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-it.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-it.tsx @@ -24,7 +24,7 @@ import selectEvent from 'react-select-event'; import UserTokensMock from '../../../../api/mocks/UserTokensMock'; import { mockComponent } from '../../../../helpers/mocks/component'; import { mockLanguage, mockLoggedInUser } from '../../../../helpers/testMocks'; -import { renderApp, RenderContext } from '../../../../helpers/testReactTestingUtils'; +import { RenderContext, renderApp } from '../../../../helpers/testReactTestingUtils'; import { getCommonNodes, getCopyToClipboardValue, @@ -81,11 +81,6 @@ it('should follow and complete all steps', async () => { await user.click(ui.dotnetBuildButton.get()); expect(getCopyToClipboardValue(1)).toMatchSnapshot('.NET: gitlab-ci.yml'); - // CFamily - await user.click(ui.cFamilyBuildButton.get()); - expect(getCopyToClipboardValue(1)).toMatchSnapshot('CFamily: sonar-project.properties'); - expect(getCopyToClipboardValue(3)).toMatchSnapshot('CFamily: gitlab-ci.yml'); - // Other await user.click(ui.otherBuildButton.get()); expect(getCopyToClipboardValue(1)).toMatchSnapshot('Other: sonar-project.properties'); @@ -139,7 +134,6 @@ function renderGitLabTutorial( '/', - -cache: - paths: - - .sonar - -stages: - - download - - build - - scan - -download: - stage: download + only: + - merge_requests + - master + - main + - develop + +vulnerability-report: + stage: vulnerability-report script: - - mkdir -p .sonar - - curl -sSLo build-wrapper-linux-x86.zip $SONAR_HOST_URL/static/cpp/build-wrapper-linux-x86.zip - - unzip -o build-wrapper-linux-x86.zip -d .sonar - -build: - stage: build - script: - - .sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir .sonar/bw-output - -sonarqube-check: - stage: scan - script: - - curl -sSLo sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip - - unzip -o sonar-scanner.zip -d .sonar - - .sonar/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=.sonar/bw-output - allow_failure: true" -`; - -exports[`should follow and complete all steps: CFamily: sonar-project.properties 1`] = ` -"sonar.projectKey=my-project -sonar.qualitygate.wait=true + - 'curl -u "\${SONAR_TOKEN}:" "\${SONAR_HOST_URL}/api/issues/gitlab_sast_export?projectKey=my-project&branch=\${CI_COMMIT_BRANCH}&pullRequest=\${CI_MERGE_REQUEST_IID}" -o gl-sast-sonar-report.json' + allow_failure: true + only: + - merge_requests + - master + - main + - develop + artifacts: + expire_in: 1 day + reports: + sast: gl-sast-sonar-report.json + dependencies: + - sonarqube-check " `; exports[`should follow and complete all steps: Gradle: gitlab-ci.yml 1`] = ` -"sonarqube-check: +"stages: + - sonarqube-check + - vulnerability-report + +sonarqube-check: + stage: sonarqube-check image: gradle:jre11-slim variables: SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache @@ -75,8 +66,28 @@ exports[`should follow and complete all steps: Gradle: gitlab-ci.yml 1`] = ` - .sonar/cache script: gradle sonar allow_failure: true - rules: - - if: $CI_COMMIT_BRANCH == 'main' + only: + - merge_requests + - master + - main + - develop + +vulnerability-report: + stage: vulnerability-report + script: + - 'curl -u "\${SONAR_TOKEN}:" "\${SONAR_HOST_URL}/api/issues/gitlab_sast_export?projectKey=my-project&branch=\${CI_COMMIT_BRANCH}&pullRequest=\${CI_MERGE_REQUEST_IID}" -o gl-sast-sonar-report.json' + allow_failure: true + only: + - merge_requests + - master + - main + - develop + artifacts: + expire_in: 1 day + reports: + sast: gl-sast-sonar-report.json + dependencies: + - sonarqube-check " `; @@ -109,7 +120,12 @@ sonar { `; exports[`should follow and complete all steps: Maven: gitlab-ci.yml 1`] = ` -"sonarqube-check: +"stages: + - sonarqube-check + - vulnerability-report + +sonarqube-check: + stage: sonarqube-check image: maven:3.6.3-jdk-11 variables: SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache @@ -119,21 +135,48 @@ exports[`should follow and complete all steps: Maven: gitlab-ci.yml 1`] = ` paths: - .sonar/cache script: - - mvn verify sonar:sonar -Dsonar.projectKey=my-project -Dsonar.projectName='MyProject' + - mvn verify sonar:sonar + allow_failure: true + only: + - merge_requests + - master + - main + - develop + +vulnerability-report: + stage: vulnerability-report + script: + - 'curl -u "\${SONAR_TOKEN}:" "\${SONAR_HOST_URL}/api/issues/gitlab_sast_export?projectKey=my-project&branch=\${CI_COMMIT_BRANCH}&pullRequest=\${CI_MERGE_REQUEST_IID}" -o gl-sast-sonar-report.json' allow_failure: true - rules: - - if: $CI_COMMIT_BRANCH == 'main' + only: + - merge_requests + - master + - main + - develop + artifacts: + expire_in: 1 day + reports: + sast: gl-sast-sonar-report.json + dependencies: + - sonarqube-check " `; exports[`should follow and complete all steps: Maven: pom.xml 1`] = ` " + my-project + MyProject true " `; exports[`should follow and complete all steps: Other: gitlab-ci.yml 1`] = ` -"sonarqube-check: +"stages: + - sonarqube-check + - vulnerability-report + +sonarqube-check: + stage: sonarqube-check image: name: sonarsource/sonar-scanner-cli:latest entrypoint: [""] @@ -147,8 +190,28 @@ exports[`should follow and complete all steps: Other: gitlab-ci.yml 1`] = ` script: - sonar-scanner allow_failure: true - rules: - - if: $CI_COMMIT_BRANCH == 'main' + only: + - merge_requests + - master + - main + - develop + +vulnerability-report: + stage: vulnerability-report + script: + - 'curl -u "\${SONAR_TOKEN}:" "\${SONAR_HOST_URL}/api/issues/gitlab_sast_export?projectKey=my-project&branch=\${CI_COMMIT_BRANCH}&pullRequest=\${CI_MERGE_REQUEST_IID}" -o gl-sast-sonar-report.json' + allow_failure: true + only: + - merge_requests + - master + - main + - develop + artifacts: + expire_in: 1 day + reports: + sast: gl-sast-sonar-report.json + dependencies: + - sonarqube-check " `; diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx index 323b6ad67cc..20b0c25132b 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx @@ -17,25 +17,25 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import * as React from 'react'; import CodeSnippet from '../../../common/CodeSnippet'; -import { CompilationInfo } from '../../components/CompilationInfo'; import { BuildTools } from '../../types'; export interface PipeCommandProps { - branchesEnabled?: boolean; - buildTool: BuildTools; - mainBranchName: string; + buildTool: Exclude; projectKey: string; - projectName: string; } const BUILD_TOOL_SPECIFIC = { - [BuildTools.Gradle]: { image: 'gradle:jre11-slim', script: () => 'gradle sonar' }, + [BuildTools.Gradle]: { + image: 'gradle:jre11-slim', + script: () => 'gradle sonar', + }, [BuildTools.Maven]: { image: 'maven:3.6.3-jdk-11', - script: (projectKey: string, projectName: string) => ` - - mvn verify sonar:sonar -Dsonar.projectKey=${projectKey} -Dsonar.projectName='${projectName}'`, + script: () => ` + - mvn verify sonar:sonar`, }, [BuildTools.DotNet]: { image: 'mcr.microsoft.com/dotnet/core/sdk:latest', @@ -58,49 +58,16 @@ const BUILD_TOOL_SPECIFIC = { }; export default function PipeCommand(props: PipeCommandProps) { - const { projectKey, branchesEnabled, buildTool, mainBranchName, projectName } = props; - let command: string; - if (buildTool === BuildTools.CFamily) { - command = `image: - -cache: - paths: - - .sonar + const { projectKey, buildTool } = props; -stages: - - download - - build - - scan + const { image, script } = BUILD_TOOL_SPECIFIC[buildTool]; -download: - stage: download - script: - - mkdir -p .sonar - - curl -sSLo build-wrapper-linux-x86.zip $SONAR_HOST_URL/static/cpp/build-wrapper-linux-x86.zip - - unzip -o build-wrapper-linux-x86.zip -d .sonar - -build: - stage: build - script: - - .sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir .sonar/bw-output + const command = `stages: + - sonarqube-check + - vulnerability-report sonarqube-check: - stage: scan - script: - - curl -sSLo sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip - - unzip -o sonar-scanner.zip -d .sonar - - .sonar/sonar-scanner-4.6.2.2472-linux/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=.sonar/bw-output - allow_failure: true`; - } else { - const onlyBlock = branchesEnabled - ? `- if: $CI_PIPELINE_SOURCE == 'merge_request_event' - - if: $CI_COMMIT_BRANCH == '${mainBranchName}' - - if: $CI_COMMIT_BRANCH == 'develop'` - : `- if: $CI_COMMIT_BRANCH == '${mainBranchName}'`; - - const { image, script } = BUILD_TOOL_SPECIFIC[buildTool]; - - command = `sonarqube-check: + stage: sonarqube-check image: ${image} variables: SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache @@ -109,16 +76,31 @@ sonarqube-check: key: "\${CI_JOB_NAME}" paths: - .sonar/cache - script: ${script(projectKey, projectName)} + script: ${script(projectKey)} + allow_failure: true + only: + - merge_requests + - master + - main + - develop + +vulnerability-report: + stage: vulnerability-report + script: + - 'curl -u "\${SONAR_TOKEN}:" "\${SONAR_HOST_URL}/api/issues/gitlab_sast_export?projectKey=${projectKey}&branch=\${CI_COMMIT_BRANCH}&pullRequest=\${CI_MERGE_REQUEST_IID}" -o gl-sast-sonar-report.json' allow_failure: true - rules: - ${onlyBlock} + only: + - merge_requests + - master + - main + - develop + artifacts: + expire_in: 1 day + reports: + sast: gl-sast-sonar-report.json + dependencies: + - sonarqube-check `; - } - return ( - <> - - {buildTool === BuildTools.CFamily && } - - ); + + return ; } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 8d5125ef3a2..8d3b3e495c2 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -4128,9 +4128,9 @@ onboarding.tutorial.with.gitlab_ci.variables.section2.step4=Leave the {value} ch onboarding.tutorial.with.gitlab_ci.yaml.title=Create or update the configuration file onboarding.tutorial.with.gitlab_ci.yaml.description=Create or update your {filename} file with the following content. onboarding.tutorial.with.gitlab_ci.yaml.filename=.gitlab-ci.yml -onboarding.tutorial.with.gitlab_ci.yaml.baseconfig=Note that this is a minimal base configuration to run a SonarQube analysis on your main branch and merge requests. -onboarding.tutorial.with.gitlab_ci.yaml.baseconfig.no_branches=Note that this is a minimal base configuration to run a SonarQube analysis on your main branch. -onboarding.tutorial.with.gitlab_ci.yaml.existing=If you already have a pipeline configured and running, you might want to add the example from this step to your existing yml file. +onboarding.tutorial.with.gitlab_ci.yaml.baseconfig=Note that this is a minimal base configuration to run a SonarQube analysis on your main branch and merge requests, and fetch the vulnerability report (if applicable). +onboarding.tutorial.with.gitlab_ci.yaml.existing=If you already have a pipeline configured and running, you might want to add the example above to your existing yml file. +onboarding.tutorial.with.gitlab_ci.yaml.premium=The vulnerability report stage will only be available for Gitlab Premium users. You may safely remove it if you have not subscribed to this service. onboarding.tutorial.with.jenkins.title=Analyze your project with Jenkins onboarding.tutorial.with.jenkins.alm_selection.title=Select your DevOps platform