]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19650 Update code snippets to add vulnerability report stage to GitLab CI
authorDavid Cho-Lerat <david.cho-lerat@sonarsource.com>
Mon, 3 Jul 2023 08:49:09 +0000 (10:49 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 5 Jul 2023 20:03:04 +0000 (20:03 +0000)
server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx
server/sonar-web/src/main/js/components/tutorials/gitlabci/GitLabCITutorial.tsx
server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx
server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-it.tsx
server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/GitLabCITutorial-it.tsx.snap
server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 3de6a3ae6825960a34ee67a4f6f0e9169d4ebf55..fdb72ea155405f350fdeaef145a9a5942f66a899 100644 (file)
@@ -255,7 +255,6 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender
           baseUrl={baseUrl}
           component={component}
           currentUser={currentUser}
-          mainBranchName={mainBranchName}
           willRefreshAutomatically={willRefreshAutomatically}
         />
       )}
index ce390a784d74e55659137d343b0d2c2636a3c6b3..86a8b46dc38f518d9f8962684ac6f76462aa3bd6 100644 (file)
@@ -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) {
       <YmlFileStep
         finished={step > Steps.YML}
         component={component}
-        mainBranchName={mainBranchName}
         onDone={() => setStep(Steps.ALL_SET)}
         onOpen={() => setStep(Steps.YML)}
         open={step === Steps.YML}
index 1b727795d95db4898f8b4ecc83651940ddeedaf2..e5eb3526f37ce98dcb83c781d36f9e7332502732 100644 (file)
@@ -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 = () => `<properties>
+const mavenSnippet = (key: string, name: string) => `<properties>
+  <sonar.projectKey>${key}</sonar.projectKey>
+  <sonar.projectName>${name}</sonar.projectName>
   <sonar.qualitygate.wait>true</sonar.qualitygate.wait>
 </properties>`;
 
@@ -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<BuildTools>();
 
   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) {
       <ol className="list-styled">
         <li>
           {translate('onboarding.build')}
+
           <RenderOptions
-            label={translate('onboarding.build')}
             checked={buildTool}
+            label={translate('onboarding.build')}
             onCheck={setBuildTool as (key: string) => void}
             optionLabelKey="onboarding.build"
             options={buildTools}
           />
+
           {buildTool === BuildTools.CFamily && (
             <GithubCFamilyExampleRepositories
-              className="big-spacer-bottom big-spacer-top abs-width-600"
               ci={TutorialModes.GitLabCI}
+              className="sw-mb-4 sw-mt-4 sw-w-[600px]"
             />
           )}
         </li>
-        {buildTool !== undefined && buildTool !== BuildTools.DotNet && (
-          <li className="abs-width-600">
-            <FormattedMessage
-              defaultMessage={translate(
-                `onboarding.tutorial.with.gitlab_ci.project_key.${buildTool}.step2`
+
+        {buildTool !== undefined &&
+          buildTool !== BuildTools.CFamily &&
+          buildTool !== BuildTools.DotNet && (
+            <li className="sw-w-[600px]">
+              <FormattedMessage
+                defaultMessage={translate(
+                  `onboarding.tutorial.with.gitlab_ci.project_key.${buildTool}.step2`
+                )}
+                id={`onboarding.tutorial.with.gitlab_ci.project_key.${buildTool}.step2`}
+                values={Object.assign(
+                  {
+                    file: (
+                      <>
+                        <code className="rule">{filenameForBuildTool[buildTool]}</code>
+
+                        <ClipboardIconButton
+                          className="little-spacer-left"
+                          copyValue={filenameForBuildTool[buildTool]}
+                        />
+                      </>
+                    ),
+                  },
+                  buildTool === BuildTools.Gradle
+                    ? {
+                        file2: (
+                          <>
+                            <code className="rule">{GradleBuildDSL.Kotlin}</code>
+
+                            <ClipboardIconButton
+                              className="sw-ml-1"
+                              copyValue={GradleBuildDSL.Kotlin}
+                            />
+                          </>
+                        ),
+                      }
+                    : {}
+                )}
+              />
+
+              {buildTool === BuildTools.Gradle ? (
+                <GradleBuildSelection className="sw-mb-4 sw-mt-2">
+                  {(build) => (
+                    <CodeSnippet
+                      snippet={snippetForBuildTool[buildTool](component.key, component.name, build)}
+                    />
+                  )}
+                </GradleBuildSelection>
+              ) : (
+                <CodeSnippet
+                  snippet={snippetForBuildTool[buildTool](component.key, component.name)}
+                />
               )}
-              id={`onboarding.tutorial.with.gitlab_ci.project_key.${buildTool}.step2`}
-              values={Object.assign(
-                {
-                  file: (
-                    <>
-                      <code className="rule">{filenameForBuildTool[buildTool]}</code>
-                      <ClipboardIconButton
-                        className="little-spacer-left"
-                        copyValue={filenameForBuildTool[buildTool]}
-                      />
-                    </>
-                  ),
-                },
-                buildTool === BuildTools.Gradle
-                  ? {
-                      file2: (
+            </li>
+          )}
+
+        {buildTool && (
+          <li className="sw-w-[600px]">
+            {buildTool !== BuildTools.CFamily && (
+              <>
+                <div className="sw-mb-4">
+                  <FormattedMessage
+                    defaultMessage={translate(
+                      'onboarding.tutorial.with.gitlab_ci.yaml.description'
+                    )}
+                    id="onboarding.tutorial.with.gitlab_ci.yaml.description"
+                    values={{
+                      filename: (
                         <>
-                          <code className="rule">{GradleBuildDSL.Kotlin}</code>
+                          <code className="rule">
+                            {translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')}
+                          </code>
+
                           <ClipboardIconButton
-                            className="little-spacer-left"
-                            copyValue={GradleBuildDSL.Kotlin}
+                            className="sw-ml-1"
+                            copyValue={translate(
+                              'onboarding.tutorial.with.gitlab_ci.yaml.filename'
+                            )}
                           />
                         </>
                       ),
-                    }
-                  : {}
-              )}
-            />
-            {buildTool === BuildTools.Gradle ? (
-              <GradleBuildSelection className="spacer-top big-spacer-bottom">
-                {(build) => (
-                  <CodeSnippet
-                    snippet={snippetForBuildTool[buildTool](component.key, component.name, build)}
+                    }}
                   />
-                )}
-              </GradleBuildSelection>
-            ) : (
-              <CodeSnippet snippet={snippetForBuildTool[buildTool](component.key)} />
+                </div>
+
+                <div className="sw-mb-4 sw-w-[600px]">
+                  <PipeCommand buildTool={buildTool} projectKey={component.key} />
+                </div>
+
+                <FlagMessage className="sw-mb-4" variant="warning">
+                  {translate('onboarding.tutorial.with.gitlab_ci.yaml.premium')}
+                </FlagMessage>
+
+                <p className="sw-mb-1">
+                  {translate('onboarding.tutorial.with.gitlab_ci.yaml.baseconfig')}
+                </p>
+
+                <p>{translate('onboarding.tutorial.with.gitlab_ci.yaml.existing')}</p>
+              </>
             )}
-          </li>
-        )}
-        {buildTool && (
-          <li className="abs-width-600">
-            <div className="big-spacer-bottom">
-              <FormattedMessage
-                defaultMessage={translate('onboarding.tutorial.with.gitlab_ci.yaml.description')}
-                id="onboarding.tutorial.with.gitlab_ci.yaml.description"
-                values={{
-                  filename: (
-                    <>
-                      <code className="rule">
-                        {translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')}
-                      </code>
-                      <ClipboardIconButton
-                        className="little-spacer-left"
-                        copyValue={translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')}
-                      />
-                    </>
-                  ),
-                }}
-              />
-            </div>
-            <div className="big-spacer-bottom abs-width-600">
-              <PipeCommand
-                buildTool={buildTool}
-                branchesEnabled={branchSupportEnabled}
-                mainBranchName={mainBranchName}
-                projectKey={component.key}
-                projectName={component.name}
-              />
-            </div>
-            <p className="little-spacer-bottom">
-              {branchSupportEnabled
-                ? translate('onboarding.tutorial.with.gitlab_ci.yaml.baseconfig')
-                : translate('onboarding.tutorial.with.gitlab_ci.yaml.baseconfig.no_branches')}
-            </p>
-            <p>{translate('onboarding.tutorial.with.gitlab_ci.yaml.existing')}</p>
             <FinishButton onClick={props.onDone} />
           </li>
         )}
index 7d76c65e381620aa4e890641b8e5e0bffbb82bc8..48caa3e9c5302cc8aba103445dc07cb8070cdd00 100644 (file)
@@ -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(
     '/',
     <GitLabCITutorial
       baseUrl="http://localhost:9000"
-      mainBranchName="main"
       component={mockComponent()}
       currentUser={mockLoggedInUser()}
       {...overrides}
index 5e7914f582260e0cfcfe87888426449c3fc46309..d3ae770b821997f95f9554609f915cdb4c7d2b22 100644 (file)
@@ -1,7 +1,12 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should follow and complete all steps: .NET: gitlab-ci.yml 1`] = `
-"sonarqube-check:
+"stages:
+    - sonarqube-check
+    - vulnerability-report
+
+sonarqube-check:
+  stage: sonarqube-check
   image: mcr.microsoft.com/dotnet/core/sdk:latest
   variables:
     SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
@@ -19,52 +24,38 @@ exports[`should follow and complete all steps: .NET: gitlab-ci.yml 1`] = `
       - "dotnet build"
       - "dotnet sonarscanner end /d:sonar.token=\\"$SONAR_TOKEN\\""
   allow_failure: true
-  rules:
-    - if: $CI_COMMIT_BRANCH == 'main'
-"
-`;
-
-exports[`should follow and complete all steps: CFamily: gitlab-ci.yml 1`] = `
-"image: <image ready for your build toolchain>
-
-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 <your clean build command>
-
-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`] = `
 "<properties>
+  <sonar.projectKey>my-project</sonar.projectKey>
+  <sonar.projectName>MyProject</sonar.projectName>
   <sonar.qualitygate.wait>true</sonar.qualitygate.wait>
 </properties>"
 `;
 
 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
 "
 `;
 
index 323b6ad67ccc2b3523a751cca6bc856a39612c7a..20b0c25132bcc426bec0bf59b05f92807f0afae5 100644 (file)
  * 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<BuildTools, BuildTools.CFamily>;
   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: <image ready for your build toolchain>
-
-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 <your clean build command>
+  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 (
-    <>
-      <CodeSnippet snippet={command} />
-      {buildTool === BuildTools.CFamily && <CompilationInfo />}
-    </>
-  );
+
+  return <CodeSnippet snippet={command} />;
 }
index 8d5125ef3a2e890ef70ddc22db9bde488c732b71..8d3b3e495c2ea3c888e410fb142591127688d825 100644 (file)
@@ -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