]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22422 Create missing C/C++ tutorials for GitLab
authorLucas Paulger <lucas.paulger@sonarsource.com>
Wed, 19 Jun 2024 15:45:42 +0000 (18:45 +0300)
committersonartech <sonartech@sonarsource.com>
Thu, 20 Jun 2024 20:02:37 +0000 (20:02 +0000)
Co-authored-by: Benjamin Raymond <31401273+7PH@users.noreply.github.com>
12 files changed:
server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/AnalysisCommand.tsx
server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/__snapshots__/BitbucketPipelinesTutorial-it.tsx.snap
server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/CFamily.ts
server/sonar-web/src/main/js/components/tutorials/components/CreateYmlFile.tsx
server/sonar-web/src/main/js/components/tutorials/components/JreRequiredWarning.tsx [new file with mode: 0644]
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
server/sonar-web/src/main/js/components/tutorials/other/__tests__/__snapshots__/OtherTutorial-it.tsx.snap
server/sonar-web/src/main/js/components/tutorials/other/commands/DownloadScanner.tsx
server/sonar-web/src/main/js/components/tutorials/utils.ts

index b5f49ab41f029f390567beb644e7cbdef359bd66..1e9a2874bb18290a452ec38c086895a80f94df38 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 { Link } from '@sonarsource/echoes-react';
 import { Dictionary } from 'lodash';
 import * as React from 'react';
-import { FormattedMessage } from 'react-intl';
 import withAvailableFeatures, {
   WithAvailableFeaturesProps,
 } from '../../../app/components/available-features/withAvailableFeatures';
-import { DocLink } from '../../../helpers/doc-links';
-import { useDocUrl } from '../../../helpers/docs';
-import { translate } from '../../../helpers/l10n';
 import { Feature } from '../../../types/features';
 import { Component } from '../../../types/types';
 import { CompilationInfo } from '../components/CompilationInfo';
 import CreateYmlFile from '../components/CreateYmlFile';
+import { JreRequiredWarning } from '../components/JreRequiredWarning';
 import { Arch, AutoConfig, BuildTools, TutorialConfig } from '../types';
 import { isCFamily } from '../utils';
 import { PreambuleYaml } from './PreambuleYaml';
@@ -78,7 +74,6 @@ const showJreWarning = (config: TutorialConfig, arch: Arch) => {
 export function AnalysisCommand(props: Readonly<AnalysisCommandProps>) {
   const { config, arch, mainBranchName, component } = props;
   const branchesEnabled = props.hasFeature(Feature.BranchSupport);
-  const scannerRequirementsUrl = useDocUrl(DocLink.SonarScannerRequirements);
 
   if (!config.buildTool) {
     return null;
@@ -93,29 +88,13 @@ export function AnalysisCommand(props: Readonly<AnalysisCommandProps>) {
     projectName: component.name,
   });
 
-  const warning = showJreWarning(config, arch) && (
-    <p className="sw-mb-2">
-      <FormattedMessage
-        defaultMessage={translate('onboarding.analysis.sq_scanner.jre_required_warning')}
-        id="onboarding.analysis.sq_scanner.jre_required_warning"
-        values={{
-          link: (
-            <Link to={scannerRequirementsUrl}>
-              {translate('onboarding.analysis.sq_scanner.jre_required_warning.link')}
-            </Link>
-          ),
-        }}
-      />
-    </p>
-  );
-
   return (
     <>
       <PreambuleYaml buildTool={config.buildTool} component={component} />
       <CreateYmlFile
         yamlFileName="bitbucket-pipelines.yml"
         yamlTemplate={yamlTemplate}
-        warning={warning}
+        warning={showJreWarning(config, arch) && <JreRequiredWarning />}
       />
       {isCFamily(config.buildTool) && <CompilationInfo />}
     </>
index af14ac13ac1c827c4194f83267afdd237ceb65a5..a88b747697f6bafd7ebcce2656fcf92e78c5bc19 100644 (file)
@@ -101,7 +101,7 @@ definitions:
     - step: &build-step
         name: Build the project, and run the SonarQube analysis
         script:
-          - export SONAR_SCANNER_VERSION=5.0.1.3006
+          - export SONAR_SCANNER_VERSION=6.0.0.4432
           - mkdir $HOME/.sonar
           - curl -sSLo $HOME/.sonar/build-wrapper-linux-aarch64.zip \${SONAR_HOST_URL}/static/cpp/build-wrapper-linux-aarch64.zip
           - unzip -o $HOME/.sonar/build-wrapper-linux-aarch64.zip -d $HOME/.sonar/
@@ -139,7 +139,7 @@ definitions:
     - step: &build-step
         name: Build the project, and run the SonarQube analysis
         script:
-          - export SONAR_SCANNER_VERSION=5.0.1.3006
+          - export SONAR_SCANNER_VERSION=6.0.0.4432
           - mkdir $HOME/.sonar
           - curl -sSLo $HOME/.sonar/build-wrapper-linux-aarch64.zip \${SONAR_HOST_URL}/static/cpp/build-wrapper-linux-aarch64.zip
           - unzip -o $HOME/.sonar/build-wrapper-linux-aarch64.zip -d $HOME/.sonar/
@@ -173,7 +173,7 @@ definitions:
     - step: &build-step
         name: Build the project, and run the SonarQube analysis
         script:
-          - export SONAR_SCANNER_VERSION=5.0.1.3006
+          - export SONAR_SCANNER_VERSION=6.0.0.4432
           - mkdir $HOME/.sonar
           - curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip \${SONAR_HOST_URL}/static/cpp/build-wrapper-linux-x86.zip
           - unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/
@@ -211,7 +211,7 @@ definitions:
     - step: &build-step
         name: Build the project, and run the SonarQube analysis
         script:
-          - export SONAR_SCANNER_VERSION=5.0.1.3006
+          - export SONAR_SCANNER_VERSION=6.0.0.4432
           - mkdir $HOME/.sonar
           - curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip \${SONAR_HOST_URL}/static/cpp/build-wrapper-linux-x86.zip
           - unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/
index cf77fbf478ae36d22a16d3b60a3a6c9b13f4bdc2..45cf9a2f670d8b112f9e9747582b4cba0365306e 100644 (file)
@@ -19,6 +19,7 @@
  */
 import { AutoConfig, BuildTools, OSs } from '../../types';
 import {
+  SONAR_SCANNER_CLI_LATEST_VERSION,
   getBuildWrapperExecutableLinux,
   getBuildWrapperFolderLinux,
   getScannerUrlSuffix,
@@ -45,7 +46,7 @@ definitions:
     - step: &build-step
         name: Build the project, and run the SonarQube analysis
         script:
-          - export SONAR_SCANNER_VERSION=5.0.1.3006
+          - export SONAR_SCANNER_VERSION=${SONAR_SCANNER_CLI_LATEST_VERSION}
           - mkdir $HOME/.sonar
           - curl -sSLo $HOME/.sonar/${buildWrapperFolder}.zip \${SONAR_HOST_URL}/static/cpp/${buildWrapperFolder}.zip
           - unzip -o $HOME/.sonar/${buildWrapperFolder}.zip -d $HOME/.sonar/
index 8be1e9d92e27eaaeaa01149a8f8ece8a873d1963..d660cc9396146c656cfa4145c9644baef487b19c 100644 (file)
@@ -17,7 +17,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import { ClipboardIconButton, CodeSnippet, FlagMessage, NumberedListItem } from 'design-system';
+import { ClipboardIconButton, CodeSnippet, NumberedListItem } from 'design-system';
 import * as React from 'react';
 import { FormattedMessage } from 'react-intl';
 import { translate } from '../../../helpers/l10n';
@@ -45,13 +45,7 @@ export default function CreateYmlFile(props: Readonly<CreateYmlFileProps>) {
           ),
         }}
       />
-      {warning && (
-        <div>
-          <FlagMessage className="sw-mt-2 sw-w-abs-600" variant="warning">
-            {warning}
-          </FlagMessage>
-        </div>
-      )}
+      {warning}
       <CodeSnippet className="sw-p-6 sw-overflow-auto" snippet={yamlTemplate} language="yml" />
     </NumberedListItem>
   );
diff --git a/server/sonar-web/src/main/js/components/tutorials/components/JreRequiredWarning.tsx b/server/sonar-web/src/main/js/components/tutorials/components/JreRequiredWarning.tsx
new file mode 100644 (file)
index 0000000..2b3cf62
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.
+ */
+import { LinkStandalone } from '@sonarsource/echoes-react';
+import { FlagMessage } from 'design-system';
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { DocLink } from '../../../helpers/doc-links';
+import { useDocUrl } from '../../../helpers/docs';
+import { translate } from '../../../helpers/l10n';
+
+export function JreRequiredWarning() {
+  const scannerRequirementsUrl = useDocUrl(DocLink.SonarScannerRequirements);
+
+  return (
+    <div>
+      <FlagMessage className="sw-mt-2 sw-w-abs-600" variant="warning">
+        <p className="sw-mb-2">
+          <FormattedMessage
+            defaultMessage={translate('onboarding.analysis.sq_scanner.jre_required_warning')}
+            id="onboarding.analysis.sq_scanner.jre_required_warning"
+            values={{
+              link: (
+                <LinkStandalone to={scannerRequirementsUrl}>
+                  {translate('onboarding.analysis.sq_scanner.jre_required_warning.link')}
+                </LinkStandalone>
+              ),
+            }}
+          />
+        </p>
+      </FlagMessage>
+    </div>
+  );
+}
index fa9f0642e5988ed82fc09f8126be1584eb311eff..fd25ce98de37fa7dc53d894a423ade0ef963fafd 100644 (file)
@@ -38,8 +38,14 @@ import BuildConfigSelection from '../components/BuildConfigSelection';
 import GithubCFamilyExampleRepositories from '../components/GithubCFamilyExampleRepositories';
 import GradleBuildSelection from '../components/GradleBuildSelection';
 import { InlineSnippet } from '../components/InlineSnippet';
-import { BuildTools, GradleBuildDSL, TutorialConfig, TutorialModes } from '../types';
-import { isCFamily } from '../utils';
+import { JreRequiredWarning } from '../components/JreRequiredWarning';
+import RenderOptions from '../components/RenderOptions';
+import { Arch, BuildTools, GradleBuildDSL, OSs, TutorialConfig, TutorialModes } from '../types';
+import {
+  shouldShowArchSelector,
+  shouldShowGithubCFamilyExampleRepositories,
+  showJreWarning,
+} from '../utils';
 import PipeCommand from './commands/PipeCommand';
 
 export interface YmlFileStepProps extends WithAvailableFeaturesProps {
@@ -110,8 +116,10 @@ const snippetLanguageForBuildTool = {
   [BuildTools.Other]: undefined,
 };
 
-export function YmlFileStep(props: YmlFileStepProps) {
+export function YmlFileStep(props: Readonly<YmlFileStepProps>) {
   const { component, hasCLanguageFeature, setDone } = props;
+  const [os, setOs] = React.useState<OSs>(OSs.Linux);
+  const [arch, setArch] = React.useState<Arch>(Arch.X86_64);
 
   const [config, setConfig] = React.useState<TutorialConfig>({});
   const { buildTool } = config;
@@ -131,11 +139,32 @@ export function YmlFileStep(props: YmlFileStepProps) {
           ci={TutorialModes.GitLabCI}
           config={config}
           supportCFamily={hasCLanguageFeature}
-          hideAutoConfig
           onSetConfig={onSetConfig}
         />
+        {(config.buildTool === BuildTools.Other ||
+          config.buildTool === BuildTools.Cpp ||
+          config.buildTool === BuildTools.ObjectiveC) && (
+          <RenderOptions
+            label={translate('onboarding.build.other.os')}
+            checked={os}
+            onCheck={(value: OSs) => setOs(value)}
+            optionLabelKey="onboarding.build.other.os"
+            options={[OSs.Linux, OSs.Windows, OSs.MacOS]}
+            titleLabelKey="onboarding.build.other.os"
+          />
+        )}
+        {shouldShowArchSelector(os, config) && (
+          <RenderOptions
+            label={translate('onboarding.build.other.architecture')}
+            checked={arch}
+            onCheck={(value: Arch) => setArch(value)}
+            optionLabelKey="onboarding.build.other.architecture"
+            options={[Arch.X86_64, Arch.Arm64]}
+            titleLabelKey="onboarding.build.other.architecture"
+          />
+        )}
 
-        {isCFamily(config.buildTool) && (
+        {shouldShowGithubCFamilyExampleRepositories(config) && (
           <GithubCFamilyExampleRepositories
             ci={TutorialModes.GitLabCI}
             className="sw-my-4 sw-w-abs-600"
@@ -143,102 +172,104 @@ export function YmlFileStep(props: YmlFileStepProps) {
         )}
       </NumberedListItem>
 
-      {buildTool !== undefined &&
-        buildTool !== BuildTools.Cpp &&
-        buildTool !== BuildTools.ObjectiveC &&
-        buildTool !== BuildTools.DotNet && (
-          <NumberedListItem>
-            <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: (
-                    <>
-                      <InlineSnippet snippet={filenameForBuildTool[buildTool]} />
-
-                      <ClipboardIconButton
-                        className="sw-ml-2 sw-align-sub"
-                        copyValue={filenameForBuildTool[buildTool]}
-                      />
-                    </>
-                  ),
-                },
-                buildTool === BuildTools.Gradle
-                  ? {
-                      file2: (
-                        <>
-                          <InlineSnippet snippet={GradleBuildDSL.Kotlin} />
-
-                          <ClipboardIconButton
-                            className="sw-ml-2 sw-align-sub"
-                            copyValue={GradleBuildDSL.Kotlin}
-                          />
-                        </>
-                      ),
-                    }
-                  : {},
+      {/* Step 2 */}
+      {buildTool !== undefined && buildTool !== BuildTools.DotNet && (
+        <NumberedListItem>
+          <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: (
+                  <>
+                    <InlineSnippet snippet={filenameForBuildTool[buildTool]} />
+
+                    <ClipboardIconButton
+                      className="sw-ml-2 sw-align-sub"
+                      copyValue={filenameForBuildTool[buildTool]}
+                    />
+                  </>
+                ),
+              },
+              buildTool === BuildTools.Gradle
+                ? {
+                    file2: (
+                      <>
+                        <InlineSnippet snippet={GradleBuildDSL.Kotlin} />
+
+                        <ClipboardIconButton
+                          className="sw-ml-2 sw-align-sub"
+                          copyValue={GradleBuildDSL.Kotlin}
+                        />
+                      </>
+                    ),
+                  }
+                : {},
+            )}
+          />
+          {buildTool === BuildTools.Gradle ? (
+            <GradleBuildSelection className="sw-mb-4 sw-mt-2">
+              {(build) => (
+                <CodeSnippet
+                  className="sw-p-6"
+                  language="gradle"
+                  snippet={snippetForBuildTool[buildTool](component.key, component.name, build)}
+                />
               )}
+            </GradleBuildSelection>
+          ) : (
+            <CodeSnippet
+              className="sw-p-6"
+              language={snippetLanguageForBuildTool[buildTool]}
+              snippet={snippetForBuildTool[buildTool](component.key, component.name)}
             />
-            {buildTool === BuildTools.Gradle ? (
-              <GradleBuildSelection className="sw-mb-4 sw-mt-2">
-                {(build) => (
-                  <CodeSnippet
-                    className="sw-p-6"
-                    language="gradle"
-                    snippet={snippetForBuildTool[buildTool](component.key, component.name, build)}
-                  />
-                )}
-              </GradleBuildSelection>
-            ) : (
-              <CodeSnippet
-                className="sw-p-6"
-                language={snippetLanguageForBuildTool[buildTool]}
-                snippet={snippetForBuildTool[buildTool](component.key, component.name)}
-              />
-            )}
-          </NumberedListItem>
-        )}
+          )}
+        </NumberedListItem>
+      )}
 
+      {/* Step 3 */}
       {buildTool && (
-        <>
-          {buildTool !== BuildTools.Cpp && buildTool !== BuildTools.ObjectiveC && (
-            <NumberedListItem>
-              <FormattedMessage
-                defaultMessage={translate('onboarding.tutorial.with.gitlab_ci.yaml.description')}
-                id="onboarding.tutorial.with.gitlab_ci.yaml.description"
-                values={{
-                  filename: (
-                    <>
-                      <InlineSnippet
-                        snippet={translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')}
-                      />
-
-                      <ClipboardIconButton
-                        className="sw-ml-2 sw-align-sub"
-                        copyValue={translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')}
-                      />
-                    </>
-                  ),
-                }}
-              />
-
-              <PipeCommand buildTool={buildTool} projectKey={component.key} />
-
-              <FlagMessage className="sw-mb-4 sw-mt-2" 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>
-            </NumberedListItem>
-          )}
-        </>
+        <NumberedListItem>
+          <FormattedMessage
+            defaultMessage={translate('onboarding.tutorial.with.gitlab_ci.yaml.description')}
+            id="onboarding.tutorial.with.gitlab_ci.yaml.description"
+            values={{
+              filename: (
+                <>
+                  <InlineSnippet
+                    snippet={translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')}
+                  />
+
+                  <ClipboardIconButton
+                    className="sw-ml-2 sw-align-sub"
+                    copyValue={translate('onboarding.tutorial.with.gitlab_ci.yaml.filename')}
+                  />
+                </>
+              ),
+            }}
+          />
+          {showJreWarning(config, arch) && <JreRequiredWarning />}
+
+          <PipeCommand
+            buildTool={buildTool}
+            projectKey={component.key}
+            os={os}
+            arch={arch}
+            config={config}
+          />
+
+          <FlagMessage className="sw-mb-4 sw-mt-2" 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>
+        </NumberedListItem>
       )}
     </NumberedList>
   );
index 8459ba6ef1aadc40e55af0504cd4393db9e56643..978609584695fe3822a8db00800c39d76dc83663 100644 (file)
@@ -79,6 +79,32 @@ it('should follow and complete all steps', async () => {
   await user.click(ui.dotnetBuildButton.get());
   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('.NET: gitlab-ci.yml');
 
+  // C++/Objective-C
+  await user.click(ui.cppBuildButton.get());
+  //linux
+  expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('CPP: sonar-project.properties');
+  expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('CPP: gitlab-ci.yml');
+  //windows
+  await user.click(ui.windowsButton.get());
+  expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('CPP - windows: gitlab-ci.yml');
+  //macos
+  await user.click(ui.macosButton.get());
+  expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('CPP - macos: gitlab-ci.yml');
+
+  // c++ manual config
+  await user.click(ui.autoConfigManual.get());
+
+  //linux
+  await user.click(ui.linuxButton.get());
+  expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('CPP - manual: gitlab-ci.yml');
+
+  //windows
+  await user.click(ui.windowsButton.get());
+  expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('CPP - windows: gitlab-ci.yml');
+  //macos
+  await user.click(ui.macosButton.get());
+  expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('CPP - macos: gitlab-ci.yml');
+
   // Other
   await user.click(ui.otherBuildButton.get());
   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('Other: sonar-project.properties');
index 905163f387cd024368e67965dc236118f1af7923..304f4025ddc4df099385692192af7e47e01b814c 100644 (file)
@@ -1,20 +1,28 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`should follow and complete all steps: .NET: gitlab-ci.yml 1`] = `
-"stages:
-    - sonarqube-check
-    - sonarqube-vulnerability-report
+"image: mcr.microsoft.com/dotnet/sdk:7.0
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+
+stages:
+  - sonarqube-check
+  - sonarqube-vulnerability-report
 
 sonarqube-check:
   stage: sonarqube-check
-  image: mcr.microsoft.com/dotnet/sdk:7.0
-  variables:
-    SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
-    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  dependencies:
+    - get-binaries
+    - build
   cache:
-    key: "\${CI_JOB_NAME}"
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
     paths:
-      - .sonar/cache
+      - sonar-scanner/
+      
+      
   script: 
       - "apt-get update"
       - "apt-get install --yes --no-install-recommends openjdk-17-jre"
@@ -44,26 +52,560 @@ sonarqube-vulnerability-report:
     expire_in: 1 day
     reports:
       sast: gl-sast-sonar-report.json
+"
+`;
+
+exports[`should follow and complete all steps: CPP - macos: gitlab-ci.yml 1`] = `
+"image: gcc
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  
+
+stages:
+  - get-binaries
+  - build
+  - sonarqube-check
+  - sonarqube-vulnerability-report
+
+get-binaries:
+  stage: get-binaries
+  cache:
+    policy: push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      
+  script:
+    # Download sonar-scanner
+    - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.0.0.4432-macosx.zip'
+    - unzip -o sonar-scanner.zip
+    - mv sonar-scanner-6.0.0.4432-macosx sonar-scanner
+    
+        
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+build:
+  stage: build
+  script:
+    # prepare the build tree
+    - mkdir build
+    
+  cache:
+    policy: pull-push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+    - sonar-scanner/
+    
+
+sonarqube-check:
+  stage: sonarqube-check
+  dependencies:
+    - get-binaries
+    - build
+  cache:
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      
+      
+  script: sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" 
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+sonarqube-vulnerability-report:
+  stage: sonarqube-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_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+  artifacts:
+    expire_in: 1 day
+    reports:
+      sast: gl-sast-sonar-report.json
+"
+`;
+
+exports[`should follow and complete all steps: CPP - macos: gitlab-ci.yml 2`] = `
+"image: gcc
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
+
+stages:
+  - get-binaries
+  - build
+  - sonarqube-check
+  - sonarqube-vulnerability-report
+
+get-binaries:
+  stage: get-binaries
+  cache:
+    policy: push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      - build-wrapper/
+  script:
+    # Download sonar-scanner
+    - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.0.0.4432-macosx.zip'
+    - unzip -o sonar-scanner.zip
+    - mv sonar-scanner-6.0.0.4432-macosx sonar-scanner
+    # Download build-wrapper
+    - curl -sSLo ./build-wrapper-macosx-x86.zip "$SONAR_HOST_URL/static/cpp/build-wrapper-macosx-x86.zip"
+    - unzip -o build-wrapper-macosx-x86.zip
+    - mv build-wrapper-macosx-x86 build-wrapper
+        
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+build:
+  stage: build
+  script:
+    # prepare the build tree
+    - mkdir build
+    - build-wrapper/build-wrapper-macosx-x86 --out-dir "\${BUILD_WRAPPER_OUT_DIR}" <your clean build command>
+  cache:
+    policy: pull-push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+    - sonar-scanner/
+    - build-wrapper/
+    - "\${BUILD_WRAPPER_OUT_DIR}"
+
+sonarqube-check:
+  stage: sonarqube-check
+  dependencies:
+    - get-binaries
+    - build
+  cache:
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      - "\${BUILD_WRAPPER_OUT_DIR}"
+      
+  script: sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" 
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+sonarqube-vulnerability-report:
+  stage: sonarqube-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_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+  artifacts:
+    expire_in: 1 day
+    reports:
+      sast: gl-sast-sonar-report.json
+"
+`;
+
+exports[`should follow and complete all steps: CPP - manual: gitlab-ci.yml 1`] = `
+"image: gcc
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
+
+stages:
+  - get-binaries
+  - build
+  - sonarqube-check
+  - sonarqube-vulnerability-report
+
+get-binaries:
+  stage: get-binaries
+  cache:
+    policy: push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      - build-wrapper/
+  script:
+    # Download sonar-scanner
+    - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.0.0.4432-linux.zip'
+    - unzip -o sonar-scanner.zip
+    - mv sonar-scanner-6.0.0.4432-linux sonar-scanner
+    # Download build-wrapper
+    - curl -sSLo ./build-wrapper-linux-x86.zip "$SONAR_HOST_URL/static/cpp/build-wrapper-linux-x86.zip"
+    - unzip -o build-wrapper-linux-x86.zip
+    - mv build-wrapper-linux-x86 build-wrapper
+        
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+build:
+  stage: build
+  script:
+    # prepare the build tree
+    - mkdir build
+    - build-wrapper/build-wrapper-linux-x86-64 --out-dir "\${BUILD_WRAPPER_OUT_DIR}" <your clean build command>
+  cache:
+    policy: pull-push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+    - sonar-scanner/
+    - build-wrapper/
+    - "\${BUILD_WRAPPER_OUT_DIR}"
+
+sonarqube-check:
+  stage: sonarqube-check
   dependencies:
-    - sonarqube-check
+    - get-binaries
+    - build
+  cache:
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      - "\${BUILD_WRAPPER_OUT_DIR}"
+      
+  script: sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" 
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+sonarqube-vulnerability-report:
+  stage: sonarqube-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_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+  artifacts:
+    expire_in: 1 day
+    reports:
+      sast: gl-sast-sonar-report.json
+"
+`;
+
+exports[`should follow and complete all steps: CPP - windows: gitlab-ci.yml 1`] = `
+"image: gcc
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  
+
+stages:
+  - get-binaries
+  - build
+  - sonarqube-check
+  - sonarqube-vulnerability-report
+
+get-binaries:
+  stage: get-binaries
+  cache:
+    policy: push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      
+  script:
+    # Download sonar-scanner
+    - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.0.0.4432-windows.zip'
+    - unzip -o sonar-scanner.zip
+    - mv sonar-scanner-6.0.0.4432-windows sonar-scanner
+    
+        
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+build:
+  stage: build
+  script:
+    # prepare the build tree
+    - mkdir build
+    
+  cache:
+    policy: pull-push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+    - sonar-scanner/
+    
+
+sonarqube-check:
+  stage: sonarqube-check
+  dependencies:
+    - get-binaries
+    - build
+  cache:
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      
+      
+  script: sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" 
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+sonarqube-vulnerability-report:
+  stage: sonarqube-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_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+  artifacts:
+    expire_in: 1 day
+    reports:
+      sast: gl-sast-sonar-report.json
+"
+`;
+
+exports[`should follow and complete all steps: CPP - windows: gitlab-ci.yml 2`] = `
+"image: gcc
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
+
+stages:
+  - get-binaries
+  - build
+  - sonarqube-check
+  - sonarqube-vulnerability-report
+
+get-binaries:
+  stage: get-binaries
+  cache:
+    policy: push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      - build-wrapper/
+  script:
+    # Download sonar-scanner
+    - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.0.0.4432-windows.zip'
+    - unzip -o sonar-scanner.zip
+    - mv sonar-scanner-6.0.0.4432-windows sonar-scanner
+    # Download build-wrapper
+    - curl -sSLo ./build-wrapper-win-x86.zip "$SONAR_HOST_URL/static/cpp/build-wrapper-win-x86.zip"
+    - unzip -o build-wrapper-win-x86.zip
+    - mv build-wrapper-win-x86 build-wrapper
+        
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+build:
+  stage: build
+  script:
+    # prepare the build tree
+    - mkdir build
+    - build-wrapper/build-wrapper-win-x86-64.exe --out-dir "\${BUILD_WRAPPER_OUT_DIR}" <your clean build command>
+  cache:
+    policy: pull-push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+    - sonar-scanner/
+    - build-wrapper/
+    - "\${BUILD_WRAPPER_OUT_DIR}"
+
+sonarqube-check:
+  stage: sonarqube-check
+  dependencies:
+    - get-binaries
+    - build
+  cache:
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      - "\${BUILD_WRAPPER_OUT_DIR}"
+      
+  script: sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" 
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+sonarqube-vulnerability-report:
+  stage: sonarqube-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_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+  artifacts:
+    expire_in: 1 day
+    reports:
+      sast: gl-sast-sonar-report.json
+"
+`;
+
+exports[`should follow and complete all steps: CPP: gitlab-ci.yml 1`] = `
+"image: gcc
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  
+
+stages:
+  - get-binaries
+  - build
+  - sonarqube-check
+  - sonarqube-vulnerability-report
+
+get-binaries:
+  stage: get-binaries
+  cache:
+    policy: push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      
+  script:
+    # Download sonar-scanner
+    - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.0.0.4432-linux.zip'
+    - unzip -o sonar-scanner.zip
+    - mv sonar-scanner-6.0.0.4432-linux sonar-scanner
+    
+        
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+build:
+  stage: build
+  script:
+    # prepare the build tree
+    - mkdir build
+    
+  cache:
+    policy: pull-push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+    - sonar-scanner/
+    
+
+sonarqube-check:
+  stage: sonarqube-check
+  dependencies:
+    - get-binaries
+    - build
+  cache:
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      
+      
+  script: sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" 
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+
+sonarqube-vulnerability-report:
+  stage: sonarqube-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_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'
+  artifacts:
+    expire_in: 1 day
+    reports:
+      sast: gl-sast-sonar-report.json
+"
+`;
+
+exports[`should follow and complete all steps: CPP: sonar-project.properties 1`] = `
+"sonar.projectKey=my-project
+sonar.qualitygate.wait=true
 "
 `;
 
 exports[`should follow and complete all steps: Gradle: gitlab-ci.yml 1`] = `
-"stages:
-    - sonarqube-check
-    - sonarqube-vulnerability-report
+"image: gradle:8.2.0-jdk17-jammy
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+
+stages:
+  - sonarqube-check
+  - sonarqube-vulnerability-report
 
 sonarqube-check:
   stage: sonarqube-check
-  image: gradle:8.2.0-jdk17-jammy
-  variables:
-    SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
-    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  dependencies:
+    - get-binaries
+    - build
   cache:
-    key: "\${CI_JOB_NAME}"
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
     paths:
-      - .sonar/cache
+      - sonar-scanner/
+      
+      
   script: gradle sonar
   allow_failure: true
   rules:
@@ -86,8 +628,6 @@ sonarqube-vulnerability-report:
     expire_in: 1 day
     reports:
       sast: gl-sast-sonar-report.json
-  dependencies:
-    - sonarqube-check
 "
 `;
 
@@ -120,20 +660,28 @@ sonar {
 `;
 
 exports[`should follow and complete all steps: Maven: gitlab-ci.yml 1`] = `
-"stages:
-    - sonarqube-check
-    - sonarqube-vulnerability-report
+"image: maven:3-eclipse-temurin-17
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+
+stages:
+  - sonarqube-check
+  - sonarqube-vulnerability-report
 
 sonarqube-check:
   stage: sonarqube-check
-  image: maven:3-eclipse-temurin-17
-  variables:
-    SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
-    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  dependencies:
+    - get-binaries
+    - build
   cache:
-    key: "\${CI_JOB_NAME}"
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
     paths:
-      - .sonar/cache
+      - sonar-scanner/
+      
+      
   script: 
     - mvn verify sonar:sonar
   allow_failure: true
@@ -157,8 +705,6 @@ sonarqube-vulnerability-report:
     expire_in: 1 day
     reports:
       sast: gl-sast-sonar-report.json
-  dependencies:
-    - sonarqube-check
 "
 `;
 
@@ -171,22 +717,30 @@ exports[`should follow and complete all steps: Maven: pom.xml 1`] = `
 `;
 
 exports[`should follow and complete all steps: Other: gitlab-ci.yml 1`] = `
-"stages:
-    - sonarqube-check
-    - sonarqube-vulnerability-report
+"image: 
+    name: sonarsource/sonar-scanner-cli:latest
+    entrypoint: [""]
+
+variables:
+  SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+
+stages:
+  - sonarqube-check
+  - sonarqube-vulnerability-report
 
 sonarqube-check:
   stage: sonarqube-check
-  image: 
-    name: sonarsource/sonar-scanner-cli:5.0
-    entrypoint: [""]
-  variables:
-    SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
-    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  dependencies:
+    - get-binaries
+    - build
   cache:
-    key: "\${CI_JOB_NAME}"
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
     paths:
-      - .sonar/cache
+      - sonar-scanner/
+      
+      
   script: 
     - sonar-scanner
   allow_failure: true
@@ -210,8 +764,6 @@ sonarqube-vulnerability-report:
     expire_in: 1 day
     reports:
       sast: gl-sast-sonar-report.json
-  dependencies:
-    - sonarqube-check
 "
 `;
 
index 907d1988476783f793bc88226ac8951094ed11a7..ed1a2df278056f8ffe56dcb58c507d4fd87cad16 100644 (file)
  */
 import { CodeSnippet } from 'design-system';
 import * as React from 'react';
-import { BuildTools } from '../../types';
+import { CompilationInfo } from '../../components/CompilationInfo';
+import { Arch, AutoConfig, BuildTools, OSs, TutorialConfig } from '../../types';
+import {
+  SONAR_SCANNER_CLI_LATEST_VERSION,
+  getBuildWrapperExecutable,
+  getBuildWrapperFolder,
+  getScannerUrlSuffix,
+  isCFamily,
+} from '../../utils';
 
 export interface PipeCommandProps {
-  buildTool: Exclude<BuildTools, BuildTools.Cpp | BuildTools.ObjectiveC>;
+  arch: Arch;
+  buildTool: BuildTools;
+  config: TutorialConfig;
+  os: OSs;
   projectKey: string;
 }
 
-const BUILD_TOOL_SPECIFIC = {
+type ScriptFunction = (projectKey?: string, autoConfig?: AutoConfig) => string;
+
+const BUILD_TOOL_SPECIFIC: {
+  [key in BuildTools]: {
+    image: string;
+    script: ScriptFunction;
+  };
+} = {
   [BuildTools.Gradle]: {
     image: 'gradle:8.2.0-jdk17-jammy',
     script: () => 'gradle sonar',
@@ -47,43 +65,104 @@ const BUILD_TOOL_SPECIFIC = {
       - "dotnet build"
       - "dotnet sonarscanner end /d:sonar.token=\\"$SONAR_TOKEN\\""`,
   },
+  [BuildTools.Cpp]: {
+    image: 'gcc',
+    script: (autoConfig?: AutoConfig) =>
+      `sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" ${autoConfig === AutoConfig.Manual ? `--define sonar.cfamily.compile-commands="\${BUILD_WRAPPER_OUT_DIR}/compile_commands.json"` : ''}`,
+  },
+  [BuildTools.ObjectiveC]: {
+    image: 'gcc',
+    script: (autoConfig?: AutoConfig) =>
+      `sonar-scanner/bin/sonar-scanner --define sonar.host.url="\${SONAR_HOST_URL}" ${autoConfig === AutoConfig.Manual ? `--define sonar.cfamily.compile-commands="\${BUILD_WRAPPER_OUT_DIR}/compile_commands.json"` : ''}`,
+  },
   [BuildTools.Other]: {
     image: `
-    name: sonarsource/sonar-scanner-cli:5.0
+    name: sonarsource/sonar-scanner-cli:latest
     entrypoint: [""]`,
     script: () => `
     - sonar-scanner`,
   },
 };
 
-export default function PipeCommand(props: PipeCommandProps) {
-  const { projectKey, buildTool } = props;
+export default function PipeCommand(props: Readonly<PipeCommandProps>) {
+  const { projectKey, buildTool, config, os, arch } = props;
+  const { autoConfig } = config;
 
   const { image, script } = BUILD_TOOL_SPECIFIC[buildTool];
 
-  const command = `stages:
-    - sonarqube-check
-    - sonarqube-vulnerability-report
+  const suffix = getScannerUrlSuffix(os, arch);
+
+  const getBinaries = `get-binaries:
+  stage: get-binaries
+  cache:
+    policy: push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+      - sonar-scanner/
+      ${autoConfig === AutoConfig.Manual ? `- build-wrapper/` : ''}
+  script:
+    # Download sonar-scanner
+    - curl -sSLo ./sonar-scanner.zip 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_CLI_LATEST_VERSION}${suffix}.zip'
+    - unzip -o sonar-scanner.zip
+    - mv sonar-scanner-${SONAR_SCANNER_CLI_LATEST_VERSION}${suffix} sonar-scanner
+    ${
+      autoConfig === AutoConfig.Manual
+        ? `# Download build-wrapper
+    - curl -sSLo ./${getBuildWrapperFolder(os, arch)}.zip "$SONAR_HOST_URL/static/cpp/${getBuildWrapperFolder(os, arch)}.zip"
+    - unzip -o ${getBuildWrapperFolder(os, arch)}.zip
+    - mv ${getBuildWrapperFolder(os, arch)} build-wrapper`
+        : ''
+    }
+        
+  rules:
+    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: $CI_COMMIT_BRANCH == 'master'
+    - if: $CI_COMMIT_BRANCH == 'main'
+    - if: $CI_COMMIT_BRANCH == 'develop'`;
+
+  const build = `build:
+  stage: build
+  script:
+    # prepare the build tree
+    - mkdir build
+    ${
+      autoConfig === AutoConfig.Manual
+        ? `- build-wrapper/${getBuildWrapperExecutable(os, arch)} --out-dir "\${BUILD_WRAPPER_OUT_DIR}" <your clean build command>`
+        : ''
+    }
+  cache:
+    policy: pull-push
+    key: "\${CI_COMMIT_SHORT_SHA}"
+    paths:
+    - sonar-scanner/
+    ${
+      autoConfig === AutoConfig.Manual
+        ? `- build-wrapper/
+    - "\${BUILD_WRAPPER_OUT_DIR}"`
+        : ''
+    }`;
 
-sonarqube-check:
+  const sonarqubeCheck = `sonarqube-check:
   stage: sonarqube-check
-  image: ${image}
-  variables:
-    SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
-    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  dependencies:
+    - get-binaries
+    - build
   cache:
-    key: "\${CI_JOB_NAME}"
+    policy: pull
+    key: "\${CI_COMMIT_SHORT_SHA}"
     paths:
-      - .sonar/cache
-  script: ${script(projectKey)}
+      - sonar-scanner/
+      ${autoConfig === AutoConfig.Manual ? `- "\${BUILD_WRAPPER_OUT_DIR}"` : ''}
+      
+  script: ${script(projectKey, autoConfig)}
   allow_failure: true
   rules:
     - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
     - if: $CI_COMMIT_BRANCH == 'master'
     - if: $CI_COMMIT_BRANCH == 'main'
-    - if: $CI_COMMIT_BRANCH == 'develop'
+    - if: $CI_COMMIT_BRANCH == 'develop'`;
 
-sonarqube-vulnerability-report:
+  const vulnerabilityReport = `sonarqube-vulnerability-report:
   stage: sonarqube-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'
@@ -97,9 +176,47 @@ sonarqube-vulnerability-report:
     expire_in: 1 day
     reports:
       sast: gl-sast-sonar-report.json
-  dependencies:
-    - sonarqube-check
 `;
 
-  return <CodeSnippet className="sw-p-6" snippet={command} language="yml" />;
+  let stageDeclaration = ['sonarqube-check', 'sonarqube-vulnerability-report'];
+  let stages = [sonarqubeCheck, vulnerabilityReport];
+
+  if (buildTool === BuildTools.Cpp || buildTool === BuildTools.ObjectiveC) {
+    // only for c-family languages on manual configuration
+    stages = [getBinaries, build, ...stages];
+    stageDeclaration = ['get-binaries', 'build', ...stageDeclaration];
+  }
+
+  const stageDefinition =
+    stageDeclaration.length > 0
+      ? `- ${stageDeclaration[0]}\n${stageDeclaration
+          .slice(1)
+          .map((stage) => `  - ${stage}`)
+          .join('\n')}`
+      : '';
+
+  const variables = isCFamily(buildTool)
+    ? `SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
+  ${autoConfig === AutoConfig.Manual ? `BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed` : ''}`
+    : `SONAR_USER_HOME: "\${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
+  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task`;
+
+  const command = `image: ${image}
+
+variables:
+  ${variables}
+
+stages:
+  ${stageDefinition}
+
+${stages.join('\n\n')}`;
+
+  return (
+    <>
+      <CodeSnippet className="sw-p-6" snippet={command} language="yml" />
+      {buildTool === (BuildTools.Cpp || BuildTools.ObjectiveC) &&
+        autoConfig === AutoConfig.Manual && <CompilationInfo />}
+    </>
+  );
 }
index 9bbba92c69505d240ea7c4a6dff5fc39d49c625f..2ae0900ed2dfe4ca0fecdf8a8b30be4971df1c3c 100644 (file)
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`can choose build tools and copy provided settings: c++ (automatic) and other linux arm64: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -18,7 +18,7 @@ exports[`can choose build tools and copy provided settings: c++ (automatic) and
 `;
 
 exports[`can choose build tools and copy provided settings: c++ (automatic) and other linux: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -35,7 +35,7 @@ exports[`can choose build tools and copy provided settings: c++ (automatic) and
 `;
 
 exports[`can choose build tools and copy provided settings: c++ (automatic) and other linux: execute scanner 2`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -52,7 +52,7 @@ exports[`can choose build tools and copy provided settings: c++ (automatic) and
 `;
 
 exports[`can choose build tools and copy provided settings: c++ (automatic) and other macos: execute scanner 2`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-macosx
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-macosx.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -64,7 +64,7 @@ export SONAR_SCANNER_OPTS="-server"
 exports[`can choose build tools and copy provided settings: c++ (automatic) and other windows: execute scanner 1`] = `"sonar-scanner.bat -D"sonar.projectKey=my-project" -D"sonar.sources=." -D"sonar.host.url=http://localhost:9000""`;
 
 exports[`can choose build tools and copy provided settings: c++ (automatic) and other windows: execute scanner 2`] = `
-"$env:SONAR_SCANNER_VERSION = "5.0.1.3006"
+"$env:SONAR_SCANNER_VERSION = "6.0.0.4432"
 $env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
 $env:SONAR_SCANNER_HOME = "$env:SONAR_DIRECTORY/sonar-scanner-$env:SONAR_SCANNER_VERSION-windows"
 rm $env:SONAR_SCANNER_HOME -Force -Recurse -ErrorAction SilentlyContinue
@@ -86,7 +86,7 @@ export PATH=$HOME/.sonar/build-wrapper-linux-aarch64:$PATH
 `;
 
 exports[`can choose build tools and copy provided settings: c++ (manual) linux arm64: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -113,7 +113,7 @@ export PATH=$HOME/.sonar/build-wrapper-linux-x86:$PATH
 `;
 
 exports[`can choose build tools and copy provided settings: c++ (manual) linux: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -140,7 +140,7 @@ export PATH=$HOME/.sonar/build-wrapper-macosx-x86:$PATH
 `;
 
 exports[`can choose build tools and copy provided settings: c++ (manual) macos: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-macosx
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-macosx.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -171,7 +171,7 @@ $env:Path += ";$env:SONAR_DIRECTORY/build-wrapper-win-x86"
 `;
 
 exports[`can choose build tools and copy provided settings: c++ (manual) windows: download scanner 1`] = `
-"$env:SONAR_SCANNER_VERSION = "5.0.1.3006"
+"$env:SONAR_SCANNER_VERSION = "6.0.0.4432"
 $env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
 $env:SONAR_SCANNER_HOME = "$env:SONAR_DIRECTORY/sonar-scanner-$env:SONAR_SCANNER_VERSION-windows"
 rm $env:SONAR_SCANNER_HOME -Force -Recurse -ErrorAction SilentlyContinue
@@ -233,7 +233,7 @@ export PATH=$HOME/.sonar/build-wrapper-linux-aarch64:$PATH
 `;
 
 exports[`can choose build tools and copy provided settings: objective-c linux arm64: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -260,7 +260,7 @@ export PATH=$HOME/.sonar/build-wrapper-linux-x86:$PATH
 `;
 
 exports[`can choose build tools and copy provided settings: objective-c linux: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -287,7 +287,7 @@ export PATH=$HOME/.sonar/build-wrapper-macosx-x86:$PATH
 `;
 
 exports[`can choose build tools and copy provided settings: objective-c macos: download scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
+"export SONAR_SCANNER_VERSION=6.0.0.4432
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-macosx
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-macosx.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
@@ -318,7 +318,7 @@ $env:Path += ";$env:SONAR_DIRECTORY/build-wrapper-win-x86"
 `;
 
 exports[`can choose build tools and copy provided settings: objective-c windows: download scanner 1`] = `
-"$env:SONAR_SCANNER_VERSION = "5.0.1.3006"
+"$env:SONAR_SCANNER_VERSION = "6.0.0.4432"
 $env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
 $env:SONAR_SCANNER_HOME = "$env:SONAR_DIRECTORY/sonar-scanner-$env:SONAR_SCANNER_VERSION-windows"
 rm $env:SONAR_SCANNER_HOME -Force -Recurse -ErrorAction SilentlyContinue
index 872f355e2061011ccafbf810c59b50edb0ff6c59..9e8564d4d8df488ccab401fb1c29b625b38352a4 100644 (file)
@@ -34,7 +34,7 @@ import { useDocUrl } from '../../../../helpers/docs';
 import { translate } from '../../../../helpers/l10n';
 import { InlineSnippet } from '../../components/InlineSnippet';
 import { Arch, OSs } from '../../types';
-import { getScannerUrlSuffix } from '../../utils';
+import { SONAR_SCANNER_CLI_LATEST_VERSION, getScannerUrlSuffix } from '../../utils';
 
 export interface DownloadScannerProps {
   arch: Arch;
@@ -121,7 +121,7 @@ export default function DownloadScanner(props: Readonly<DownloadScannerProps>) {
 
 function getRemoteDownloadSnippet(os: OSs, arch: Arch) {
   if (os === OSs.Windows) {
-    return `$env:SONAR_SCANNER_VERSION = "5.0.1.3006"
+    return `$env:SONAR_SCANNER_VERSION = "${SONAR_SCANNER_CLI_LATEST_VERSION}"
 $env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
 $env:SONAR_SCANNER_HOME = "$env:SONAR_DIRECTORY/sonar-scanner-$env:SONAR_SCANNER_VERSION-windows"
 rm $env:SONAR_SCANNER_HOME -Force -Recurse -ErrorAction SilentlyContinue
@@ -135,7 +135,7 @@ $env:SONAR_SCANNER_OPTS="-server"
 `;
   }
   const suffix = getScannerUrlSuffix(os, arch);
-  return `export SONAR_SCANNER_VERSION=5.0.1.3006
+  return `export SONAR_SCANNER_VERSION=${SONAR_SCANNER_CLI_LATEST_VERSION}
 export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION${suffix}
 curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION${suffix}.zip
 unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
index fc1a041aaae4698218a355b85c32aeb0cb7ac720..8fb5b323ba7d96b43a445644f04178cd9d127909 100644 (file)
@@ -23,6 +23,8 @@ import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../types/alm-
 import { UserToken } from '../../types/token';
 import { Arch, AutoConfig, BuildTools, GradleBuildDSL, OSs, TutorialConfig } from './types';
 
+export const SONAR_SCANNER_CLI_LATEST_VERSION = '6.0.0.4432';
+
 export function quote(os: string): (s: string) => string {
   return os === 'win' ? (s: string) => `"${s}"` : (s: string) => s;
 }
@@ -185,3 +187,13 @@ export function getScannerUrlSuffix(os: OSs, arch?: Arch) {
   }
   return '';
 }
+
+export function showJreWarning(config: TutorialConfig, arch: Arch) {
+  if (!isCFamily(config.buildTool)) {
+    return false;
+  }
+  if (config.autoConfig === AutoConfig.Automatic) {
+    return false;
+  }
+  return arch === Arch.Arm64;
+}