aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author7PH <benjamin.raymond@sonarsource.com>2024-06-04 14:45:24 +0200
committersonartech <sonartech@sonarsource.com>2024-06-06 20:02:43 +0000
commit32a9a1730baad588acb37495a99d6384b973618c (patch)
tree7e2e8bdb01782e084b1090ef5813da3cf37f1618
parent1665a57c0e3110d51e99bb3b1b10f2a1a677ec5f (diff)
downloadsonarqube-32a9a1730baad588acb37495a99d6384b973618c.tar.gz
sonarqube-32a9a1730baad588acb37495a99d6384b973618c.zip
SONAR-22341 Add AutoConfig option to SQ onboarding tutorials for C/C++
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx9
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx42
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/AzurePipelinesTutorial-it.tsx69
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap77
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx22
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx149
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx3
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/AnalysisCommand.tsx48
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/BitbucketPipelinesTutorial.tsx19
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/PreambuleYaml.tsx3
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/BitbucketPipelinesTutorial-it.tsx38
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/__snapshots__/BitbucketPipelinesTutorial-it.tsx.snap133
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/CFamily.ts13
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/DotNet.ts16
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Gradle.ts8
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Maven.ts18
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Others.ts8
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/components/BuildConfigSelection.tsx84
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/components/RenderOptions.tsx5
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/components/YamlFileStep.tsx37
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx12
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx15
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/GithubActionTutorial-it.tsx47
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/GithubActionTutorial-it.tsx.snap179
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx59
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/gitlabci/GitLabCITutorial.tsx1
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx53
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx71
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx4
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx50
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/JenkinsTutorial-it.tsx.snap544
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamily.tsx (renamed from server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx)27
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/other/BuildToolForm.tsx123
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/other/ProjectAnalysisStep.tsx54
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/other/__tests__/OtherTutorial-it.tsx49
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/other/__tests__/__snapshots__/OtherTutorial-it.tsx.snap98
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx41
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/test-utils.ts5
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/types.ts15
-rw-r--r--server/sonar-web/src/main/js/components/tutorials/utils.ts30
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties17
43 files changed, 1591 insertions, 712 deletions
diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx
index 560eb393f6a..8f024dd20d1 100644
--- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/AzurePipelinesTutorial.tsx
@@ -24,6 +24,7 @@ import { AlmKeys } from '../../../types/alm-settings';
import { Component } from '../../../types/types';
import { LoggedInUser } from '../../../types/users';
import AllSet from '../components/AllSet';
+import { TutorialConfig } from '../types';
import BranchAnalysisStepContent from './BranchAnalysisStepContent';
import ExtensionInstallationStepContent from './ExtensionInstallationStepContent';
import ServiceEndpointStepContent from './ServiceEndpointStepContent';
@@ -44,8 +45,14 @@ export enum Steps {
export default function AzurePipelinesTutorial(props: AzurePipelinesTutorialProps) {
const { alm, baseUrl, component, currentUser, willRefreshAutomatically } = props;
+
+ const [config, setConfig] = React.useState<TutorialConfig>({});
const [done, setDone] = React.useState<boolean>(false);
+ React.useEffect(() => {
+ setDone(Boolean(config.buildTool));
+ }, [config.buildTool]);
+
return (
<>
<Title>{translate('onboarding.tutorial.with.azure_pipelines.title')}</Title>
@@ -76,7 +83,7 @@ export default function AzurePipelinesTutorial(props: AzurePipelinesTutorialProp
`onboarding.tutorial.with.azure_pipelines.${Steps.BranchAnalysis}.title`,
)}
>
- <BranchAnalysisStepContent component={component} onDone={setDone} />
+ <BranchAnalysisStepContent config={config} setConfig={setConfig} component={component} />
</TutorialStep>
{done && (
diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx
index e4f852ffa28..811e2ce5829 100644
--- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx
@@ -19,50 +19,32 @@
*/
import * as React from 'react';
import withLanguagesContext from '../../../app/components/languages/withLanguagesContext';
-import { translate } from '../../../helpers/l10n';
import { Languages } from '../../../types/languages';
import { Component } from '../../../types/types';
-import RenderOptions from '../components/RenderOptions';
-import { BuildTools } from '../types';
+import BuildConfigSelection from '../components/BuildConfigSelection';
+import { TutorialConfig, TutorialModes } from '../types';
import AnalysisCommand from './commands/AnalysisCommand';
export interface BranchesAnalysisStepProps {
component: Component;
+ config: TutorialConfig;
languages: Languages;
- onDone: (done: boolean) => void;
+ setConfig: (config: TutorialConfig) => void;
}
-const BUILD_TOOLS_ORDERED: Array<BuildTools> = [
- BuildTools.DotNet,
- BuildTools.Maven,
- BuildTools.Gradle,
- BuildTools.CFamily,
- BuildTools.Other,
-];
-
export function BranchAnalysisStepContent(props: BranchesAnalysisStepProps) {
- const { component, languages } = props;
+ const { config, setConfig, component, languages } = props;
- const [buildTechnology, setBuildTechnology] = React.useState<BuildTools | undefined>();
- const buildToolsList = languages['c']
- ? BUILD_TOOLS_ORDERED
- : BUILD_TOOLS_ORDERED.filter((t) => t !== BuildTools.CFamily);
return (
<>
- <span>{translate('onboarding.build')}</span>
- <RenderOptions
- label={translate('onboarding.build')}
- checked={buildTechnology}
- onCheck={(value) => setBuildTechnology(value as BuildTools)}
- optionLabelKey="onboarding.build"
- options={buildToolsList}
- />
- <AnalysisCommand
- onStepValidationChange={props.onDone}
- buildTool={buildTechnology}
- projectKey={component.key}
- projectName={component.name}
+ <BuildConfigSelection
+ ci={TutorialModes.AzurePipelines}
+ config={config}
+ supportCFamily={Boolean(languages['c'])}
+ onSetConfig={setConfig}
/>
+
+ <AnalysisCommand config={config} projectKey={component.key} projectName={component.name} />
</>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/AzurePipelinesTutorial-it.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/AzurePipelinesTutorial-it.tsx
index 73dde6800bb..3f58c95ae0c 100644
--- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/AzurePipelinesTutorial-it.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/AzurePipelinesTutorial-it.tsx
@@ -53,10 +53,10 @@ it('should render correctly and allow token generation', async () => {
screen.getByRole('heading', { name: 'onboarding.tutorial.with.azure_pipelines.title' }),
).toBeInTheDocument();
- //// Default step.
+ // Default step.
assertDefaultStepIsCorrectlyRendered();
- //// Token step.
+ // Token step.
assertServiceEndpointStepIsCorrectlyRendered();
// Generate a token.
@@ -73,36 +73,50 @@ it('should render correctly and allow token generation', async () => {
).toBeInTheDocument();
await clickButton(user, 'continue', modal);
- //// Analysis step: .NET
+ // Analysis step: .NET
await user.click(getTutorialBuildButtons().dotnetBuildButton.get());
assertDotNetStepIsCorrectlyRendered();
- //// Analysis step: Maven
+ // Analysis step: Maven
await user.click(getTutorialBuildButtons().mavenBuildButton.get());
assertMavenStepIsCorrectlyRendered();
- //// Analysis step: Gradle
+ // Analysis step: Gradle
await user.click(getTutorialBuildButtons().gradleBuildButton.get());
assertGradleStepIsCorrectlyRendered();
- //// Analysis step: C Family
- await user.click(getTutorialBuildButtons().cFamilyBuildButton.get());
-
- // OS's
+ // Analysis step: C Family
+ await user.click(getTutorialBuildButtons().cppBuildButton.get());
+ // Default: Automatic configuration
+ // expect linux/win/macos buttons not to be present
+ expect(getTutorialBuildButtons().linuxButton.query()).not.toBeInTheDocument();
+ expect(getTutorialBuildButtons().windowsButton.query()).not.toBeInTheDocument();
+ expect(getTutorialBuildButtons().macosButton.query()).not.toBeInTheDocument();
+ assertAutomaticCppStepIsCorrectlyRendered();
+
+ // Switch to manual configuration
+ await user.click(getTutorialBuildButtons().autoConfigManual.get());
await user.click(getTutorialBuildButtons().linuxButton.get());
- assertCFamilyStepIsCorrectlyRendered(OSs.Linux);
-
+ assertManualCppStepIsCorrectlyRendered(OSs.Linux);
await user.click(getTutorialBuildButtons().windowsButton.get());
- assertCFamilyStepIsCorrectlyRendered(OSs.Windows);
+ assertObjCStepIsCorrectlyRendered(OSs.Windows);
+ await user.click(getTutorialBuildButtons().macosButton.get());
+ assertObjCStepIsCorrectlyRendered(OSs.MacOS);
+ // Analysis step: C Family
+ await user.click(getTutorialBuildButtons().objCBuildButton.get());
+ await user.click(getTutorialBuildButtons().linuxButton.get());
+ assertObjCStepIsCorrectlyRendered(OSs.Linux);
+ await user.click(getTutorialBuildButtons().windowsButton.get());
+ assertObjCStepIsCorrectlyRendered(OSs.Windows);
await user.click(getTutorialBuildButtons().macosButton.get());
- assertCFamilyStepIsCorrectlyRendered(OSs.MacOS);
+ assertObjCStepIsCorrectlyRendered(OSs.MacOS);
- //// Analysis step: Other
+ // Analysis step: Other
await user.click(getTutorialBuildButtons().otherBuildButton.get());
assertOtherStepIsCorrectlyRendered();
- //// Finish tutorial
+ // Finish tutorial
assertFinishStepIsCorrectlyRendered();
});
@@ -110,7 +124,7 @@ it('should not offer CFamily analysis if the language is not available', () => {
renderAzurePipelinesTutorial(undefined, { languages: {} });
expect(getTutorialBuildButtons().dotnetBuildButton.get()).toBeInTheDocument();
- expect(getTutorialBuildButtons().cFamilyBuildButton.query()).not.toBeInTheDocument();
+ expect(getTutorialBuildButtons().cppBuildButton.query()).not.toBeInTheDocument();
});
function assertDefaultStepIsCorrectlyRendered() {
@@ -151,14 +165,29 @@ function assertGradleStepIsCorrectlyRendered() {
expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('gradle, copy additional properties');
}
-function assertCFamilyStepIsCorrectlyRendered(os: string) {
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(`cfamily ${os}, copy shell script`);
+function assertObjCStepIsCorrectlyRendered(os: string) {
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(`objectivec ${os}, copy shell script`);
+ expect(getCopyToClipboardValue(1, 'Copy to clipboard')).toBe('foo');
+ expect(getCopyToClipboardValue(2, 'Copy to clipboard')).toMatchSnapshot(
+ `objectivec ${os}, copy additional properties`,
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ `objectivec ${os}, copy build-wrapper command`,
+ );
+}
+
+function assertAutomaticCppStepIsCorrectlyRendered() {
+ assertOtherStepIsCorrectlyRendered();
+}
+
+function assertManualCppStepIsCorrectlyRendered(os: string) {
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(`manual-cpp ${os}, copy shell script`);
expect(getCopyToClipboardValue(1, 'Copy to clipboard')).toBe('foo');
expect(getCopyToClipboardValue(2, 'Copy to clipboard')).toMatchSnapshot(
- `cfamily ${os}, copy additional properties`,
+ `manual-cpp ${os}, copy additional properties`,
);
expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
- `cfamily ${os}, copy build-wrapper command`,
+ `manual-cpp ${os}, copy build-wrapper command`,
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap
index bb473275129..3e7f2240b79 100644
--- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/AzurePipelinesTutorial-it.tsx.snap
@@ -1,46 +1,73 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should render correctly and allow token generation: cfamily linux, copy additional properties 1`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
+exports[`should render correctly and allow token generation: gradle, copy additional properties 1`] = `
+"# Additional properties that will be passed to the scanner,
+# Put one key=value per line, example:
+# sonar.exclusions=**/*.bin
+sonar.projectKey=foo
+sonar.projectName=MyProject
+"
+`;
+
+exports[`should render correctly and allow token generation: manual-cpp linux, copy additional properties 1`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
-exports[`should render correctly and allow token generation: cfamily linux, copy build-wrapper command 1`] = `"./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your build command here>"`;
+exports[`should render correctly and allow token generation: manual-cpp linux, copy build-wrapper command 1`] = `"./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your build command here>"`;
-exports[`should render correctly and allow token generation: cfamily linux, copy shell script 1`] = `
+exports[`should render correctly and allow token generation: manual-cpp linux, copy shell script 1`] = `
"curl 'http://localhost/static/cpp/build-wrapper-linux-x86.zip' --output build-wrapper.zip
unzip build-wrapper.zip"
`;
-exports[`should render correctly and allow token generation: cfamily mac, copy additional properties 1`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
+exports[`should render correctly and allow token generation: maven, copy additional properties 1`] = `
+"# Additional properties that will be passed to the scanner,
+# Put one key=value per line, example:
+# sonar.exclusions=**/*.bin
+sonar.projectKey=foo
+sonar.projectName=MyProject
+"
+`;
+
+exports[`should render correctly and allow token generation: objectivec linux, copy additional properties 1`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
+
+exports[`should render correctly and allow token generation: objectivec linux, copy build-wrapper command 1`] = `"./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your build command here>"`;
+
+exports[`should render correctly and allow token generation: objectivec linux, copy shell script 1`] = `
+"curl 'http://localhost/static/cpp/build-wrapper-linux-x86.zip' --output build-wrapper.zip
+unzip build-wrapper.zip"
+`;
+
+exports[`should render correctly and allow token generation: objectivec mac, copy additional properties 1`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
+
+exports[`should render correctly and allow token generation: objectivec mac, copy additional properties 2`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
-exports[`should render correctly and allow token generation: cfamily mac, copy build-wrapper command 1`] = `"./build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your build command here>"`;
+exports[`should render correctly and allow token generation: objectivec mac, copy build-wrapper command 1`] = `"./build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your build command here>"`;
-exports[`should render correctly and allow token generation: cfamily mac, copy shell script 1`] = `
+exports[`should render correctly and allow token generation: objectivec mac, copy build-wrapper command 2`] = `"./build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your build command here>"`;
+
+exports[`should render correctly and allow token generation: objectivec mac, copy shell script 1`] = `
"curl 'http://localhost/static/cpp/build-wrapper-macosx-x86.zip' --output build-wrapper.zip
unzip build-wrapper.zip"
`;
-exports[`should render correctly and allow token generation: cfamily win, copy additional properties 1`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
+exports[`should render correctly and allow token generation: objectivec mac, copy shell script 2`] = `
+"curl 'http://localhost/static/cpp/build-wrapper-macosx-x86.zip' --output build-wrapper.zip
+unzip build-wrapper.zip"
+`;
+
+exports[`should render correctly and allow token generation: objectivec win, copy additional properties 1`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
+
+exports[`should render correctly and allow token generation: objectivec win, copy additional properties 2`] = `"sonar.cfamily.compile-commands=bw-output/compile_commands.json"`;
+
+exports[`should render correctly and allow token generation: objectivec win, copy build-wrapper command 1`] = `"build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir bw-output <your build command here>"`;
-exports[`should render correctly and allow token generation: cfamily win, copy build-wrapper command 1`] = `"build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir bw-output <your build command here>"`;
+exports[`should render correctly and allow token generation: objectivec win, copy build-wrapper command 2`] = `"build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir bw-output <your build command here>"`;
-exports[`should render correctly and allow token generation: cfamily win, copy shell script 1`] = `
+exports[`should render correctly and allow token generation: objectivec win, copy shell script 1`] = `
"Invoke-WebRequest -Uri 'http://localhost/static/cpp/build-wrapper-win-x86.zip' -OutFile 'build-wrapper.zip'
Expand-Archive -Path 'build-wrapper.zip' -DestinationPath '.'"
`;
-exports[`should render correctly and allow token generation: gradle, copy additional properties 1`] = `
-"# Additional properties that will be passed to the scanner,
-# Put one key=value per line, example:
-# sonar.exclusions=**/*.bin
-sonar.projectKey=foo
-sonar.projectName=MyProject
-"
-`;
-
-exports[`should render correctly and allow token generation: maven, copy additional properties 1`] = `
-"# Additional properties that will be passed to the scanner,
-# Put one key=value per line, example:
-# sonar.exclusions=**/*.bin
-sonar.projectKey=foo
-sonar.projectName=MyProject
-"
+exports[`should render correctly and allow token generation: objectivec win, copy shell script 2`] = `
+"Invoke-WebRequest -Uri 'http://localhost/static/cpp/build-wrapper-win-x86.zip' -OutFile 'build-wrapper.zip'
+Expand-Archive -Path 'build-wrapper.zip' -DestinationPath '.'"
`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx
index d87b5abfcbe..32d77e59a03 100644
--- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { BuildTools } from '../../types';
+import { BuildTools, TutorialConfig } from '../../types';
import ClangGCC from './ClangGCC';
import DotNet from './DotNet';
import JavaGradle from './JavaGradle';
@@ -26,24 +26,19 @@ import JavaMaven from './JavaMaven';
import Other from './Other';
export interface AnalysisCommandProps {
- buildTool?: BuildTools;
- onStepValidationChange: (isValid: boolean) => void;
+ config: TutorialConfig;
projectKey: string;
projectName: string;
}
export default function AnalysisCommand(props: AnalysisCommandProps) {
- const { buildTool, onStepValidationChange, projectKey, projectName } = props;
-
- React.useEffect(() => {
- if (buildTool && buildTool !== BuildTools.CFamily) {
- onStepValidationChange(true);
- }
- }, [buildTool, onStepValidationChange]);
+ const { config, projectKey, projectName } = props;
+ const { buildTool } = config;
if (!buildTool) {
return null;
}
+
switch (buildTool) {
case BuildTools.Maven:
return <JavaMaven projectKey={projectKey} projectName={projectName} />;
@@ -54,10 +49,9 @@ export default function AnalysisCommand(props: AnalysisCommandProps) {
case BuildTools.DotNet:
return <DotNet projectKey={projectKey} />;
- case BuildTools.CFamily:
- return (
- <ClangGCC onStepValidationChange={props.onStepValidationChange} projectKey={projectKey} />
- );
+ case BuildTools.Cpp:
+ case BuildTools.ObjectiveC:
+ return <ClangGCC config={config} projectKey={projectKey} />;
case BuildTools.Other:
return <Other projectKey={projectKey} />;
diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx
index 01f1ed48956..eaab6c03151 100644
--- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx
@@ -31,13 +31,14 @@ import { CompilationInfo } from '../../components/CompilationInfo';
import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories';
import RenderOptions from '../../components/RenderOptions';
import SentenceWithHighlights from '../../components/SentenceWithHighlights';
-import { BuildTools, OSs, TutorialModes } from '../../types';
+import { AutoConfig, BuildTools, OSs, TutorialConfig, TutorialModes } from '../../types';
import AlertClassicEditor from './AlertClassicEditor';
+import Other from './Other';
import PrepareAnalysisCommand, { PrepareType } from './PrepareAnalysisCommand';
import PublishSteps from './PublishSteps';
export interface ClangGCCProps {
- onStepValidationChange: (isValid: boolean) => void;
+ config: TutorialConfig;
projectKey: string;
}
@@ -50,8 +51,8 @@ type OsConstant = {
};
export default function ClangGCC(props: ClangGCCProps) {
- const { projectKey, onStepValidationChange } = props;
- const [os, setOs] = React.useState<OSs | undefined>(OSs.Linux);
+ const { config, projectKey } = props;
+ const [os, setOs] = React.useState<OSs>(OSs.Linux);
const host = getHostUrl();
const codeSnippetDownload: OsConstant = {
@@ -81,17 +82,9 @@ unzip build-wrapper.zip`,
},
};
- React.useEffect(() => {
- if (os) {
- onStepValidationChange(true);
- } else {
- onStepValidationChange(false);
- }
- }, [os, onStepValidationChange]);
-
- const handlOsChange = (value: OSs) => {
- setOs(value);
- };
+ if (config.buildTool === BuildTools.Cpp && config.autoConfig === AutoConfig.Automatic) {
+ return <Other projectKey={projectKey} />;
+ }
return (
<>
@@ -99,84 +92,80 @@ unzip build-wrapper.zip`,
<RenderOptions
label={translate('onboarding.tutorial.with.azure_pipelines.os')}
checked={os}
- onCheck={handlOsChange}
+ onCheck={(value: OSs) => setOs(value)}
optionLabelKey="onboarding.build.other.os"
options={Object.values(OSs)}
/>
- {os && (
- <>
- <GithubCFamilyExampleRepositories
- className="sw-mt-4 sw-w-abs-600"
- os={os}
- ci={TutorialModes.AzurePipelines}
+ <GithubCFamilyExampleRepositories
+ className="sw-mt-4 sw-w-abs-600"
+ os={os}
+ ci={TutorialModes.AzurePipelines}
+ />
+ <AlertClassicEditor />
+ <NumberedList className="sw-mt-4">
+ <NumberedListItem>
+ <SentenceWithHighlights
+ translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp"
+ highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare"
+ highlightKeys={['pipeline']}
/>
- <AlertClassicEditor />
- <NumberedList className="sw-mt-4">
- <NumberedListItem>
+ <UnorderedList ticks className="sw-ml-12 sw-mt-2">
+ <ListItem>
<SentenceWithHighlights
- translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp"
- highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare"
- highlightKeys={['pipeline']}
+ translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.script"
+ highlightPrefixKeys={codeSnippetDownload[os].highlightScriptKey}
+ highlightKeys={['task', 'inline']}
/>
- <UnorderedList ticks className="sw-ml-12 sw-mt-2">
- <ListItem>
- <SentenceWithHighlights
- translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.script"
- highlightPrefixKeys={codeSnippetDownload[os].highlightScriptKey}
- highlightKeys={['task', 'inline']}
- />
- <CodeSnippet className="sw-p-6" snippet={codeSnippetDownload[os].script} />
- </ListItem>
- </UnorderedList>
- </NumberedListItem>
+ <CodeSnippet className="sw-p-6" snippet={codeSnippetDownload[os].script} />
+ </ListItem>
+ </UnorderedList>
+ </NumberedListItem>
- <NumberedListItem>
- <SentenceWithHighlights
- translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.ccpp"
- highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare"
- highlightKeys={['task', 'before']}
- />
- <PrepareAnalysisCommand
- buildTool={BuildTools.CFamily}
- kind={PrepareType.StandAlone}
- projectKey={projectKey}
- />
- </NumberedListItem>
+ <NumberedListItem>
+ <SentenceWithHighlights
+ translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.ccpp"
+ highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare"
+ highlightKeys={['task', 'before']}
+ />
+ <PrepareAnalysisCommand
+ buildTool={BuildTools.Cpp}
+ kind={PrepareType.StandAlone}
+ projectKey={projectKey}
+ />
+ </NumberedListItem>
- <NumberedListItem>
+ <NumberedListItem>
+ <SentenceWithHighlights
+ translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build.ccpp"
+ highlightKeys={['task']}
+ />
+ <UnorderedList className="sw-mt-2">
+ <ListItem>
<SentenceWithHighlights
- translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build.ccpp"
- highlightKeys={['task']}
+ translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_script.ccpp"
+ highlightKeys={['build_wrapper']}
/>
- <UnorderedList className="sw-mt-2">
- <ListItem>
- <SentenceWithHighlights
- translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_script.ccpp"
- highlightKeys={['build_wrapper']}
- />
- <CodeSnippet
- className="sw-p-6"
- isOneLine
- snippet={codeSnippetDownload[os].scriptBuild}
- />
- <CompilationInfo />
- </ListItem>
- </UnorderedList>
- </NumberedListItem>
-
- <NumberedListItem>
- <SentenceWithHighlights
- translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.ccpp"
- highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run"
- highlightKeys={['task', 'after']}
+ <CodeSnippet
+ className="sw-p-6"
+ isOneLine
+ snippet={codeSnippetDownload[os].scriptBuild}
/>
- </NumberedListItem>
+ <CompilationInfo />
+ </ListItem>
+ </UnorderedList>
+ </NumberedListItem>
+
+ <NumberedListItem>
+ <SentenceWithHighlights
+ translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.ccpp"
+ highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run"
+ highlightKeys={['task', 'after']}
+ />
+ </NumberedListItem>
- <PublishSteps />
- </NumberedList>
- </>
- )}
+ <PublishSteps />
+ </NumberedList>
</>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx
index f9eb7b633dd..2f484e85a68 100644
--- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx
@@ -24,6 +24,7 @@ import { translate } from '../../../../helpers/l10n';
import { InlineSnippet } from '../../components/InlineSnippet';
import SentenceWithHighlights from '../../components/SentenceWithHighlights';
import { BuildTools } from '../../types';
+import { isCFamily } from '../../utils';
export enum PrepareType {
JavaMavenGradle,
@@ -118,7 +119,7 @@ sonar.projectName=${projectName}
/>
</span>
</ListItem>
- {buildTool === BuildTools.CFamily && (
+ {isCFamily(buildTool) && (
<ListItem>
<span className="sw-flex sw-items-center sw-flex-wrap">
<FormattedMessage
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/AnalysisCommand.tsx
index fbcc35f2633..66bf5fa08fd 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/AnalysisCommand.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/AnalysisCommand.tsx
@@ -26,7 +26,8 @@ import { Feature } from '../../../types/features';
import { Component } from '../../../types/types';
import { CompilationInfo } from '../components/CompilationInfo';
import CreateYmlFile from '../components/CreateYmlFile';
-import { BuildTools } from '../types';
+import { BuildTools, TutorialConfig } from '../types';
+import { isCFamily } from '../utils';
import { PreambuleYaml } from './PreambuleYaml';
import cFamilyExample from './commands/CFamily';
import dotNetExample from './commands/DotNet';
@@ -35,42 +36,49 @@ import mavenExample from './commands/Maven';
import othersExample from './commands/Others';
export interface AnalysisCommandProps extends WithAvailableFeaturesProps {
- buildTool: BuildTools;
component: Component;
+ config: TutorialConfig;
mainBranchName: string;
}
-const YamlTemplate: Dictionary<
- (
- branchesEnabled?: boolean,
- mainBranchName?: string,
- projectKey?: string,
- projectName?: string,
- ) => string
-> = {
+export type BuildToolExampleBuilder = (data: {
+ branchesEnabled?: boolean;
+ config: TutorialConfig;
+ mainBranchName?: string;
+ projectKey?: string;
+ projectName?: string;
+}) => string;
+
+const YamlTemplate: Dictionary<BuildToolExampleBuilder> = {
[BuildTools.Gradle]: gradleExample,
[BuildTools.Maven]: mavenExample,
[BuildTools.DotNet]: dotNetExample,
- [BuildTools.CFamily]: cFamilyExample,
+ [BuildTools.Cpp]: cFamilyExample,
+ [BuildTools.ObjectiveC]: cFamilyExample,
[BuildTools.Other]: othersExample,
};
export function AnalysisCommand(props: AnalysisCommandProps) {
- const { buildTool, mainBranchName, component } = props;
- const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
+ const { config, mainBranchName, component } = props;
+ const branchesEnabled = props.hasFeature(Feature.BranchSupport);
+
+ if (!config.buildTool) {
+ return null;
+ }
- const yamlTemplate = YamlTemplate[buildTool](
- branchSupportEnabled,
+ const yamlTemplate = YamlTemplate[config.buildTool]({
+ config,
+ branchesEnabled,
mainBranchName,
- component.key,
- component.name,
- );
+ projectKey: component.key,
+ projectName: component.name,
+ });
return (
<>
- <PreambuleYaml buildTool={buildTool} component={component} />
+ <PreambuleYaml buildTool={config.buildTool} component={component} />
<CreateYmlFile yamlFileName="bitbucket-pipelines.yml" yamlTemplate={yamlTemplate} />
- {buildTool === BuildTools.CFamily && <CompilationInfo />}
+ {isCFamily(config.buildTool) && <CompilationInfo />}
</>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/BitbucketPipelinesTutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/BitbucketPipelinesTutorial.tsx
index 95dbda5bdfe..21e6173ac78 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/BitbucketPipelinesTutorial.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/BitbucketPipelinesTutorial.tsx
@@ -26,7 +26,8 @@ import { LoggedInUser } from '../../../types/users';
import AllSet from '../components/AllSet';
import GithubCFamilyExampleRepositories from '../components/GithubCFamilyExampleRepositories';
import YamlFileStep from '../components/YamlFileStep';
-import { BuildTools, TutorialModes } from '../types';
+import { TutorialConfig, TutorialModes } from '../types';
+import { shouldShowGithubCFamilyExampleRepositories } from '../utils';
import AnalysisCommand from './AnalysisCommand';
import RepositoryVariables from './RepositoryVariables';
@@ -49,7 +50,13 @@ export default function BitbucketPipelinesTutorial(props: BitbucketPipelinesTuto
const { almBinding, baseUrl, currentUser, component, willRefreshAutomatically, mainBranchName } =
props;
- const [done, setDone] = React.useState<boolean>(false);
+ const [config, setConfig] = React.useState<TutorialConfig>({});
+ const [done, setDone] = React.useState(false);
+
+ React.useEffect(() => {
+ setDone(Boolean(config.buildTool));
+ }, [config.buildTool]);
+
return (
<>
<Title>{translate('onboarding.tutorial.with.bitbucket_ci.title')}</Title>
@@ -66,17 +73,17 @@ export default function BitbucketPipelinesTutorial(props: BitbucketPipelinesTuto
/>
</TutorialStep>
<TutorialStep title={translate('onboarding.tutorial.with.bitbucket_pipelines.yaml.title')}>
- <YamlFileStep setDone={setDone}>
- {(buildTool) => (
+ <YamlFileStep config={config} setConfig={setConfig} ci={TutorialModes.BitbucketPipelines}>
+ {(config) => (
<>
- {buildTool === BuildTools.CFamily && (
+ {shouldShowGithubCFamilyExampleRepositories(config) && (
<GithubCFamilyExampleRepositories
className="sw-my-4 sw-w-abs-600"
ci={TutorialModes.BitbucketPipelines}
/>
)}
<AnalysisCommand
- buildTool={buildTool}
+ config={config}
component={component}
mainBranchName={mainBranchName}
/>
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/PreambuleYaml.tsx b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/PreambuleYaml.tsx
index 1df171e33a0..83222ccbe61 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/PreambuleYaml.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/PreambuleYaml.tsx
@@ -33,7 +33,8 @@ export function PreambuleYaml(props: PreambuleYamlProps) {
switch (buildTool) {
case BuildTools.Gradle:
return <GradleBuild component={component} />;
- case BuildTools.CFamily:
+ case BuildTools.Cpp:
+ case BuildTools.ObjectiveC:
case BuildTools.Other:
return <DefaultProjectKey component={component} />;
default:
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/BitbucketPipelinesTutorial-it.tsx b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/BitbucketPipelinesTutorial-it.tsx
index 13b3640f87b..76f46695e44 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/BitbucketPipelinesTutorial-it.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/BitbucketPipelinesTutorial-it.tsx
@@ -86,15 +86,41 @@ it('should follow and complete all steps', async () => {
await user.click(ui.dotnetBuildButton.get());
expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('.NET: bitbucket-pipelines.yml');
- // CFamily
- await user.click(ui.cFamilyBuildButton.get());
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('CFamily: sonar-project.properties');
- expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('CFamily: bitbucket-pipelines.yml');
+ // Cpp
+ await user.click(ui.cppBuildButton.get());
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: sonar-project.properties',
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: bitbucket-pipelines.yml',
+ );
+
+ // Cpp (manual)
+ await user.click(ui.autoConfigManual.get());
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'C++ (manual) and Objective-C: sonar-project.properties',
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'C++ (manual) and Objective-C: bitbucket-pipelines.yml',
+ );
+
+ // Objective-C
+ await user.click(ui.objCBuildButton.get());
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'C++ (manual) and Objective-C: bitbucket-pipelines.yml',
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'C++ (manual) and Objective-C: sonar-project.properties',
+ );
// Other
await user.click(ui.otherBuildButton.get());
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('Other: sonar-project.properties');
- expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('Other: .github/workflows/build.yml');
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: sonar-project.properties',
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: .github/workflows/build.yml',
+ );
expect(ui.allSetSentence.get()).toBeInTheDocument();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/__snapshots__/BitbucketPipelinesTutorial-it.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/__snapshots__/BitbucketPipelinesTutorial-it.tsx.snap
index 827109d5f21..39b68ed6fdd 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/__snapshots__/BitbucketPipelinesTutorial-it.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/__snapshots__/BitbucketPipelinesTutorial-it.tsx.snap
@@ -31,7 +31,69 @@ pipelines:
- step: *build-step"
`;
-exports[`should follow and complete all steps: CFamily: bitbucket-pipelines.yml 1`] = `
+exports[`should follow and complete all steps: C++ (automatic) and other: .github/workflows/build.yml 1`] = `
+"image: maven:3.3.9
+
+definitions:
+ steps:
+ - step: &build-step
+ name: SonarQube analysis
+ script:
+ - pipe: sonarsource/sonarqube-scan:2.0.1
+ variables:
+ SONAR_HOST_URL: \${SONAR_HOST_URL} # Get the value from the repository/workspace variable.
+ SONAR_TOKEN: \${SONAR_TOKEN} # Get the value from the repository/workspace variable. You shouldn't set secret in clear text here.
+ caches:
+ sonar: ~/.sonar
+
+clone:
+ depth: full
+
+pipelines:
+ branches:
+ '{main}':
+ - step: *build-step
+
+ pull-requests:
+ '**':
+ - step: *build-step
+"
+`;
+
+exports[`should follow and complete all steps: C++ (automatic) and other: bitbucket-pipelines.yml 1`] = `
+"image: maven:3.3.9
+
+definitions:
+ steps:
+ - step: &build-step
+ name: SonarQube analysis
+ script:
+ - pipe: sonarsource/sonarqube-scan:2.0.1
+ variables:
+ SONAR_HOST_URL: \${SONAR_HOST_URL} # Get the value from the repository/workspace variable.
+ SONAR_TOKEN: \${SONAR_TOKEN} # Get the value from the repository/workspace variable. You shouldn't set secret in clear text here.
+ caches:
+ sonar: ~/.sonar
+
+clone:
+ depth: full
+
+pipelines:
+ branches:
+ '{main}':
+ - step: *build-step
+
+ pull-requests:
+ '**':
+ - step: *build-step
+"
+`;
+
+exports[`should follow and complete all steps: C++ (automatic) and other: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
+
+exports[`should follow and complete all steps: C++ (automatic) and other: sonar-project.properties 2`] = `"sonar.projectKey=my-project"`;
+
+exports[`should follow and complete all steps: C++ (manual) and Objective-C: bitbucket-pipelines.yml 1`] = `
"image: <image ready for your build toolchain>
definitions:
@@ -65,7 +127,43 @@ pipelines:
- step: *build-step"
`;
-exports[`should follow and complete all steps: CFamily: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
+exports[`should follow and complete all steps: C++ (manual) and Objective-C: bitbucket-pipelines.yml 2`] = `"sonar.projectKey=my-project"`;
+
+exports[`should follow and complete all steps: C++ (manual) and Objective-C: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
+
+exports[`should follow and complete all steps: C++ (manual) and Objective-C: sonar-project.properties 2`] = `
+"image: <image ready for your build toolchain>
+
+definitions:
+ steps:
+ - step: &build-step
+ name: Build the project, and run the SonarQube analysis
+ script:
+ - export SONAR_SCANNER_VERSION=5.0.1.3006
+ - 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/
+ - curl -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/
+ - export PATH="$PATH:$HOME/.sonar/sonar-scanner-\${SONAR_SCANNER_VERSION}-linux/bin"
+ - <any step required before running your build, like ./configure>
+ - $HOME/.sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your clean build command>
+ - sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json
+ caches:
+ sonar: ~/.sonar
+
+clone:
+ depth: full
+
+pipelines:
+ branches:
+ '{main}':
+ - step: *build-step
+
+ pull-requests:
+ '**':
+ - step: *build-step"
+`;
exports[`should follow and complete all steps: Gradle: bitbucket-pipelines.yml 1`] = `
"image: eclipse-temurin:17
@@ -149,37 +247,6 @@ pipelines:
- step: *build-step"
`;
-exports[`should follow and complete all steps: Other: .github/workflows/build.yml 1`] = `
-"image: maven:3.3.9
-
-definitions:
- steps:
- - step: &build-step
- name: SonarQube analysis
- script:
- - pipe: sonarsource/sonarqube-scan:2.0.1
- variables:
- SONAR_HOST_URL: \${SONAR_HOST_URL} # Get the value from the repository/workspace variable.
- SONAR_TOKEN: \${SONAR_TOKEN} # Get the value from the repository/workspace variable. You shouldn't set secret in clear text here.
- caches:
- sonar: ~/.sonar
-
-clone:
- depth: full
-
-pipelines:
- branches:
- '{main}':
- - step: *build-step
-
- pull-requests:
- '**':
- - step: *build-step
-"
-`;
-
-exports[`should follow and complete all steps: Other: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
-
exports[`should follow and complete all steps: sonar token key 1`] = `"SONAR_TOKEN"`;
exports[`should follow and complete all steps: sonarqube host url key 1`] = `"SONAR_HOST_URL"`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/CFamily.ts b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/CFamily.ts
index ab6adff8e9e..2f694274649 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/CFamily.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/CFamily.ts
@@ -17,7 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-export default function cFamilyExample(branchesEnabled: boolean, mainBranchName: string) {
+import { AutoConfig, BuildTools } from '../../types';
+import { BuildToolExampleBuilder } from '../AnalysisCommand';
+import othersExample from './Others';
+
+const cFamilyExample: BuildToolExampleBuilder = ({ config, branchesEnabled, mainBranchName }) => {
+ if (config.buildTool === BuildTools.Cpp && config.autoConfig === AutoConfig.Automatic) {
+ return othersExample({ config, branchesEnabled, mainBranchName });
+ }
return `image: <image ready for your build toolchain>
definitions:
@@ -53,4 +60,6 @@ ${
- step: *build-step`
: ''
}`;
-}
+};
+
+export default cFamilyExample;
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/DotNet.ts b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/DotNet.ts
index 621cb328358..df12f554254 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/DotNet.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/DotNet.ts
@@ -17,11 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-export default function dotNetExample(
- branchesEnabled: boolean,
- mainBranchName: string,
- projectKey: string,
-) {
+import { BuildToolExampleBuilder } from '../AnalysisCommand';
+
+const dotNetExample: BuildToolExampleBuilder = ({
+ branchesEnabled,
+ mainBranchName,
+ projectKey,
+}) => {
return `image: mcr.microsoft.com/dotnet/sdk:7.0
definitions:
@@ -54,4 +56,6 @@ ${
- step: *build-step`
: ''
}`;
-}
+};
+
+export default dotNetExample;
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Gradle.ts b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Gradle.ts
index 4d96925a69a..45cb5b262e8 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Gradle.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Gradle.ts
@@ -17,7 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-export default function gradleExample(branchesEnabled: boolean, mainBranchName: string) {
+import { BuildToolExampleBuilder } from '../AnalysisCommand';
+
+const gradleExample: BuildToolExampleBuilder = ({ branchesEnabled, mainBranchName }) => {
return `image: eclipse-temurin:17
definitions:
@@ -47,4 +49,6 @@ ${
- step: *build-step`
: ''
}`;
-}
+};
+
+export default gradleExample;
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Maven.ts b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Maven.ts
index cc32ef6249b..6a53708be3d 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Maven.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Maven.ts
@@ -17,12 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-export default function mavenExample(
- branchesEnabled: boolean,
- mainBranchName: string,
- projectKey: string,
- projectName: string,
-) {
+import { BuildToolExampleBuilder } from '../AnalysisCommand';
+
+const mavenExample: BuildToolExampleBuilder = ({
+ branchesEnabled,
+ mainBranchName,
+ projectKey,
+ projectName,
+}) => {
return `image: maven:3-eclipse-temurin-17
definitions:
@@ -52,4 +54,6 @@ ${
- step: *build-step`
: ''
}`;
-}
+};
+
+export default mavenExample;
diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Others.ts b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Others.ts
index 7ae93f05190..94c145180f7 100644
--- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Others.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/commands/Others.ts
@@ -17,7 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-export default function othersExample(branchesEnabled: boolean, mainBranchName: string) {
+import { BuildToolExampleBuilder } from '../AnalysisCommand';
+
+const othersExample: BuildToolExampleBuilder = ({ branchesEnabled, mainBranchName }) => {
return `image: maven:3.3.9
definitions:
@@ -48,4 +50,6 @@ ${
`
: ''
}`;
-}
+};
+
+export default othersExample;
diff --git a/server/sonar-web/src/main/js/components/tutorials/components/BuildConfigSelection.tsx b/server/sonar-web/src/main/js/components/tutorials/components/BuildConfigSelection.tsx
new file mode 100644
index 00000000000..9cfff92517a
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/tutorials/components/BuildConfigSelection.tsx
@@ -0,0 +1,84 @@
+/*
+ * 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 { FlagMessage } from 'design-system';
+import * as React from 'react';
+import { translate } from '../../../helpers/l10n';
+import { AutoConfig, BuildTools, TutorialConfig, TutorialModes } from '../types';
+import { getBuildToolOptions, isCFamily, supportsAutoConfig } from '../utils';
+import RenderOptions from './RenderOptions';
+
+export interface BuildConfigSelectionProps {
+ ci: TutorialModes;
+ config: TutorialConfig;
+ hideAutoConfig?: boolean;
+ onSetConfig(config: TutorialConfig): void;
+ supportCFamily: boolean;
+}
+
+export default function BuildConfigSelection(props: Readonly<BuildConfigSelectionProps>) {
+ const { ci, config, hideAutoConfig, supportCFamily, onSetConfig } = props;
+
+ function onSelectBuildTool(buildTool: BuildTools) {
+ const autoConfig = buildTool === BuildTools.Cpp ? AutoConfig.Automatic : undefined;
+ onSetConfig({ ...config, buildTool, autoConfig });
+ }
+
+ function onSelectAutoConfig(autoConfig: AutoConfig) {
+ onSetConfig({ ...config, autoConfig });
+ }
+
+ return (
+ <>
+ {translate('onboarding.build')}
+ <RenderOptions
+ label={translate('onboarding.build')}
+ checked={config.buildTool}
+ onCheck={onSelectBuildTool}
+ optionLabelKey="onboarding.build"
+ options={getBuildToolOptions(supportCFamily)}
+ />
+
+ {ci === TutorialModes.Jenkins && isCFamily(config.buildTool) && (
+ <FlagMessage variant="info" className="sw-mt-2 sw-w-abs-600">
+ {translate('onboarding.tutorial.with.jenkins.jenkinsfile.cfamilly.agent_setup')}
+ </FlagMessage>
+ )}
+
+ {!hideAutoConfig &&
+ config.buildTool &&
+ supportsAutoConfig(config.buildTool) &&
+ onSelectAutoConfig && (
+ <>
+ <div className="sw-mt-4">{translate('onboarding.build.cpp.autoconfig')}</div>
+ <RenderOptions
+ label="onboarding.build.cpp.autoconfig"
+ checked={config.autoConfig}
+ onCheck={onSelectAutoConfig}
+ optionLabelKey="onboarding.build.cpp.autoconfig"
+ options={[AutoConfig.Automatic, AutoConfig.Manual]}
+ />
+ <FlagMessage className="sw-mt-2 sw-w-abs-600" variant="info">
+ {translate(`onboarding.build.cpp.autoconfig.${config.autoConfig}.description`)}
+ </FlagMessage>
+ </>
+ )}
+ </>
+ );
+}
diff --git a/server/sonar-web/src/main/js/components/tutorials/components/RenderOptions.tsx b/server/sonar-web/src/main/js/components/tutorials/components/RenderOptions.tsx
index b972264dfc2..cb379b20db4 100644
--- a/server/sonar-web/src/main/js/components/tutorials/components/RenderOptions.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/components/RenderOptions.tsx
@@ -27,7 +27,6 @@ export interface RenderOptionsProps {
onCheck: (checked: string) => void;
optionLabelKey: string;
options: string[];
- setDone?: (doneStatus: boolean) => void;
titleLabelKey?: string;
}
@@ -35,15 +34,11 @@ export default function RenderOptions({
checked,
label,
onCheck,
- setDone,
optionLabelKey,
options,
titleLabelKey,
}: RenderOptionsProps) {
const onChange = (checked: string) => {
- if (setDone) {
- setDone(true);
- }
onCheck(checked);
};
diff --git a/server/sonar-web/src/main/js/components/tutorials/components/YamlFileStep.tsx b/server/sonar-web/src/main/js/components/tutorials/components/YamlFileStep.tsx
index fe16f855f8c..d1b01e6835a 100644
--- a/server/sonar-web/src/main/js/components/tutorials/components/YamlFileStep.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/components/YamlFileStep.tsx
@@ -19,42 +19,33 @@
*/
import { NumberedList, NumberedListItem } from 'design-system';
import * as React from 'react';
-import { translate } from '../../../helpers/l10n';
import { withCLanguageFeature } from '../../hoc/withCLanguageFeature';
-import RenderOptions from '../components/RenderOptions';
-import { BuildTools } from '../types';
+import { TutorialConfig, TutorialModes } from '../types';
+import BuildConfigSelection from './BuildConfigSelection';
export interface YamlFileStepProps {
- children?: (buildTool: BuildTools) => React.ReactElement<{}>;
+ children?: (config: TutorialConfig) => React.ReactElement<{}>;
+ ci: TutorialModes;
+ config: TutorialConfig;
hasCLanguageFeature: boolean;
- setDone?: (doneStatus: boolean) => void;
+ setConfig: (config: TutorialConfig) => void;
}
export function YamlFileStep(props: YamlFileStepProps) {
- const { children, hasCLanguageFeature } = props;
-
- const buildTools = [BuildTools.Maven, BuildTools.Gradle, BuildTools.DotNet];
- if (hasCLanguageFeature) {
- buildTools.push(BuildTools.CFamily);
- }
- buildTools.push(BuildTools.Other);
-
- const [buildToolSelected, setBuildToolSelected] = React.useState<BuildTools>();
+ const { ci, config, setConfig, children, hasCLanguageFeature } = props;
return (
<NumberedList>
<NumberedListItem>
- {translate('onboarding.build')}
- <RenderOptions
- label={translate('onboarding.build')}
- checked={buildToolSelected}
- onCheck={(value) => setBuildToolSelected(value as BuildTools)}
- options={buildTools}
- optionLabelKey="onboarding.build"
- setDone={props.setDone}
+ <BuildConfigSelection
+ ci={ci}
+ config={config}
+ onSetConfig={setConfig}
+ supportCFamily={hasCLanguageFeature}
/>
</NumberedListItem>
- {children && buildToolSelected && children(buildToolSelected)}
+
+ {children && config && children(config)}
</NumberedList>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx
index 81cc14e14af..f58f9d0bae9 100644
--- a/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx
@@ -23,7 +23,7 @@ import withAvailableFeatures, {
} from '../../../app/components/available-features/withAvailableFeatures';
import { Feature } from '../../../types/features';
import { Component } from '../../../types/types';
-import { BuildTools } from '../types';
+import { BuildTools, TutorialConfig } from '../types';
import CFamily from './commands/CFamily';
import DotNet from './commands/DotNet';
import Gradle from './commands/Gradle';
@@ -31,17 +31,17 @@ import JavaMaven from './commands/JavaMaven';
import Others from './commands/Others';
export interface AnalysisCommandProps extends WithAvailableFeaturesProps {
- buildTool: BuildTools;
component: Component;
+ config: TutorialConfig;
mainBranchName: string;
monorepo?: boolean;
}
export function AnalysisCommand(props: Readonly<AnalysisCommandProps>) {
- const { buildTool, component, mainBranchName, monorepo } = props;
+ const { config, component, mainBranchName, monorepo } = props;
const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
- switch (buildTool) {
+ switch (config.buildTool) {
case BuildTools.Maven:
return (
<JavaMaven
@@ -69,9 +69,11 @@ export function AnalysisCommand(props: Readonly<AnalysisCommandProps>) {
component={component}
/>
);
- case BuildTools.CFamily:
+ case BuildTools.Cpp:
+ case BuildTools.ObjectiveC:
return (
<CFamily
+ config={config}
branchesEnabled={branchSupportEnabled}
mainBranchName={mainBranchName}
monorepo={monorepo}
diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx
index bbb62cc3dfa..6bad8ad02d4 100644
--- a/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx
@@ -25,6 +25,7 @@ import { Component } from '../../../types/types';
import { LoggedInUser } from '../../../types/users';
import AllSet from '../components/AllSet';
import YamlFileStep from '../components/YamlFileStep';
+import { TutorialConfig, TutorialModes } from '../types';
import AnalysisCommand from './AnalysisCommand';
import SecretStep from './SecretStep';
@@ -39,7 +40,6 @@ export interface GitHubActionTutorialProps {
}
export default function GitHubActionTutorial(props: GitHubActionTutorialProps) {
- const [done, setDone] = React.useState<boolean>(false);
const {
almBinding,
baseUrl,
@@ -50,6 +50,13 @@ export default function GitHubActionTutorial(props: GitHubActionTutorialProps) {
willRefreshAutomatically,
} = props;
+ const [config, setConfig] = React.useState<TutorialConfig>({});
+ const [done, setDone] = React.useState<boolean>(false);
+
+ React.useEffect(() => {
+ setDone(Boolean(config.buildTool));
+ }, [config.buildTool]);
+
return (
<>
<Title>{translate('onboarding.tutorial.with.github_ci.title')}</Title>
@@ -66,10 +73,10 @@ export default function GitHubActionTutorial(props: GitHubActionTutorialProps) {
/>
</TutorialStep>
<TutorialStep title={translate('onboarding.tutorial.with.github_action.yaml.title')}>
- <YamlFileStep setDone={setDone}>
- {(buildTool) => (
+ <YamlFileStep config={config} setConfig={setConfig} ci={TutorialModes.GitHubActions}>
+ {(config) => (
<AnalysisCommand
- buildTool={buildTool}
+ config={config}
mainBranchName={mainBranchName}
component={component}
monorepo={monorepo}
diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/GithubActionTutorial-it.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/GithubActionTutorial-it.tsx
index 2ab91d22c1f..3f946d6a27b 100644
--- a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/GithubActionTutorial-it.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/GithubActionTutorial-it.tsx
@@ -84,26 +84,57 @@ it('should follow and complete all steps', async () => {
await user.click(ui.dotnetBuildButton.get());
expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('.NET: .github/workflows/build.yml');
- // CFamily
- await user.click(ui.cFamilyBuildButton.get());
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('CFamily: sonar-project.properties');
+ // Cpp
+ await user.click(ui.cppBuildButton.get());
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: sonar-project.properties',
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: .github/workflows/build.yml',
+ );
+
+ await user.click(ui.autoConfigManual.get());
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('C++: sonar-project.properties');
await user.click(ui.linuxButton.get());
expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
- 'CFamily Linux: .github/workflows/build.yml',
+ 'C++ Linux: .github/workflows/build.yml',
);
await user.click(ui.windowsButton.get());
expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
- 'CFamily Windows: .github/workflows/build.yml',
+ 'C++ Windows: .github/workflows/build.yml',
);
await user.click(ui.macosButton.get());
expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
- 'CFamily MacOS: .github/workflows/build.yml',
+ 'C++ MacOS: .github/workflows/build.yml',
+ );
+
+ // Objective-C
+ await user.click(ui.objCBuildButton.get());
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'Objective-C: sonar-project.properties',
+ );
+
+ await user.click(ui.linuxButton.get());
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'Objective-C Linux: .github/workflows/build.yml',
+ );
+ await user.click(ui.windowsButton.get());
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'Objective-C Windows: .github/workflows/build.yml',
+ );
+ await user.click(ui.macosButton.get());
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'Objective-C MacOS: .github/workflows/build.yml',
);
// Other
await user.click(ui.otherBuildButton.get());
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('Other: sonar-project.properties');
- expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('Other: .github/workflows/build.yml');
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: sonar-project.properties',
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'C++ (automatic) and other: .github/workflows/build.yml',
+ );
expect(ui.allSetSentence.get()).toBeInTheDocument();
});
diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/GithubActionTutorial-it.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/GithubActionTutorial-it.tsx.snap
index eb5e451a53d..3cc30b5bdf0 100644
--- a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/GithubActionTutorial-it.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/GithubActionTutorial-it.tsx.snap
@@ -50,7 +50,77 @@ jobs:
.\\.sonar\\scanner\\dotnet-sonarscanner end /d:sonar.token="\${{ secrets.SONAR_TOKEN }}""
`;
-exports[`should follow and complete all steps: CFamily Linux: .github/workflows/build.yml 1`] = `
+exports[`should follow and complete all steps: C++ (automatic) and other: .github/workflows/build.yml 1`] = `
+"name: Build
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+jobs:
+ build:
+ name: Build and analyze
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - uses: sonarsource/sonarqube-scan-action@master
+ env:
+ SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
+ SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}
+ # If you wish to fail your job when the Quality Gate is red, uncomment the
+ # following lines. This would typically be used to fail a deployment.
+ # We do not recommend to use this in a pull request. Prefer using pull request
+ # decoration instead.
+ # - uses: sonarsource/sonarqube-quality-gate-action@master
+ # timeout-minutes: 5
+ # env:
+ # SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}"
+`;
+
+exports[`should follow and complete all steps: C++ (automatic) and other: .github/workflows/build.yml 2`] = `
+"name: Build
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+jobs:
+ build:
+ name: Build and analyze
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - uses: sonarsource/sonarqube-scan-action@master
+ env:
+ SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
+ SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}
+ # If you wish to fail your job when the Quality Gate is red, uncomment the
+ # following lines. This would typically be used to fail a deployment.
+ # We do not recommend to use this in a pull request. Prefer using pull request
+ # decoration instead.
+ # - uses: sonarsource/sonarqube-quality-gate-action@master
+ # timeout-minutes: 5
+ # env:
+ # SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}"
+`;
+
+exports[`should follow and complete all steps: C++ (automatic) and other: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
+
+exports[`should follow and complete all steps: C++ (automatic) and other: sonar-project.properties 2`] = `"sonar.projectKey=my-project"`;
+
+exports[`should follow and complete all steps: C++ Linux: .github/workflows/build.yml 1`] = `
"name: Build
on:
@@ -86,7 +156,7 @@ jobs:
sonar-scanner --define sonar.cfamily.compile-commands="\${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json""
`;
-exports[`should follow and complete all steps: CFamily MacOS: .github/workflows/build.yml 1`] = `
+exports[`should follow and complete all steps: C++ MacOS: .github/workflows/build.yml 1`] = `
"name: Build
on:
@@ -122,7 +192,7 @@ jobs:
sonar-scanner --define sonar.cfamily.compile-commands="\${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json""
`;
-exports[`should follow and complete all steps: CFamily Windows: .github/workflows/build.yml 1`] = `
+exports[`should follow and complete all steps: C++ Windows: .github/workflows/build.yml 1`] = `
"name: Build
on:
@@ -158,7 +228,7 @@ jobs:
sonar-scanner --define sonar.cfamily.compile-commands="\${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json""
`;
-exports[`should follow and complete all steps: CFamily: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
+exports[`should follow and complete all steps: C++: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
exports[`should follow and complete all steps: Gradle: .github/workflows/build.yml 1`] = `
"name: Build
@@ -270,7 +340,7 @@ jobs:
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=my-project -Dsonar.projectName='MyProject'"
`;
-exports[`should follow and complete all steps: Other: .github/workflows/build.yml 1`] = `
+exports[`should follow and complete all steps: Objective-C Linux: .github/workflows/build.yml 1`] = `
"name: Build
on:
@@ -284,26 +354,101 @@ jobs:
build:
name: Build and analyze
runs-on: ubuntu-latest
-
+ env:
+ BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- - uses: sonarsource/sonarqube-scan-action@master
+ - name: Install sonar-scanner and build-wrapper
env:
+ SONAR_HOST_URL: \${{secrets.SONAR_HOST_URL}}
+ uses: SonarSource/sonarqube-github-c-cpp@v1
+ - name: Run build-wrapper
+ run: |
+ build-wrapper-linux-x86-64 --out-dir \${{ env.BUILD_WRAPPER_OUT_DIR }} <insert_your_clean_build_command>
+ - name: Run sonar-scanner
+ env:
+ GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
- SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}
- # If you wish to fail your job when the Quality Gate is red, uncomment the
- # following lines. This would typically be used to fail a deployment.
- # We do not recommend to use this in a pull request. Prefer using pull request
- # decoration instead.
- # - uses: sonarsource/sonarqube-quality-gate-action@master
- # timeout-minutes: 5
- # env:
- # SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}"
+ SONAR_HOST_URL: \${{secrets.SONAR_HOST_URL}}
+ run: |
+ sonar-scanner --define sonar.cfamily.compile-commands="\${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json""
+`;
+
+exports[`should follow and complete all steps: Objective-C MacOS: .github/workflows/build.yml 1`] = `
+"name: Build
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+jobs:
+ build:
+ name: Build and analyze
+ runs-on: macos-latest
+ env:
+ BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - name: Install sonar-scanner and build-wrapper
+ env:
+ SONAR_HOST_URL: \${{secrets.SONAR_HOST_URL}}
+ uses: SonarSource/sonarqube-github-c-cpp@v1
+ - name: Run build-wrapper
+ run: |
+ build-wrapper-macosx-x86 --out-dir \${{ env.BUILD_WRAPPER_OUT_DIR }} <insert_your_clean_build_command>
+ - name: Run sonar-scanner
+ env:
+ GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
+ SONAR_HOST_URL: \${{secrets.SONAR_HOST_URL}}
+ run: |
+ sonar-scanner --define sonar.cfamily.compile-commands="\${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json""
+`;
+
+exports[`should follow and complete all steps: Objective-C Windows: .github/workflows/build.yml 1`] = `
+"name: Build
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+jobs:
+ build:
+ name: Build and analyze
+ runs-on: windows-latest
+ env:
+ BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - name: Install sonar-scanner and build-wrapper
+ env:
+ SONAR_HOST_URL: \${{secrets.SONAR_HOST_URL}}
+ uses: SonarSource/sonarqube-github-c-cpp@v1
+ - name: Run build-wrapper
+ run: |
+ build-wrapper-win-x86-64 --out-dir \${{ env.BUILD_WRAPPER_OUT_DIR }} <insert_your_clean_build_command>
+ - name: Run sonar-scanner
+ env:
+ GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
+ SONAR_HOST_URL: \${{secrets.SONAR_HOST_URL}}
+ run: |
+ sonar-scanner --define sonar.cfamily.compile-commands="\${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json""
`;
-exports[`should follow and complete all steps: Other: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
+exports[`should follow and complete all steps: Objective-C: sonar-project.properties 1`] = `"sonar.projectKey=my-project"`;
exports[`should follow and complete all steps: sonar token key 1`] = `"SONAR_TOKEN"`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx
index 7c8195a939e..7c0513374fc 100644
--- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx
@@ -26,13 +26,15 @@ import CreateYmlFile from '../../components/CreateYmlFile';
import DefaultProjectKey from '../../components/DefaultProjectKey';
import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories';
import RenderOptions from '../../components/RenderOptions';
-import { OSs, TutorialModes } from '../../types';
+import { AutoConfig, BuildTools, OSs, TutorialConfig, TutorialModes } from '../../types';
import { generateGitHubActionsYaml } from '../utils';
import MonorepoDocLinkFallback from './MonorepoDocLinkFallback';
+import Others from './Others';
export interface CFamilyProps {
branchesEnabled?: boolean;
component: Component;
+ config: TutorialConfig;
mainBranchName: string;
monorepo?: boolean;
}
@@ -86,8 +88,12 @@ const STEPS = {
};
export default function CFamily(props: CFamilyProps) {
- const { component, branchesEnabled, mainBranchName, monorepo } = props;
- const [os, setOs] = React.useState<undefined | OSs>(OSs.Linux);
+ const { config, component, branchesEnabled, mainBranchName, monorepo } = props;
+ const [os, setOs] = React.useState<OSs>(OSs.Linux);
+
+ if (config.buildTool === BuildTools.Cpp && config.autoConfig === AutoConfig.Automatic) {
+ return <Others {...props} />;
+ }
const runsOn = {
[OSs.Linux]: 'ubuntu-latest',
@@ -106,33 +112,30 @@ export default function CFamily(props: CFamilyProps) {
optionLabelKey="onboarding.build.other.os"
options={Object.values(OSs)}
/>
- {os && (
- <GithubCFamilyExampleRepositories
- className="sw-mt-4 sw-w-abs-600"
- os={os}
- ci={TutorialModes.GitHubActions}
- />
- )}
+ <GithubCFamilyExampleRepositories
+ className="sw-mt-4 sw-w-abs-600"
+ os={os}
+ ci={TutorialModes.GitHubActions}
+ />
</NumberedListItem>
- {os &&
- (monorepo ? (
- <MonorepoDocLinkFallback />
- ) : (
- <>
- <CreateYmlFile
- yamlFileName=".github/workflows/build.yml"
- yamlTemplate={generateGitHubActionsYaml(
- mainBranchName,
- !!branchesEnabled,
- runsOn[os],
- STEPS[os],
- `env:
+ {monorepo ? (
+ <MonorepoDocLinkFallback />
+ ) : (
+ <>
+ <CreateYmlFile
+ yamlFileName=".github/workflows/build.yml"
+ yamlTemplate={generateGitHubActionsYaml(
+ mainBranchName,
+ !!branchesEnabled,
+ runsOn[os],
+ STEPS[os],
+ `env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed`,
- )}
- />
- <CompilationInfo />
- </>
- ))}
+ )}
+ />
+ <CompilationInfo />
+ </>
+ )}
</>
);
}
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 bebd34e2a4a..0b778d63c6e 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
@@ -44,6 +44,7 @@ export default function GitLabCITutorial(props: GitLabCITutorialProps) {
const { baseUrl, component, currentUser, willRefreshAutomatically } = props;
const [done, setDone] = React.useState<boolean>(false);
+
return (
<>
<Title>{translate('onboarding.tutorial.with.gitlab_ci.title')}</Title>
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 c9382b02125..fa9f0642e59 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
@@ -34,17 +34,18 @@ import { GRADLE_SCANNER_VERSION } from '../../../helpers/constants';
import { translate } from '../../../helpers/l10n';
import { Component } from '../../../types/types';
import { withCLanguageFeature } from '../../hoc/withCLanguageFeature';
+import BuildConfigSelection from '../components/BuildConfigSelection';
import GithubCFamilyExampleRepositories from '../components/GithubCFamilyExampleRepositories';
import GradleBuildSelection from '../components/GradleBuildSelection';
import { InlineSnippet } from '../components/InlineSnippet';
-import RenderOptions from '../components/RenderOptions';
-import { BuildTools, GradleBuildDSL, TutorialModes } from '../types';
+import { BuildTools, GradleBuildDSL, TutorialConfig, TutorialModes } from '../types';
+import { isCFamily } from '../utils';
import PipeCommand from './commands/PipeCommand';
export interface YmlFileStepProps extends WithAvailableFeaturesProps {
component: Component;
hasCLanguageFeature: boolean;
- setDone: (doneStatus: boolean) => void;
+ setDone: (done: boolean) => void;
}
const mavenSnippet = (key: string, name: string) => `<properties>
@@ -86,54 +87,55 @@ sonar.qualitygate.wait=true
`;
const snippetForBuildTool = {
- [BuildTools.CFamily]: otherSnippet,
+ [BuildTools.Cpp]: otherSnippet,
+ [BuildTools.ObjectiveC]: otherSnippet,
[BuildTools.Gradle]: gradleSnippet,
[BuildTools.Maven]: mavenSnippet,
[BuildTools.Other]: otherSnippet,
};
const filenameForBuildTool = {
- [BuildTools.CFamily]: 'sonar-project.properties',
+ [BuildTools.Cpp]: 'sonar-project.properties',
+ [BuildTools.ObjectiveC]: 'sonar-project.properties',
[BuildTools.Gradle]: GradleBuildDSL.Groovy,
[BuildTools.Maven]: 'pom.xml',
[BuildTools.Other]: 'sonar-project.properties',
};
const snippetLanguageForBuildTool = {
- [BuildTools.CFamily]: undefined,
+ [BuildTools.Cpp]: undefined,
+ [BuildTools.ObjectiveC]: undefined,
[BuildTools.Gradle]: undefined,
[BuildTools.Maven]: 'xml',
[BuildTools.Other]: undefined,
};
export function YmlFileStep(props: YmlFileStepProps) {
- const { component, hasCLanguageFeature } = props;
+ const { component, hasCLanguageFeature, setDone } = props;
- const [buildTool, setBuildTool] = React.useState<BuildTools>();
+ const [config, setConfig] = React.useState<TutorialConfig>({});
+ const { buildTool } = config;
- const buildTools = [BuildTools.Maven, BuildTools.Gradle, BuildTools.DotNet];
-
- if (hasCLanguageFeature) {
- buildTools.push(BuildTools.CFamily);
+ function onSetConfig(config: TutorialConfig) {
+ setConfig(config);
}
- buildTools.push(BuildTools.Other);
+ React.useEffect(() => {
+ setDone(Boolean(config.buildTool));
+ }, [config.buildTool, setDone]);
const renderForm = () => (
<NumberedList>
<NumberedListItem>
- {translate('onboarding.build')}
-
- <RenderOptions
- checked={buildTool}
- label={translate('onboarding.build')}
- onCheck={setBuildTool as (key: string) => void}
- optionLabelKey="onboarding.build"
- options={buildTools}
- setDone={props.setDone}
+ <BuildConfigSelection
+ ci={TutorialModes.GitLabCI}
+ config={config}
+ supportCFamily={hasCLanguageFeature}
+ hideAutoConfig
+ onSetConfig={onSetConfig}
/>
- {buildTool === BuildTools.CFamily && (
+ {isCFamily(config.buildTool) && (
<GithubCFamilyExampleRepositories
ci={TutorialModes.GitLabCI}
className="sw-my-4 sw-w-abs-600"
@@ -142,7 +144,8 @@ export function YmlFileStep(props: YmlFileStepProps) {
</NumberedListItem>
{buildTool !== undefined &&
- buildTool !== BuildTools.CFamily &&
+ buildTool !== BuildTools.Cpp &&
+ buildTool !== BuildTools.ObjectiveC &&
buildTool !== BuildTools.DotNet && (
<NumberedListItem>
<FormattedMessage
@@ -201,7 +204,7 @@ export function YmlFileStep(props: YmlFileStepProps) {
{buildTool && (
<>
- {buildTool !== BuildTools.CFamily && (
+ {buildTool !== BuildTools.Cpp && buildTool !== BuildTools.ObjectiveC && (
<NumberedListItem>
<FormattedMessage
defaultMessage={translate('onboarding.tutorial.with.gitlab_ci.yaml.description')}
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 a0c857a20e0..5e092e4b2ce 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
@@ -22,7 +22,7 @@ import * as React from 'react';
import { BuildTools } from '../../types';
export interface PipeCommandProps {
- buildTool: Exclude<BuildTools, BuildTools.CFamily>;
+ buildTool: Exclude<BuildTools, BuildTools.Cpp | BuildTools.ObjectiveC>;
projectKey: string;
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx
index 4090603fe7c..87ca0994688 100644
--- a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx
@@ -17,90 +17,71 @@
* 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, NumberedList, NumberedListItem, TutorialStep } from 'design-system';
+import { NumberedList, NumberedListItem, TutorialStep } from 'design-system';
import * as React from 'react';
import { translate } from '../../../helpers/l10n';
import { Component } from '../../../types/types';
import { withCLanguageFeature } from '../../hoc/withCLanguageFeature';
-import RenderOptions from '../components/RenderOptions';
-import { BuildTools } from '../types';
-import CFamilly from './buildtool-steps/CFamilly';
+import BuildConfigSelection from '../components/BuildConfigSelection';
+import { BuildTools, TutorialConfig, TutorialModes } from '../types';
+import CFamily from './buildtool-steps/CFamily';
import DotNet from './buildtool-steps/DotNet';
import Gradle from './buildtool-steps/Gradle';
import Maven from './buildtool-steps/Maven';
import Other from './buildtool-steps/Other';
-const BUILD_TOOLS_WITH_NO_ADDITIONAL_OPTIONS = [
- BuildTools.Maven,
- BuildTools.Gradle,
- BuildTools.Other,
-];
-
const BUILDTOOL_COMPONENT_MAP: {
[x in BuildTools]: React.ComponentType<React.PropsWithChildren<LanguageProps>>;
} = {
[BuildTools.Maven]: Maven,
[BuildTools.Gradle]: Gradle,
[BuildTools.DotNet]: DotNet,
- [BuildTools.CFamily]: CFamilly,
+ [BuildTools.Cpp]: CFamily,
+ [BuildTools.ObjectiveC]: CFamily,
[BuildTools.Other]: Other,
};
-export interface JenkinsfileStepProps {
+export interface LanguageProps {
baseUrl: string;
component: Component;
- hasCLanguageFeature: boolean;
- onDone: (done: boolean) => void;
+ config: TutorialConfig;
}
-export interface LanguageProps {
+export interface JenkinsfileStepProps {
baseUrl: string;
component: Component;
- onDone: (done: boolean) => void;
+ hasCLanguageFeature: boolean;
+ setDone: (done: boolean) => void;
}
-export function JenkinsfileStep(props: JenkinsfileStepProps) {
- const { component, hasCLanguageFeature, baseUrl, onDone } = props;
-
- const [buildTool, setBuildTool] = React.useState<BuildTools>();
+export function JenkinsStep(props: Readonly<JenkinsfileStepProps>) {
+ const { component, hasCLanguageFeature, baseUrl, setDone } = props;
- const buildToolOrder = Object.keys(BUILDTOOL_COMPONENT_MAP);
- if (!hasCLanguageFeature) {
- buildToolOrder.splice(buildToolOrder.indexOf(BuildTools.CFamily), 1);
- }
-
- const BuildToolComponent = buildTool ? BUILDTOOL_COMPONENT_MAP[buildTool] : undefined;
+ const [config, setConfig] = React.useState<TutorialConfig>({});
React.useEffect(() => {
- if (buildTool && BUILD_TOOLS_WITH_NO_ADDITIONAL_OPTIONS.includes(buildTool)) {
- onDone(true);
- }
- }, [buildTool, onDone]);
+ setDone(Boolean(config.buildTool));
+ }, [config.buildTool, setDone]);
+
+ const BuildToolComponent = config.buildTool && BUILDTOOL_COMPONENT_MAP[config.buildTool];
return (
<TutorialStep title={translate('onboarding.tutorial.with.jenkins.jenkinsfile.title')}>
<NumberedList>
<NumberedListItem>
- {translate('onboarding.build')}
- <RenderOptions
- label={translate('onboarding.build')}
- checked={buildTool}
- onCheck={(value) => setBuildTool(value as BuildTools)}
- optionLabelKey="onboarding.build"
- options={buildToolOrder}
+ <BuildConfigSelection
+ ci={TutorialModes.Jenkins}
+ config={config}
+ supportCFamily={hasCLanguageFeature}
+ onSetConfig={setConfig}
/>
- {buildTool === BuildTools.CFamily && (
- <FlagMessage variant="info" className="sw-mt-2 sw-w-abs-600">
- {translate('onboarding.tutorial.with.jenkins.jenkinsfile.cfamilly.agent_setup')}
- </FlagMessage>
- )}
</NumberedListItem>
- {BuildToolComponent !== undefined && (
- <BuildToolComponent component={component} baseUrl={baseUrl} onDone={props.onDone} />
+ {BuildToolComponent && (
+ <BuildToolComponent config={config} component={component} baseUrl={baseUrl} />
)}
</NumberedList>
</TutorialStep>
);
}
-export default withCLanguageFeature(JenkinsfileStep);
+export default withCLanguageFeature(JenkinsStep);
diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx
index a57b718d52a..40368aa7222 100644
--- a/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx
@@ -28,7 +28,7 @@ import { AlmKeys, AlmSettingsInstance } from '../../../types/alm-settings';
import { Feature } from '../../../types/features';
import { Component } from '../../../types/types';
import AllSet from '../components/AllSet';
-import JenkinsfileStep from './JenkinsStep';
+import JenkinsStep from './JenkinsStep';
import MultiBranchPipelineStep from './MultiBranchPipelineStep';
import PipelineStep from './PipelineStep';
import PreRequisitesStep from './PreRequisitesStep';
@@ -81,7 +81,7 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) {
projectBinding={projectBinding}
/>
- <JenkinsfileStep component={component} baseUrl={baseUrl} onDone={setDone} />
+ <JenkinsStep component={component} baseUrl={baseUrl} setDone={setDone} />
</TutorialStepList>
{done && (
<>
diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx
index 87574ba0ea4..9380803e1ae 100644
--- a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-it.tsx
@@ -131,25 +131,61 @@ it.each([AlmKeys.BitbucketCloud, AlmKeys.BitbucketServer, AlmKeys.GitHub, AlmKey
await user.click(ui.linuxDotnetCoreButton.get());
expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`linux dotnet core jenkinsfile`);
- // CFamilly
- await user.click(ui.cFamilyBuildButton.get());
+ // C++ (automatic)
+ await user.click(ui.cppBuildButton.get());
+ expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(
+ `c++ (automatic and other): build tools sonar-project.properties code`,
+ );
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (automatic and other): build tools jenkinsfile`,
+ );
+
+ // C++ (manual)
+ await user.click(ui.autoConfigManual.get());
expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`sonar-project.properties code`);
await user.click(ui.linuxButton.get());
- expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`cfamily linux jenkinsfile`);
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (manual) and objectivec: linux jenkinsfile`,
+ );
await user.click(ui.windowsButton.get());
- expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`cfamily windows jenkinsfile`);
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (manual) and objectivec: windows jenkinsfile`,
+ );
await user.click(ui.macosButton.get());
- expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`cfamily macos jenkinsfile`);
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (manual) and objectivec: macos jenkinsfile`,
+ );
+
+ // Objective-C
+ await user.click(ui.objCBuildButton.get());
+ expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(`sonar-project.properties code`);
+
+ await user.click(ui.linuxButton.get());
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (manual) and objectivec: linux jenkinsfile`,
+ );
+
+ await user.click(ui.windowsButton.get());
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (manual) and objectivec: windows jenkinsfile`,
+ );
+
+ await user.click(ui.macosButton.get());
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (manual) and objectivec: macos jenkinsfile`,
+ );
// Other
await user.click(ui.otherBuildButton.get());
expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot(
- `other build tools sonar-project.properties code`,
+ `c++ (automatic and other): build tools sonar-project.properties code`,
+ );
+ expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(
+ `c++ (automatic and other): build tools jenkinsfile`,
);
- expect(getCopyToClipboardValue(3, 'Copy')).toMatchSnapshot(`other build tools jenkinsfile`);
expect(ui.allSetSentence.get()).toBeInTheDocument();
},
diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/JenkinsTutorial-it.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/JenkinsTutorial-it.tsx.snap
index 70cf5185828..5dd2df6b18d 100644
--- a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/JenkinsTutorial-it.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/JenkinsTutorial-it.tsx.snap
@@ -26,7 +26,61 @@ sonar {
}"
`;
-exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: cfamily linux jenkinsfile 1`] = `
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 2`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh "mkdir -p .sonar"
+ sh "curl -sSLo build-wrapper-linux-x86.zip http://localhost:9000/static/cpp/build-wrapper-linux-x86.zip"
+ sh "unzip -o build-wrapper-linux-x86.zip -d .sonar"
+ }
+ stage('Build') {
+ sh ".sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your clean build command>"
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -48,7 +102,33 @@ exports[`bitbucket: can select devops platform and complete all the steps with c
}"
`;
-exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: cfamily macos jenkinsfile 1`] = `
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh '''
+ mkdir -p .sonar
+ curl -sSLo build-wrapper-macosx-x86.zip http://localhost:9000/static/cpp/build-wrapper-macosx-x86.zip
+ unzip -o build-wrapper-macosx-x86.zip -d .sonar
+ '''
+ }
+ stage('Build') {
+ sh '''
+ .sonar/build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -74,7 +154,39 @@ exports[`bitbucket: can select devops platform and complete all the steps with c
}"
`;
-exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: cfamily windows jenkinsfile 1`] = `
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ powershell '''
+ $path = "$HOME/.sonar/build-wrapper-win-x86.zip"
+ rm build-wrapper-win-x86 -Recurse -Force -ErrorAction SilentlyContinue
+ rm $path -Force -ErrorAction SilentlyContinue
+ mkdir $HOME/.sonar
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+ (New-Object System.Net.WebClient).DownloadFile(http://localhost:9000/static/cpp/build-wrapper-win-x86.zip", $path)
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+ [System.IO.Compression.ZipFile]::ExtractToDirectory($path, "$HOME/.sonar")
+ '''
+ }
+ stage('Build') {
+ powershell '''
+ $env:Path += ";$HOME/.sonar/build-wrapper-win-x86"
+ build-wrapper-win-x86-64 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ powershell "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -152,26 +264,12 @@ exports[`bitbucket: can select devops platform and complete all the steps with c
}"
`;
-exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: other build tools jenkinsfile 1`] = `
-"node {
- stage('SCM') {
- checkout scm
- }
- stage('SonarQube Analysis') {
- def scannerHome = tool 'SonarScanner';
- withSonarQubeEnv() {
- sh "\${scannerHome}/bin/sonar-scanner"
- }
- }
-}"
-`;
-
-exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: other build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
-
exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: ref spec 1`] = `"+refs/heads/*:refs/remotes/@{remote}/*"`;
exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
exports[`bitbucket: can select devops platform and complete all the steps with copying code snippets: windows dotnet core jenkinsfile 1`] = `
"node {
stage('SCM') {
@@ -233,7 +331,61 @@ sonar {
}"
`;
-exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: cfamily linux jenkinsfile 1`] = `
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 2`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh "mkdir -p .sonar"
+ sh "curl -sSLo build-wrapper-linux-x86.zip http://localhost:9000/static/cpp/build-wrapper-linux-x86.zip"
+ sh "unzip -o build-wrapper-linux-x86.zip -d .sonar"
+ }
+ stage('Build') {
+ sh ".sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your clean build command>"
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -255,7 +407,33 @@ exports[`bitbucketcloud: can select devops platform and complete all the steps w
}"
`;
-exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: cfamily macos jenkinsfile 1`] = `
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh '''
+ mkdir -p .sonar
+ curl -sSLo build-wrapper-macosx-x86.zip http://localhost:9000/static/cpp/build-wrapper-macosx-x86.zip
+ unzip -o build-wrapper-macosx-x86.zip -d .sonar
+ '''
+ }
+ stage('Build') {
+ sh '''
+ .sonar/build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -281,7 +459,39 @@ exports[`bitbucketcloud: can select devops platform and complete all the steps w
}"
`;
-exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: cfamily windows jenkinsfile 1`] = `
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ powershell '''
+ $path = "$HOME/.sonar/build-wrapper-win-x86.zip"
+ rm build-wrapper-win-x86 -Recurse -Force -ErrorAction SilentlyContinue
+ rm $path -Force -ErrorAction SilentlyContinue
+ mkdir $HOME/.sonar
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+ (New-Object System.Net.WebClient).DownloadFile(http://localhost:9000/static/cpp/build-wrapper-win-x86.zip", $path)
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+ [System.IO.Compression.ZipFile]::ExtractToDirectory($path, "$HOME/.sonar")
+ '''
+ }
+ stage('Build') {
+ powershell '''
+ $env:Path += ";$HOME/.sonar/build-wrapper-win-x86"
+ build-wrapper-win-x86-64 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ powershell "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -359,26 +569,12 @@ exports[`bitbucketcloud: can select devops platform and complete all the steps w
}"
`;
-exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: other build tools jenkinsfile 1`] = `
-"node {
- stage('SCM') {
- checkout scm
- }
- stage('SonarQube Analysis') {
- def scannerHome = tool 'SonarScanner';
- withSonarQubeEnv() {
- sh "\${scannerHome}/bin/sonar-scanner"
- }
- }
-}"
-`;
-
-exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: other build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
-
exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: ref spec 1`] = `"+refs/heads/*:refs/remotes/@{remote}/*"`;
exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
exports[`bitbucketcloud: can select devops platform and complete all the steps with copying code snippets: windows dotnet core jenkinsfile 1`] = `
"node {
stage('SCM') {
@@ -440,7 +636,61 @@ sonar {
}"
`;
-exports[`github: can select devops platform and complete all the steps with copying code snippets: cfamily linux jenkinsfile 1`] = `
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 2`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh "mkdir -p .sonar"
+ sh "curl -sSLo build-wrapper-linux-x86.zip http://localhost:9000/static/cpp/build-wrapper-linux-x86.zip"
+ sh "unzip -o build-wrapper-linux-x86.zip -d .sonar"
+ }
+ stage('Build') {
+ sh ".sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your clean build command>"
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -462,7 +712,33 @@ exports[`github: can select devops platform and complete all the steps with copy
}"
`;
-exports[`github: can select devops platform and complete all the steps with copying code snippets: cfamily macos jenkinsfile 1`] = `
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh '''
+ mkdir -p .sonar
+ curl -sSLo build-wrapper-macosx-x86.zip http://localhost:9000/static/cpp/build-wrapper-macosx-x86.zip
+ unzip -o build-wrapper-macosx-x86.zip -d .sonar
+ '''
+ }
+ stage('Build') {
+ sh '''
+ .sonar/build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -488,7 +764,39 @@ exports[`github: can select devops platform and complete all the steps with copy
}"
`;
-exports[`github: can select devops platform and complete all the steps with copying code snippets: cfamily windows jenkinsfile 1`] = `
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ powershell '''
+ $path = "$HOME/.sonar/build-wrapper-win-x86.zip"
+ rm build-wrapper-win-x86 -Recurse -Force -ErrorAction SilentlyContinue
+ rm $path -Force -ErrorAction SilentlyContinue
+ mkdir $HOME/.sonar
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+ (New-Object System.Net.WebClient).DownloadFile(http://localhost:9000/static/cpp/build-wrapper-win-x86.zip", $path)
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+ [System.IO.Compression.ZipFile]::ExtractToDirectory($path, "$HOME/.sonar")
+ '''
+ }
+ stage('Build') {
+ powershell '''
+ $env:Path += ";$HOME/.sonar/build-wrapper-win-x86"
+ build-wrapper-win-x86-64 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ powershell "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`github: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -566,26 +874,12 @@ exports[`github: can select devops platform and complete all the steps with copy
}"
`;
-exports[`github: can select devops platform and complete all the steps with copying code snippets: other build tools jenkinsfile 1`] = `
-"node {
- stage('SCM') {
- checkout scm
- }
- stage('SonarQube Analysis') {
- def scannerHome = tool 'SonarScanner';
- withSonarQubeEnv() {
- sh "\${scannerHome}/bin/sonar-scanner"
- }
- }
-}"
-`;
-
-exports[`github: can select devops platform and complete all the steps with copying code snippets: other build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
-
exports[`github: can select devops platform and complete all the steps with copying code snippets: ref spec 1`] = `"+refs/heads/*:refs/remotes/@{remote}/*"`;
exports[`github: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+exports[`github: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
exports[`github: can select devops platform and complete all the steps with copying code snippets: windows dotnet core jenkinsfile 1`] = `
"node {
stage('SCM') {
@@ -647,7 +941,61 @@ sonar {
}"
`;
-exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: cfamily linux jenkinsfile 1`] = `
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools jenkinsfile 2`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner"
+ }
+ }
+}"
+`;
+
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (automatic and other): build tools sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh "mkdir -p .sonar"
+ sh "curl -sSLo build-wrapper-linux-x86.zip http://localhost:9000/static/cpp/build-wrapper-linux-x86.zip"
+ sh "unzip -o build-wrapper-linux-x86.zip -d .sonar"
+ }
+ stage('Build') {
+ sh ".sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your clean build command>"
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: linux jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -669,7 +1017,33 @@ exports[`gitlab: can select devops platform and complete all the steps with copy
}"
`;
-exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: cfamily macos jenkinsfile 1`] = `
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ sh '''
+ mkdir -p .sonar
+ curl -sSLo build-wrapper-macosx-x86.zip http://localhost:9000/static/cpp/build-wrapper-macosx-x86.zip
+ unzip -o build-wrapper-macosx-x86.zip -d .sonar
+ '''
+ }
+ stage('Build') {
+ sh '''
+ .sonar/build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: macos jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -695,7 +1069,39 @@ exports[`gitlab: can select devops platform and complete all the steps with copy
}"
`;
-exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: cfamily windows jenkinsfile 1`] = `
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 1`] = `
+"node {
+ stage('SCM') {
+ checkout scm
+ }
+ stage('Download Build Wrapper') {
+ powershell '''
+ $path = "$HOME/.sonar/build-wrapper-win-x86.zip"
+ rm build-wrapper-win-x86 -Recurse -Force -ErrorAction SilentlyContinue
+ rm $path -Force -ErrorAction SilentlyContinue
+ mkdir $HOME/.sonar
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+ (New-Object System.Net.WebClient).DownloadFile(http://localhost:9000/static/cpp/build-wrapper-win-x86.zip", $path)
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+ [System.IO.Compression.ZipFile]::ExtractToDirectory($path, "$HOME/.sonar")
+ '''
+ }
+ stage('Build') {
+ powershell '''
+ $env:Path += ";$HOME/.sonar/build-wrapper-win-x86"
+ build-wrapper-win-x86-64 --out-dir bw-output <your clean build command>
+ '''
+ }
+ stage('SonarQube Analysis') {
+ def scannerHome = tool 'SonarScanner';
+ withSonarQubeEnv() {
+ powershell "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.compile-commands=bw-output/compile_commands.json"
+ }
+ }
+}"
+`;
+
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: c++ (manual) and objectivec: windows jenkinsfile 2`] = `
"node {
stage('SCM') {
checkout scm
@@ -773,26 +1179,12 @@ exports[`gitlab: can select devops platform and complete all the steps with copy
}"
`;
-exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: other build tools jenkinsfile 1`] = `
-"node {
- stage('SCM') {
- checkout scm
- }
- stage('SonarQube Analysis') {
- def scannerHome = tool 'SonarScanner';
- withSonarQubeEnv() {
- sh "\${scannerHome}/bin/sonar-scanner"
- }
- }
-}"
-`;
-
-exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: other build tools sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
-
exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: ref spec 1`] = `"+refs/heads/*:refs/remotes/@{remote}/*"`;
exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 1`] = `"sonar.projectKey=my-project"`;
+exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: sonar-project.properties code 2`] = `"sonar.projectKey=my-project"`;
+
exports[`gitlab: can select devops platform and complete all the steps with copying code snippets: windows dotnet core jenkinsfile 1`] = `
"node {
stage('SCM') {
diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamily.tsx
index 03669459838..cef2de8da04 100644
--- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamilly.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/CFamily.tsx
@@ -25,9 +25,10 @@ import { CompilationInfo } from '../../components/CompilationInfo';
import DefaultProjectKey from '../../components/DefaultProjectKey';
import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories';
import RenderOptions from '../../components/RenderOptions';
-import { OSs, TutorialModes } from '../../types';
+import { AutoConfig, BuildTools, OSs, TutorialModes } from '../../types';
import { LanguageProps } from '../JenkinsStep';
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint';
+import Other from './Other';
const YAML_MAP: Record<OSs, (baseUrl: string) => string> = {
[OSs.Linux]: (baseUrl) => `node {
@@ -103,13 +104,13 @@ const YAML_MAP: Record<OSs, (baseUrl: string) => string> = {
}`,
};
-export default function CFamilly(props: LanguageProps) {
- const { baseUrl, component, onDone } = props;
+export default function CFamily(props: Readonly<LanguageProps>) {
+ const { baseUrl, config, component } = props;
const [os, setOs] = React.useState<OSs>(OSs.Linux);
- React.useEffect(() => {
- onDone(os !== undefined);
- }, [os, onDone]);
+ if (config.buildTool === BuildTools.Cpp && config.autoConfig === AutoConfig.Automatic) {
+ return <Other {...props} />;
+ }
return (
<>
@@ -120,25 +121,25 @@ export default function CFamilly(props: LanguageProps) {
label={translate('onboarding.build.other.os')}
checked={os}
optionLabelKey="onboarding.build.other.os"
- onCheck={(value) => setOs(value as OSs)}
+ onCheck={(value: OSs) => setOs(value)}
options={Object.values(OSs)}
/>
- {os && (
+ {
<GithubCFamilyExampleRepositories
- className="sw-my-4 sw-w-abs-600"
- os={os}
ci={TutorialModes.Jenkins}
+ os={os}
+ className="sw-my-4 sw-w-abs-600"
/>
- )}
+ }
</NumberedListItem>
- {os && (
+ {
<CreateJenkinsfileBulletPoint
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3"
snippet={YAML_MAP[os](baseUrl)}
>
<CompilationInfo />
</CreateJenkinsfileBulletPoint>
- )}
+ }
</>
);
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx
index 3e34cb6a2e8..bf5e5a08d76 100644
--- a/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/buildtool-steps/DotNet.tsx
@@ -43,15 +43,11 @@ const DotOS: { [key in keyof typeof DotNetFlavor]: OSDotNet } = {
};
export default function DotNet(props: LanguageProps) {
- const { component, onDone } = props;
+ const { component } = props;
const [flavorComponent, setFlavorComponent] =
React.useState<keyof typeof DotNetFlavor>('win_core');
const DotNetTutorial = flavorComponent && DotNetFlavor[flavorComponent];
- React.useEffect(() => {
- onDone(flavorComponent !== undefined);
- }, [flavorComponent, onDone]);
-
return (
<>
<NumberedListItem>
diff --git a/server/sonar-web/src/main/js/components/tutorials/other/BuildToolForm.tsx b/server/sonar-web/src/main/js/components/tutorials/other/BuildToolForm.tsx
index f790489a03c..f4bc5dab064 100644
--- a/server/sonar-web/src/main/js/components/tutorials/other/BuildToolForm.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/other/BuildToolForm.tsx
@@ -17,97 +17,70 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { ToggleButton } from 'design-system';
import * as React from 'react';
import { translate } from '../../../helpers/l10n';
import { withCLanguageFeature } from '../../hoc/withCLanguageFeature';
+import BuildConfigSelection from '../components/BuildConfigSelection';
import GithubCFamilyExampleRepositories from '../components/GithubCFamilyExampleRepositories';
import RenderOptions from '../components/RenderOptions';
-import { BuildTools, ManualTutorialConfig, OSs, TutorialModes } from '../types';
+import { BuildTools, OSs, TutorialConfig, TutorialModes } from '../types';
+import { shouldShowGithubCFamilyExampleRepositories } from '../utils';
interface Props {
- config?: ManualTutorialConfig;
+ config: TutorialConfig;
hasCLanguageFeature: boolean;
- onDone: (config: ManualTutorialConfig) => void;
+ os?: OSs;
+ setConfig: (config: TutorialConfig) => void;
+ setOs: (os: OSs) => void;
}
-interface State {
- config: ManualTutorialConfig;
-}
+export function BuildToolForm(props: Readonly<Props>) {
+ const { config, setConfig, os, setOs, hasCLanguageFeature } = props;
-export class BuildToolForm extends React.PureComponent<Props, State> {
- constructor(props: Props) {
- super(props);
- this.state = {
- config: this.props.config || {},
- };
- }
-
- handleBuildToolChange = (buildTool: BuildTools) => {
- const selectOsByDefault = (buildTool === BuildTools.CFamily ||
- buildTool === BuildTools.Other) && {
+ function handleConfigChange(newConfig: TutorialConfig) {
+ const selectOsByDefault = (newConfig.buildTool === BuildTools.Cpp ||
+ newConfig.buildTool === BuildTools.ObjectiveC ||
+ newConfig.buildTool === BuildTools.Other) && {
os: OSs.Linux,
};
- this.setState({ config: { buildTool, ...selectOsByDefault } }, () => {
- this.props.onDone(this.state.config);
+ setConfig({
+ ...config,
+ ...newConfig,
+ ...selectOsByDefault,
});
- };
-
- handleOSChange = (os: OSs) => {
- this.setState(
- ({ config }) => ({ config: { buildTool: config.buildTool, os } }),
- () => {
- this.props.onDone(this.state.config);
- },
- );
- };
-
- render() {
- const { config } = this.state;
- const { hasCLanguageFeature } = this.props;
- const buildTools = [BuildTools.Maven, BuildTools.Gradle, BuildTools.DotNet];
- if (hasCLanguageFeature) {
- buildTools.push(BuildTools.CFamily);
- }
- buildTools.push(BuildTools.Other);
-
- return (
- <>
- <div>
- <label className="sw-block sw-mb-1">{translate('onboarding.build')}</label>
- <ToggleButton
- label={translate('onboarding.build')}
- onChange={this.handleBuildToolChange}
- options={buildTools.map((tool) => ({
- label: translate('onboarding.build', tool),
- value: tool,
- }))}
- value={config.buildTool}
- />
- </div>
-
- {(config.buildTool === BuildTools.Other || config.buildTool === BuildTools.CFamily) && (
- <RenderOptions
- label={translate('onboarding.build.other.os')}
- checked={config.os}
- onCheck={this.handleOSChange}
- optionLabelKey="onboarding.build.other.os"
- options={[OSs.Linux, OSs.Windows, OSs.MacOS]}
- titleLabelKey="onboarding.build.other.os"
- />
- )}
-
- {config.buildTool === BuildTools.CFamily && config.os && (
- <GithubCFamilyExampleRepositories
- className="sw-mt-4 sw-w-abs-600"
- os={config.os}
- ci={TutorialModes.Local}
- />
- )}
- </>
- );
}
+
+ return (
+ <>
+ {config && (
+ <BuildConfigSelection
+ ci={TutorialModes.OtherCI}
+ config={config}
+ supportCFamily={hasCLanguageFeature}
+ onSetConfig={handleConfigChange}
+ />
+ )}
+ {(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"
+ />
+ )}
+ {shouldShowGithubCFamilyExampleRepositories(config) && (
+ <GithubCFamilyExampleRepositories
+ ci={TutorialModes.OtherCI}
+ className="sw-my-4 sw-w-abs-600"
+ />
+ )}
+ </>
+ );
}
export default withCLanguageFeature(BuildToolForm);
diff --git a/server/sonar-web/src/main/js/components/tutorials/other/ProjectAnalysisStep.tsx b/server/sonar-web/src/main/js/components/tutorials/other/ProjectAnalysisStep.tsx
index 799135f27b5..9d5e24d711a 100644
--- a/server/sonar-web/src/main/js/components/tutorials/other/ProjectAnalysisStep.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/other/ProjectAnalysisStep.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import { translate } from '../../../helpers/l10n';
import { Component } from '../../../types/types';
import Step from '../components/Step';
-import { ManualTutorialConfig } from '../types';
+import { OSs, TutorialConfig } from '../types';
import BuildToolForm from './BuildToolForm';
import AnalysisCommand from './commands/AnalysisCommand';
@@ -30,58 +30,46 @@ interface Props {
baseUrl: string;
component: Component;
isLocal: boolean;
- onFinish?: (projectKey?: string) => void;
open: boolean;
stepNumber: number;
token?: string;
}
-interface State {
- config?: ManualTutorialConfig;
-}
-
-export default class ProjectAnalysisStep extends React.PureComponent<Props, State> {
- state: State = {};
+export default function ProjectAnalysisStep(props: Readonly<Props>) {
+ const { component, open, stepNumber, baseUrl, isLocal, token } = props;
- handleBuildToolSelect = (config: ManualTutorialConfig) => {
- const { component } = this.props;
- this.setState({ config });
- if (this.props.onFinish) {
- this.props.onFinish(component.key);
- }
- };
+ const [config, setConfig] = React.useState<TutorialConfig>({});
+ const [os, setOs] = React.useState<OSs>(OSs.Linux);
- renderForm = () => {
- const { component, baseUrl, isLocal, token } = this.props;
+ function renderForm() {
return (
<div className="sw-pb-4">
- <BuildToolForm onDone={this.handleBuildToolSelect} />
+ <BuildToolForm config={config} setConfig={setConfig} os={os} setOs={setOs} />
- {this.state.config && (
+ {config && (
<div className="sw-mt-4">
<AnalysisCommand
+ config={config}
+ os={os}
component={component}
baseUrl={baseUrl}
isLocal={isLocal}
- languageConfig={this.state.config}
token={token}
/>
</div>
)}
</div>
);
- };
-
- render() {
- return (
- <Step
- finished={false}
- onOpen={noop}
- open={this.props.open}
- renderForm={this.renderForm}
- stepNumber={this.props.stepNumber}
- stepTitle={translate('onboarding.analysis.header')}
- />
- );
}
+
+ return (
+ <Step
+ finished={false}
+ onOpen={noop}
+ open={open}
+ renderForm={renderForm}
+ stepNumber={stepNumber}
+ stepTitle={translate('onboarding.analysis.header')}
+ />
+ );
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/other/__tests__/OtherTutorial-it.tsx b/server/sonar-web/src/main/js/components/tutorials/other/__tests__/OtherTutorial-it.tsx
index 53679e3194d..f366797deac 100644
--- a/server/sonar-web/src/main/js/components/tutorials/other/__tests__/OtherTutorial-it.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/other/__tests__/OtherTutorial-it.tsx
@@ -121,40 +121,63 @@ it('can choose build tools and copy provided settings', async () => {
expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('dotnet framework: execute command 2');
expect(getCopyToClipboardValue(2, 'Copy')).toMatchSnapshot('dotnet framework: execute command 3');
- // C Family - Linux
- await user.click(ui.cFamilyBuildButton.get());
+ // C++ - Automatic
+ await user.click(ui.cppBuildButton.get());
+ await user.click(ui.linuxButton.get());
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'c++ (automatic) and other linux: execute scanner',
+ );
+ await user.click(ui.windowsButton.get());
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'c++ (automatic) and other windows: execute scanner',
+ );
+ await user.click(ui.macosButton.get());
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'c++ (automatic) and other macos: execute scanner',
+ );
+
+ // C++ - Linux
+ await user.click(ui.autoConfigManual.get());
await user.click(ui.linuxButton.get());
expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
- 'cfamily linux: execute build wrapper',
+ 'c++ (manual) linux: execute build wrapper',
);
- expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('cfamily linux: execute scanner');
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('c++ (manual) linux: execute scanner');
- // C Family - Windows
+ // C++ - Windows
await user.click(ui.windowsButton.get());
expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
- 'cfamily windows: execute build wrapper',
+ 'c++ (manual) windows: execute build wrapper',
+ );
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
+ 'c++ (manual) windows: execute scanner',
);
- expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('cfamily windows: execute scanner');
- // C Family - MacOS
+ // C++ - MacOS
await user.click(ui.macosButton.get());
expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
- 'cfamily macos: execute build wrapper',
+ 'c++ (manual) macos: execute build wrapper',
);
- expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('cfamily macos: execute scanner');
+ expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('c++ (manual) macos: execute scanner');
// Other - Linux
await user.click(ui.otherBuildButton.get());
await user.click(ui.linuxButton.get());
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('other linux: execute scanner');
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'c++ (automatic) and other linux: execute scanner',
+ );
// Other - Windows
await user.click(ui.windowsButton.get());
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('other windows: execute scanner');
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'c++ (automatic) and other windows: execute scanner',
+ );
// Other - MacOS
await user.click(ui.macosButton.get());
- expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('other macos: execute scanner');
+ expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
+ 'c++ (automatic) and other macos: execute scanner',
+ );
});
function renderOtherTutorial({
diff --git a/server/sonar-web/src/main/js/components/tutorials/other/__tests__/__snapshots__/OtherTutorial-it.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/other/__tests__/__snapshots__/OtherTutorial-it.tsx.snap
index 8371fca630e..a5e42283955 100644
--- a/server/sonar-web/src/main/js/components/tutorials/other/__tests__/__snapshots__/OtherTutorial-it.tsx.snap
+++ b/server/sonar-web/src/main/js/components/tutorials/other/__tests__/__snapshots__/OtherTutorial-it.tsx.snap
@@ -1,13 +1,64 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`can choose build tools and copy provided settings: cfamily linux: execute build wrapper 1`] = `
+exports[`can choose build tools and copy provided settings: c++ (automatic) and other linux: execute scanner 1`] = `
+"sonar-scanner \\
+ -Dsonar.projectKey=my-project \\
+ -Dsonar.sources=. \\
+ -Dsonar.host.url=http://localhost:9000"
+`;
+
+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_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/
+export PATH=$SONAR_SCANNER_HOME/bin:$PATH
+export SONAR_SCANNER_OPTS="-server"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: c++ (automatic) and other macos: execute scanner 1`] = `
+"sonar-scanner \\
+ -Dsonar.projectKey=my-project \\
+ -Dsonar.sources=. \\
+ -Dsonar.host.url=http://localhost:9000"
+`;
+
+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_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/
+export PATH=$SONAR_SCANNER_HOME/bin:$PATH
+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_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
+New-Item -path $env:SONAR_SCANNER_HOME -type directory
+(New-Object System.Net.WebClient).DownloadFile("https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$env:SONAR_SCANNER_VERSION-windows.zip", "$env:SONAR_DIRECTORY/sonar-scanner.zip")
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$env:SONAR_DIRECTORY/sonar-scanner.zip", "$env:SONAR_DIRECTORY")
+rm ./.sonar/sonar-scanner.zip -Force -ErrorAction SilentlyContinue
+$env:Path += ";$env:SONAR_SCANNER_HOME/bin"
+$env:SONAR_SCANNER_OPTS="-server"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: c++ (manual) linux: execute build wrapper 1`] = `
"curl --create-dirs -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip http://localhost:9000/static/cpp/build-wrapper-linux-x86.zip
unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/
export PATH=$HOME/.sonar/build-wrapper-linux-x86:$PATH
"
`;
-exports[`can choose build tools and copy provided settings: cfamily linux: execute scanner 1`] = `
+exports[`can choose build tools and copy provided settings: c++ (manual) linux: execute scanner 1`] = `
"export SONAR_SCANNER_VERSION=5.0.1.3006
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
@@ -17,14 +68,14 @@ export SONAR_SCANNER_OPTS="-server"
"
`;
-exports[`can choose build tools and copy provided settings: cfamily macos: execute build wrapper 1`] = `
+exports[`can choose build tools and copy provided settings: c++ (manual) macos: execute build wrapper 1`] = `
"curl --create-dirs -sSLo $HOME/.sonar/build-wrapper-macosx-x86.zip http://localhost:9000/static/cpp/build-wrapper-macosx-x86.zip
unzip -o $HOME/.sonar/build-wrapper-macosx-x86.zip -d $HOME/.sonar/
export PATH=$HOME/.sonar/build-wrapper-macosx-x86:$PATH
"
`;
-exports[`can choose build tools and copy provided settings: cfamily macos: execute scanner 1`] = `
+exports[`can choose build tools and copy provided settings: c++ (manual) macos: execute scanner 1`] = `
"export SONAR_SCANNER_VERSION=5.0.1.3006
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
@@ -34,7 +85,7 @@ export SONAR_SCANNER_OPTS="-server"
"
`;
-exports[`can choose build tools and copy provided settings: cfamily windows: execute build wrapper 1`] = `
+exports[`can choose build tools and copy provided settings: c++ (manual) windows: execute build wrapper 1`] = `
"$env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
rm "$env:SONAR_DIRECTORY/build-wrapper-win-x86" -Force -Recurse -ErrorAction SilentlyContinue
New-Item -path $env:SONAR_DIRECTORY/build-wrapper-win-x86 -type directory
@@ -45,7 +96,7 @@ $env:Path += ";$env:SONAR_DIRECTORY/build-wrapper-win-x86"
"
`;
-exports[`can choose build tools and copy provided settings: cfamily windows: execute scanner 1`] = `
+exports[`can choose build tools and copy provided settings: c++ (manual) windows: execute scanner 1`] = `
"$env:SONAR_SCANNER_VERSION = "5.0.1.3006"
$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"
@@ -95,38 +146,3 @@ exports[`can choose build tools and copy provided settings: maven: execute scann
-Dsonar.host.url=http://localhost:9000 \\
-Dsonar.token=generatedtoken2"
`;
-
-exports[`can choose build tools and copy provided settings: other linux: execute scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
-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/
-export PATH=$SONAR_SCANNER_HOME/bin:$PATH
-export SONAR_SCANNER_OPTS="-server"
-"
-`;
-
-exports[`can choose build tools and copy provided settings: other macos: execute scanner 1`] = `
-"export SONAR_SCANNER_VERSION=5.0.1.3006
-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/
-export PATH=$SONAR_SCANNER_HOME/bin:$PATH
-export SONAR_SCANNER_OPTS="-server"
-"
-`;
-
-exports[`can choose build tools and copy provided settings: other windows: execute scanner 1`] = `
-"$env:SONAR_SCANNER_VERSION = "5.0.1.3006"
-$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
-New-Item -path $env:SONAR_SCANNER_HOME -type directory
-(New-Object System.Net.WebClient).DownloadFile("https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$env:SONAR_SCANNER_VERSION-windows.zip", "$env:SONAR_DIRECTORY/sonar-scanner.zip")
-Add-Type -AssemblyName System.IO.Compression.FileSystem
-[System.IO.Compression.ZipFile]::ExtractToDirectory("$env:SONAR_DIRECTORY/sonar-scanner.zip", "$env:SONAR_DIRECTORY")
-rm ./.sonar/sonar-scanner.zip -Force -ErrorAction SilentlyContinue
-$env:Path += ";$env:SONAR_SCANNER_HOME/bin"
-$env:SONAR_SCANNER_OPTS="-server"
-"
-`;
diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx
index bae1666034f..f8fb5b2f954 100644
--- a/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx
+++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { Component } from '../../../../types/types';
-import { BuildTools, ManualTutorialConfig } from '../../types';
+import { AutoConfig, BuildTools, OSs, TutorialConfig } from '../../types';
import ClangGCCCustom from './ClangGCCCommand';
import DotNet from './DotNet';
import JavaGradle from './JavaGradle';
@@ -29,19 +29,20 @@ import Other from './Other';
export interface AnalysisCommandProps {
baseUrl: string;
component: Component;
+ config: TutorialConfig;
isLocal: boolean;
- languageConfig: ManualTutorialConfig;
+ os: OSs;
token?: string;
}
export default function AnalysisCommand(props: AnalysisCommandProps) {
- const { component, baseUrl, isLocal, languageConfig, token } = props;
+ const { config, os, component, baseUrl, isLocal, token } = props;
- if (!token) {
+ if (typeof token === 'undefined') {
return null;
}
- switch (languageConfig.buildTool) {
+ switch (config.buildTool) {
case BuildTools.Maven:
return <JavaMaven baseUrl={baseUrl} component={component} token={token} />;
@@ -51,27 +52,27 @@ export default function AnalysisCommand(props: AnalysisCommandProps) {
case BuildTools.DotNet:
return <DotNet baseUrl={baseUrl} component={component} token={token} />;
- case BuildTools.CFamily:
- return languageConfig.os !== undefined ? (
- <ClangGCCCustom
- os={languageConfig.os}
- baseUrl={baseUrl}
- component={component}
- isLocal={isLocal}
- token={token}
- />
- ) : null;
-
case BuildTools.Other:
- return languageConfig.os !== undefined ? (
- <Other
+ return (
+ <Other baseUrl={baseUrl} os={os} component={component} isLocal={isLocal} token={token} />
+ );
+
+ case BuildTools.Cpp:
+ case BuildTools.ObjectiveC:
+ if (config.buildTool === BuildTools.Cpp && config.autoConfig === AutoConfig.Automatic) {
+ return (
+ <Other os={os} baseUrl={baseUrl} component={component} isLocal={isLocal} token={token} />
+ );
+ }
+ return (
+ <ClangGCCCustom
+ os={os}
baseUrl={baseUrl}
- os={languageConfig.os}
component={component}
isLocal={isLocal}
token={token}
/>
- ) : null;
+ );
default:
return null;
diff --git a/server/sonar-web/src/main/js/components/tutorials/test-utils.ts b/server/sonar-web/src/main/js/components/tutorials/test-utils.ts
index 591b1e8e12f..44f9de38066 100644
--- a/server/sonar-web/src/main/js/components/tutorials/test-utils.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/test-utils.ts
@@ -72,7 +72,8 @@ export function getTutorialBuildButtons() {
gradleBuildButton: byRole('radio', { name: `onboarding.build.${BuildTools.Gradle}` }),
gradleDSLButton: (name: GradleBuildDSL) => byRole('radio', { name }),
dotnetBuildButton: byRole('radio', { name: `onboarding.build.${BuildTools.DotNet}` }),
- cFamilyBuildButton: byRole('radio', { name: `onboarding.build.${BuildTools.CFamily}` }),
+ cppBuildButton: byRole('radio', { name: `onboarding.build.${BuildTools.Cpp}` }),
+ objCBuildButton: byRole('radio', { name: `onboarding.build.${BuildTools.ObjectiveC}` }),
otherBuildButton: byRole('radio', { name: `onboarding.build.${BuildTools.Other}` }),
windowsDotnetCoreButton: byRole('radio', {
name: `onboarding.build.${BuildTools.DotNet}.win_core`,
@@ -92,5 +93,7 @@ export function getTutorialBuildButtons() {
linuxButton: byRole('radio', { name: `onboarding.build.other.os.${OSs.Linux}` }),
windowsButton: byRole('radio', { name: `onboarding.build.other.os.${OSs.Windows}` }),
macosButton: byRole('radio', { name: `onboarding.build.other.os.${OSs.MacOS}` }),
+ autoConfigAutomatic: byRole('radio', { name: 'onboarding.build.cpp.autoconfig.automatic' }),
+ autoConfigManual: byRole('radio', { name: 'onboarding.build.cpp.autoconfig.manual' }),
};
}
diff --git a/server/sonar-web/src/main/js/components/tutorials/types.ts b/server/sonar-web/src/main/js/components/tutorials/types.ts
index b9d8a309066..afb938c12b9 100644
--- a/server/sonar-web/src/main/js/components/tutorials/types.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/types.ts
@@ -30,7 +30,8 @@ export enum TutorialModes {
export enum BuildTools {
Maven = 'maven',
Gradle = 'gradle',
- CFamily = 'cfamily',
+ Cpp = 'cpp',
+ ObjectiveC = 'objectivec',
DotNet = 'dotnet',
Other = 'other',
}
@@ -46,6 +47,12 @@ export enum OSs {
MacOS = 'mac',
}
-export type ManualTutorialConfig =
- | { buildTool?: BuildTools.Maven | BuildTools.Gradle | BuildTools.DotNet }
- | { buildTool: BuildTools.Other | BuildTools.CFamily; os?: OSs };
+export enum AutoConfig {
+ Automatic = 'automatic',
+ Manual = 'manual',
+}
+
+export type TutorialConfig = {
+ autoConfig?: AutoConfig;
+ buildTool?: BuildTools;
+};
diff --git a/server/sonar-web/src/main/js/components/tutorials/utils.ts b/server/sonar-web/src/main/js/components/tutorials/utils.ts
index 409236f6548..8231484984e 100644
--- a/server/sonar-web/src/main/js/components/tutorials/utils.ts
+++ b/server/sonar-web/src/main/js/components/tutorials/utils.ts
@@ -21,7 +21,7 @@ import { GRADLE_SCANNER_VERSION } from '../../helpers/constants';
import { convertGithubApiUrlToLink, stripTrailingSlash } from '../../helpers/urls';
import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../types/alm-settings';
import { UserToken } from '../../types/token';
-import { GradleBuildDSL } from './types';
+import { AutoConfig, BuildTools, GradleBuildDSL, TutorialConfig } from './types';
export function quote(os: string): (s: string) => string {
return os === 'win' ? (s: string) => `"${s}"` : (s: string) => s;
@@ -91,3 +91,31 @@ export function buildBitbucketCloudLink(
return `${stripTrailingSlash(almBinding.url)}/${projectBinding.repository}`;
}
+
+export function supportsAutoConfig(buildTool: BuildTools) {
+ return buildTool === BuildTools.Cpp;
+}
+
+export function getBuildToolOptions(supportCFamily: boolean) {
+ const list = [BuildTools.Maven, BuildTools.Gradle, BuildTools.DotNet];
+ if (supportCFamily) {
+ list.push(BuildTools.Cpp);
+ list.push(BuildTools.ObjectiveC);
+ }
+ list.push(BuildTools.Other);
+ return list;
+}
+
+export function isCFamily(buildTool?: BuildTools) {
+ return buildTool === BuildTools.Cpp || buildTool === BuildTools.ObjectiveC;
+}
+
+export function shouldShowGithubCFamilyExampleRepositories(config: TutorialConfig) {
+ if (config.buildTool === BuildTools.Cpp && config.autoConfig === AutoConfig.Manual) {
+ return true;
+ }
+ if (config.buildTool === BuildTools.ObjectiveC) {
+ return true;
+ }
+ return false;
+}
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 f29248383e7..078b6e470f4 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -4540,7 +4540,7 @@ onboarding.analysis.auto_refresh_after_analysis.check_these_links=Check these us
onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis=Pull Request Analysis
onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches=Branch Analysis
-onboarding.build=What option best describes your build?
+onboarding.build=What option best describes your project?
onboarding.build.maven=Maven
onboarding.build.gradle=Gradle
onboarding.build.make=Make
@@ -4548,7 +4548,8 @@ onboarding.build.dotnet=.NET
onboarding.build.dotnet.win_core=Windows + .NET Core
onboarding.build.dotnet.win_msbuild=Windows + .NET Framework
onboarding.build.dotnet.linux_core=Linux + .NET Core
-onboarding.build.cfamily=C,C++ or ObjC
+onboarding.build.cpp=C or C++
+onboarding.build.objectivec=Objective-C
onboarding.build.other=Other (for JS, TS, Go, Python, PHP, ...)
onboarding.build.dotnet.variant=Choose your build tool
@@ -4560,6 +4561,12 @@ onboarding.build.other.os.linux=Linux
onboarding.build.other.os.win=Windows
onboarding.build.other.os.mac=macOS
+onboarding.build.cpp.autoconfig=Do you want to use automatic configuration or manual configuration?
+onboarding.build.cpp.autoconfig.automatic=Automatic
+onboarding.build.cpp.autoconfig.automatic.description=Automatic Configuration allows the onboarding of most projects. Getting started does not require any specific knowledge about the project or the language.
+onboarding.build.cpp.autoconfig.manual=Manual
+onboarding.build.cpp.autoconfig.manual.description=Manual Configuration provides enhanced control over the setup, making it more suitable for certain specific use-cases. However, it may not support all scenarios and requires a certain level of understanding about the project's build process.
+
onboarding.analysis.docs=Please visit the {link} for more details.
onboarding.analysis.build_wrapper.header.linux=Download and unzip the Build Wrapper for Linux
onboarding.analysis.build_wrapper.header.win=Download and unzip the Build Wrapper for Windows
@@ -4692,7 +4699,8 @@ onboarding.tutorial.with.gitlab_ci.project_key.maven.step2=Add the following to
onboarding.tutorial.with.gitlab_ci.project_key.gradle.step2=Add the following to your {file} or {file2} file:
onboarding.tutorial.with.gitlab_ci.project_key.other.step2=Create a {file} file in your repository and paste the following code:
onboarding.tutorial.with.gitlab_ci.project_key.dotnet.step2=Create a {file} file in your repository and paste the following code:
-onboarding.tutorial.with.gitlab_ci.project_key.cfamily.step2=Create a {file} file in your repository and paste the following code:
+onboarding.tutorial.with.gitlab_ci.project_key.cpp.step2=Create a {file} file in your repository and paste the following code:
+onboarding.tutorial.with.gitlab_ci.project_key.objectivec.step2=Create a {file} file in your repository and paste the following code:
onboarding.tutorial.with.gitlab_ci.variables.title=Add environment variables
onboarding.tutorial.with.gitlab_ci.variables.description.link=Settings > CI/CD > Variables
@@ -5000,7 +5008,8 @@ onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.sec
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.dotnet=Integrate with MSBuild
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.maven=Integrate with Maven or Gradle
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.gradle=Integrate with Maven or Gradle
-onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.cfamily=Use standalone scanner
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.cpp=Use standalone scanner
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.objectivec=Use standalone scanner
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.other=Use standalone scanner
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.manual.sentence=Select the {mode} mode.
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.manual.sentence.mode=Manually provide configuration