]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14468, SONAR-14435 Improve C/C++/OjbC tutorial
authorMathieu Suen <mathieu.suen@sonarsource.com>
Thu, 4 Mar 2021 14:10:23 +0000 (15:10 +0100)
committersonartech <sonartech@sonarsource.com>
Mon, 8 Mar 2021 20:07:54 +0000 (20:07 +0000)
13 files changed:
server/sonar-docs/src/pages/analysis/azuredevops-integration.md
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/BranchAnalysisStepContent.tsx
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/BranchAnalysisStepContent-test.tsx
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/__tests__/__snapshots__/BranchAnalysisStepContent-test.tsx.snap
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/AnalysisCommand.tsx
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/ClangGCC.tsx
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PrepareAnalysisCommand.tsx
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/__tests__/__snapshots__/ClangGCC-test.tsx.snap
server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/__tests__/__snapshots__/PrepareAnalysisCommand-test.tsx.snap
server/sonar-web/src/main/js/components/tutorials/manual/BuildToolForm.tsx
server/sonar-web/src/main/js/components/tutorials/manual/__tests__/BuildToolForm-test.tsx
server/sonar-web/src/main/js/components/tutorials/manual/__tests__/__snapshots__/BuildToolForm-test.tsx.snap
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 644a235515d603261a36e4bfc1fad56fbee8dea0..249030dcb63612bd5f3b90cbdb000e505abf0cda 100644 (file)
@@ -189,11 +189,13 @@ Select your build technology below to expand the instructions for configuring br
 
 [[collapse]]
 | ## Analyzing a C/C++/Obj-C project
-|In your build pipeline, insert the following steps in the order they appear here. These steps can be interleaved with other steps of your build as long as the following order is followed. All steps have to be executed on the same agent.
-| 1. Make **Build Wrapper** available on the build agent:\
-|   Download and unzip the **Build Wrapper** on the build agent (see *Prerequisites* section of the [C/C++/Objective-C](/analysis/languages/cfamily/) page). The archive to download and decompress depends on the platform of the host.\
-|   Please, note that:
-|    - For the Microsoft-hosted build agent you will need to do it every time (as part of build pipeline), e.g. you can add **PowerShell script** task doing that. This can be done by inserting a **Command Line** task.\
+| In your build pipeline, insert the following steps in the order they appear here. These steps can be interweaved with other steps of your build as long as the following order is followed. All steps have to be executed on the same agent.
+| 
+| 1. Make the **Build Wrapper** available on the build agent: 
+|    
+|    Download and unzip the **Build Wrapper** on the build agent (see the **Prerequisites** section of the [C/C++/Objective-C](/analysis/languages/cfamily/) page). The archive to download and decompress depends on the platform of the host.
+|    Please, note that:
+|    - For the Microsoft-hosted build agent, you will need to make the **Build Wrapper** available on the build agent every time (as part of the build pipeline). To accomplish this, you can add a **PowerShell script** task by inserting a **Command Line** task.
 |     Example of PowerShell commands on a Windows host:
 |     ```
 |     Invoke-WebRequest -Uri '<sonarqube_url>/static/cpp/build-wrapper-win-x86.zip' -OutFile 'build-wrapper.zip'
@@ -210,15 +212,15 @@ Select your build technology below to expand the instructions for configuring br
 |     unzip build-wrapper.zip
 |     ```  
 |    - For the self-hosted build agent you can either download it every time (using the same scripts) or only once (as part of manual setup of build agent).
-| 2. Add a **Prepare analysis Configuration** task and configure it as follow:\
-|   Click on the **Prepare analysis on SonarQube** task to configure it:
+| 1. Add a **Prepare analysis Configuration** task and configure it as follow:
+|     Click on the **Prepare analysis on SonarQube** task to configure it:
 |    * Select the **SonarQube Server**
 |    * In *Choose the way to run the analysis*, select *standalone scanner* (even if you build with *Visual Studio*/*MSBuild*) 
 |    * In *Additional Properties* in the *Advanced* section, add the property `sonar.cfamily.build-wrapper-output` with, as its value, the output directory to which the Build Wrapper should write its results: `sonar.cfamily.build-wrapper-output=<output directory>`
-| 3. Add a **Command Line** task to run your build.\
+| 1. Add a **Command Line** task to run your build.
 |    For the analysis to happen, your build has to be run through a command line so that it can be wrapped-up by the build-wrapper.
 |    To do so, 
-|    * Run **Build Wrapper** executable. Pass in as the arguments (1) the output directory configured in the previous task and (2) the command that runs a clean build of your project (not an incremental build).\
+|    * Run **Build Wrapper** executable. Pass in as the arguments (1) the output directory configured in the previous task and (2) the command that runs a clean build of your project (not an incremental build).
 |    Example of PowerShell commands on a Windows host with an *MSBuild* build:
 |      ```
 |     build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir <output directory> MSBuild.exe /t:Rebuild
@@ -231,8 +233,50 @@ Select your build technology below to expand the instructions for configuring br
 |      ```
 |      build-wrapper-macosx-x86/build-wrapper-macos-x86 --out-dir <output directory> xcodebuild -project myproject.xcodeproj -configuration Release clean build
 |      ```
-| 4. Add a **Run Code Analysis** task to run the code analysis and make the results available to SonarQube. Consider running this task right after the previous one as the build environment should not be significantly altered before running the analysis.
-| 5. Add a **Publish Quality Gate Result** task.
+| 1. Add a **Run Code Analysis** task to run the code analysis and make the results available to SonarQube. Consider running this task right after the previous one as the build environment should not be significantly altered before running the analysis.
+| 1. Add a **Publish Quality Gate Result** task.
+| 
+| **.yml example**:
+| ```
+| trigger:
+| - master
+| - feature/*
+|
+| steps:
+| # Make Build Wrapper available
+| - task: Bash@3
+|   displayName: Download Build Wrapper
+|   inputs:
+|     targetType: inline
+|     script: >
+|       curl  '<SONARQUBE_HOST>/static/cpp/build-wrapper-linux-x86.zip' --output build-wrapper.zip
+|       unzip build-wrapper.zip
+|
+| # Prepare Analysis Configuration task
+| - task: SonarQubePrepare@4
+|   inputs:
+|     SonarQube: 'YourSonarqubeServerEndpoint'
+|     scannerMode: 'CLI'
+|     configMode: 'manual'
+|     cliProjectKey: 'YourProjectKey'
+|     extraProperties: "sonar.cfamily.build-wrapper-output=bw_output"
+| # Command Line task to run your build.
+| - task: Bash@3
+|    displayName: Bash Script
+|    inputs:
+|      targetType: inline
+|      script: >
+|        ./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw_output <Your build command>
+|
+| # Run Code Analysis task
+| - task: SonarQubeAnalyze@4
+|
+| # Publish Quality Gate Result task
+| - task: SonarQubePublish@4
+|   inputs:
+|     pollingTimeoutSec: '300'
+| ```
+|  *Note: You need to choose your correct image and adapt the correct wrapper depending on the agent os. See above example to have the correct wrapper.*
 
 ### Running your pipeline
 Commit and push your code to trigger the pipeline execution and SonarQube analysis. New pushes on your branches (and pull requests if you set up pull request analysis) trigger a new analysis in SonarQube.
index 1ec5a67b2c7662ada8066e80b73611b0abed66bd..e8fd38050d4cc7516049bd8a2397c6ec560ba305 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import { connect } from 'react-redux';
 import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getLanguages, Store } from '../../../store/rootReducer';
 import RenderOptions from '../components/RenderOptions';
 import { BuildTools } from '../types';
 import AnalysisCommand from './commands/AnalysisCommand';
 
 export interface BranchesAnalysisStepProps {
+  languages: T.Languages;
   component: T.Component;
   onStepValidationChange: (isValid: boolean) => void;
 }
@@ -36,11 +39,13 @@ const BUILD_TOOLS_ORDERED: Array<BuildTools> = [
   BuildTools.Other
 ];
 
-export default function BranchAnalysisStepContent(props: BranchesAnalysisStepProps) {
-  const { component, onStepValidationChange } = props;
+export function BranchAnalysisStepContent(props: BranchesAnalysisStepProps) {
+  const { component, onStepValidationChange, 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>
@@ -49,7 +54,7 @@ export default function BranchAnalysisStepContent(props: BranchesAnalysisStepPro
         name="buildTechnology"
         onCheck={value => setBuildTechnology(value as BuildTools)}
         optionLabelKey="onboarding.build"
-        options={BUILD_TOOLS_ORDERED}
+        options={buildToolsList}
       />
       <AnalysisCommand
         onStepValidationChange={onStepValidationChange}
@@ -59,3 +64,9 @@ export default function BranchAnalysisStepContent(props: BranchesAnalysisStepPro
     </>
   );
 }
+
+const mapStateToProps = (state: Store) => ({
+  languages: getLanguages(state)
+});
+
+export default connect(mapStateToProps)(BranchAnalysisStepContent);
index a865469b760ddd92ba11258f5cf421cb31bafdfc..ac649569b3befed982cb7585d18e03088c511e2f 100644 (file)
@@ -22,10 +22,11 @@ import * as React from 'react';
 import { mockComponent } from '../../../../helpers/testMocks';
 import RenderOptions from '../../components/RenderOptions';
 import { BuildTools } from '../../types';
-import BranchAnalysisStepContent, { BranchesAnalysisStepProps } from '../BranchAnalysisStepContent';
+import { BranchAnalysisStepContent, BranchesAnalysisStepProps } from '../BranchAnalysisStepContent';
 
 it('should render correctly', () => {
   expect(shallowRender()).toMatchSnapshot();
+  expect(shallowRender({ languages: {} })).toMatchSnapshot('without C');
 });
 
 it.each([BuildTools.DotNet, BuildTools.Gradle, BuildTools.Maven, BuildTools.Other])(
@@ -44,6 +45,7 @@ it.each([BuildTools.DotNet, BuildTools.Gradle, BuildTools.Maven, BuildTools.Othe
 function shallowRender(props: Partial<BranchesAnalysisStepProps> = {}) {
   return shallow(
     <BranchAnalysisStepContent
+      languages={{ c: { key: 'c', name: 'test' } }}
       component={mockComponent()}
       onStepValidationChange={jest.fn()}
       {...props}
index 3b1aacd4defec58072c9409eadd4fe4968ab3b0f..ab69a5c3830f90fbaeb3c15a6cb72cb6688a25a0 100644 (file)
@@ -137,3 +137,28 @@ exports[`should render correctly: other 1`] = `
   />
 </Fragment>
 `;
+
+exports[`should render correctly: without C 1`] = `
+<Fragment>
+  <span>
+    onboarding.build
+  </span>
+  <RenderOptions
+    name="buildTechnology"
+    onCheck={[Function]}
+    optionLabelKey="onboarding.build"
+    options={
+      Array [
+        "dotnet",
+        "maven",
+        "gradle",
+        "other",
+      ]
+    }
+  />
+  <AnalysisCommand
+    onStepValidationChange={[MockFunction]}
+    projectKey="my-project"
+  />
+</Fragment>
+`;
index d0506670b0685fcb664f4646cde1c6b86546bcc7..9c3ced3d9efb8f6c155e99b9f3599a9e3b269eb4 100644 (file)
@@ -38,8 +38,6 @@ export default function AnalysisCommand(props: AnalysisCommandProps) {
   React.useEffect(() => {
     if (buildTool && buildTool !== BuildTools.CFamily) {
       props.onStepValidationChange(true);
-    } else {
-      props.onStepValidationChange(false);
     }
   }, [buildTool, props.onStepValidationChange]);
 
index 59880e0c93f04bcee5ec02926b3ef6e84e674f0a..1baf28d923c3c3d1d85d3852ee681a686fd06fff 100644 (file)
@@ -54,7 +54,7 @@ unzip build-wrapper.zip`,
       highlightScriptKey:
         'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.nix',
       scriptBuild:
-        './build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir <output directory> make clean all'
+        './build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output make clean all'
     },
     [OSs.Windows]: {
       script: `Invoke-WebRequest -Uri '${host}/static/cpp/build-wrapper-win-x86.zip' -OutFile 'build-wrapper.zip'
@@ -62,7 +62,7 @@ Expand-Archive -Path 'build-wrapper.zip' -DestinationPath '.'`,
       highlightScriptKey:
         'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.win',
       scriptBuild:
-        'build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir <output directory> MSBuild.exe /t:Rebuild'
+        'build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir bw-output MSBuild.exe /t:Rebuild'
     },
     [OSs.MacOS]: {
       script: `curl '${host}/static/cpp/build-wrapper-macosx-x86.zip' --output build-wrapper.zip
@@ -70,7 +70,7 @@ unzip build-wrapper.zip`,
       highlightScriptKey:
         'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.nix',
       scriptBuild:
-        './build-wrapper-macos-x86/build-wrapper-macos-x86 --out-dir <output directory> xcodebuild' +
+        './build-wrapper-macos-x86/build-wrapper-macos-x86 --out-dir bw-output xcodebuild' +
         ' -project myproject.xcodeproj -configuration Release clean build'
     }
   };
@@ -78,9 +78,15 @@ unzip build-wrapper.zip`,
   React.useEffect(() => {
     if (os) {
       props.onStepValidationChange(true);
+    } else {
+      props.onStepValidationChange(false);
     }
   }, [os, props.onStepValidationChange]);
 
+  const handlOsChange = (value: OSs) => {
+    setOs(value);
+  };
+
   return (
     <>
       <span className="big-spacer-top display-block">
@@ -89,7 +95,7 @@ unzip build-wrapper.zip`,
       <RenderOptions
         checked={os}
         name="os"
-        onCheck={value => setOs(value as OSs)}
+        onCheck={handlOsChange}
         optionLabelKey="onboarding.build.other.os"
         options={Object.values(OSs)}
       />
@@ -110,7 +116,7 @@ unzip build-wrapper.zip`,
                 <SentenceWithHighlights
                   translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.script"
                   highlightPrefixKeys={codeSnippetDownload[os].highlightScriptKey}
-                  highlightKeys={['task']}
+                  highlightKeys={['task', 'inline']}
                 />
                 <CodeSnippet snippet={codeSnippetDownload[os].script} />
               </li>
index 60bfbf86b15bdbbd2510ab6dabc907ff748dc403..744a22da66e8a190009530ffbd257fbd8416bf72 100644 (file)
@@ -41,7 +41,7 @@ export interface PrepareAnalysisCommandProps {
 export default function PrepareAnalysisCommand(props: PrepareAnalysisCommandProps) {
   const { buildTool, kind, projectKey } = props;
 
-  const ADDITIONAL_PROPERTY = 'sonar.cfamily.build-wrapper-output=<output directory>';
+  const ADDITIONAL_PROPERTY = 'sonar.cfamily.build-wrapper-output=bw-output';
 
   const MAVEN_GRADLE_PROPS_SNIPPET = `# Additional properties that will be passed to the scanner,
 # Put one key=value per line, example:
index e2cfc176ab3bc5b3cc9d52e52569bf23db0ae806..24e43f7635518e107e20a74d96ff2af1ae2c8a6c 100644 (file)
@@ -43,6 +43,7 @@ exports[`should render correctly for "linux" 1`] = `
           highlightKeys={
             Array [
               "task",
+              "inline",
             ]
           }
           highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.nix"
@@ -94,7 +95,7 @@ unzip build-wrapper.zip"
           translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_script.ccpp"
         />
         <CodeSnippet
-          snippet="./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir <output directory> make clean all"
+          snippet="./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output make clean all"
         />
       </li>
     </ul>
@@ -158,6 +159,7 @@ exports[`should render correctly for "mac" 1`] = `
           highlightKeys={
             Array [
               "task",
+              "inline",
             ]
           }
           highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.nix"
@@ -209,7 +211,7 @@ unzip build-wrapper.zip"
           translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_script.ccpp"
         />
         <CodeSnippet
-          snippet="./build-wrapper-macos-x86/build-wrapper-macos-x86 --out-dir <output directory> xcodebuild -project myproject.xcodeproj -configuration Release clean build"
+          snippet="./build-wrapper-macos-x86/build-wrapper-macos-x86 --out-dir bw-output xcodebuild -project myproject.xcodeproj -configuration Release clean build"
         />
       </li>
     </ul>
@@ -273,6 +275,7 @@ exports[`should render correctly for "win" 1`] = `
           highlightKeys={
             Array [
               "task",
+              "inline",
             ]
           }
           highlightPrefixKeys="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.win"
@@ -324,7 +327,7 @@ Expand-Archive -Path 'build-wrapper.zip' -DestinationPath '.'"
           translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_script.ccpp"
         />
         <CodeSnippet
-          snippet="build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir <output directory> MSBuild.exe /t:Rebuild"
+          snippet="build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir bw-output MSBuild.exe /t:Rebuild"
         />
       </li>
     </ul>
index 8085026aff03908d5a532f547946c891509e0b34..170210c11f54c22e6bc3bb981122a605f97a6698 100644 (file)
@@ -240,12 +240,12 @@ exports[`should render correctly 4`] = `
             onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp.advanced
           </b>,
           "button": <ClipboardIconButton
-            copyValue="sonar.cfamily.build-wrapper-output=<output directory>"
+            copyValue="sonar.cfamily.build-wrapper-output=bw-output"
           />,
           "property": <code
             className="rule"
           >
-            sonar.cfamily.build-wrapper-output=&lt;output directory&gt;
+            sonar.cfamily.build-wrapper-output=bw-output
           </code>,
         }
       }
index f9bb51a0a97d3c115746bafa898619e8c4e86f59..1da982e10e3cbf5533c31fe6bbefa6cb441566dd 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import { connect } from 'react-redux';
 import RadioToggle from 'sonar-ui-common/components/controls/RadioToggle';
 import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getLanguages, Store } from '../../../store/rootReducer';
 import RenderOptions from '../components/RenderOptions';
 import { BuildTools, ManualTutorialConfig, OSs } from '../types';
 
 interface Props {
+  languages: T.Languages;
   config?: ManualTutorialConfig;
   onDone: (config: ManualTutorialConfig) => void;
 }
@@ -32,7 +35,7 @@ interface State {
   config: ManualTutorialConfig;
 }
 
-export default class BuildToolForm extends React.PureComponent<Props, State> {
+export class BuildToolForm extends React.PureComponent<Props, State> {
   constructor(props: Props) {
     super(props);
     this.state = {
@@ -57,13 +60,12 @@ export default class BuildToolForm extends React.PureComponent<Props, State> {
 
   render() {
     const { config } = this.state;
-    const buildTools = [
-      BuildTools.Maven,
-      BuildTools.Gradle,
-      BuildTools.DotNet,
-      BuildTools.CFamily,
-      BuildTools.Other
-    ];
+    const { languages } = this.props;
+    const buildTools = [BuildTools.Maven, BuildTools.Gradle, BuildTools.DotNet];
+    if (languages['c']) {
+      buildTools.push(BuildTools.CFamily);
+    }
+    buildTools.push(BuildTools.Other);
 
     return (
       <>
@@ -94,3 +96,9 @@ export default class BuildToolForm extends React.PureComponent<Props, State> {
     );
   }
 }
+
+const mapStateToProps = (state: Store) => ({
+  languages: getLanguages(state)
+});
+
+export default connect(mapStateToProps)(BuildToolForm);
index cf789d91a2df15fb3163dcd34136911a386c544e..3cd4d25b4056d65b7565deec6366519c97001caa 100644 (file)
 import { shallow } from 'enzyme';
 import * as React from 'react';
 import { BuildTools, OSs } from '../../types';
-import BuildToolForm from '../BuildToolForm';
+import { BuildToolForm } from '../BuildToolForm';
 
 it('renders correctly', () => {
   expect(shallowRender()).toMatchSnapshot('default');
+  expect(shallowRender({ languages: {} })).toMatchSnapshot('without C');
   expect(shallowRender().setState({ config: { buildTool: BuildTools.Maven } })).toMatchSnapshot(
     'with "maven" selected'
   );
@@ -47,5 +48,7 @@ it('correctly calls the onDone prop', () => {
 });
 
 function shallowRender(props: Partial<BuildToolForm['props']> = {}) {
-  return shallow<BuildToolForm>(<BuildToolForm onDone={jest.fn()} {...props} />);
+  return shallow<BuildToolForm>(
+    <BuildToolForm onDone={jest.fn()} languages={{ c: { key: 'c', name: 'test' } }} {...props} />
+  );
 }
index a478aa8017b664a268a1c073fbe99fbf007325ae..4f1c17201a7a5dabb52b62e1bf20dbb1e503f9dc 100644 (file)
@@ -138,3 +138,41 @@ exports[`renders correctly: with "other" selected 1`] = `
   />
 </Fragment>
 `;
+
+exports[`renders correctly: without C 1`] = `
+<Fragment>
+  <div>
+    <h4
+      className="spacer-bottom"
+    >
+      onboarding.build
+    </h4>
+    <RadioToggle
+      disabled={false}
+      name="language"
+      onCheck={[Function]}
+      options={
+        Array [
+          Object {
+            "label": "onboarding.build.maven",
+            "value": "maven",
+          },
+          Object {
+            "label": "onboarding.build.gradle",
+            "value": "gradle",
+          },
+          Object {
+            "label": "onboarding.build.dotnet",
+            "value": "dotnet",
+          },
+          Object {
+            "label": "onboarding.build.other",
+            "value": "other",
+          },
+        ]
+      }
+      value={null}
+    />
+  </div>
+</Fragment>
+`;
index 829fc92b5e5287ad5285022ed0750425eef390d0..2b86440b6d3435e4eb1ebde2fcfceb0ce1d34e35 100644 (file)
@@ -3299,7 +3299,7 @@ onboarding.token.invalid_format=The token you have entered has invalid format.
 onboarding.analysis.header=Run analysis on your project
 onboarding.analysis.auto_refresh_after_analysis=Once the analysis is completed, this page will automatically refresh and you will be able to browse the analysis results.
 
-onboarding.build=What is your build technology?
+onboarding.build=What option best describes your build?
 onboarding.build.maven=Maven
 onboarding.build.gradle=Gradle
 onboarding.build.make=Make
@@ -3644,7 +3644,7 @@ onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title=Install Son
 onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence=From your Azure DevOps instance, navigate to the Visual Studio Marketplace and install the {link} by clicking the {button} button.
 onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence.link=SonarQube extension
 onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence.button=Get it free
-onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.title=Add a new SonarQube Service Endpoint
+onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.title=Add a new SonarQube Service Endpoint in your project
 onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step1.sentence=In Azure DevOps, go to {menu}
 onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step1.sentence.menu=Project settings > Service connections
 onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step2.sentence=Add a new service connection of type {type}
@@ -3657,21 +3657,23 @@ onboarding.tutorial.with.azure_pipelines.BranchAnalysis.title=Configure analysis
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.info=The following steps assume you are using the Azure Pipelines classic editor. Check out our {doc_link} for the yaml counterpart.
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.info.doc_link=Azure DevOps integration page
 
-onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.sentence=In Azure DevOps, create or edit a {pipeline} to make Build Wrapper available on the build agent.
-onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.script.sentence=Add a {task} task to download and decompress the Build Wrapper on the build agent.
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.sentence=In Azure DevOps, create or edit a build {pipeline} to make Build Wrapper available on the build agent.
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.script.sentence=Add a {task} task, select {inline} mode and add the following script to download and decompress the Build Wrapper on the build agent.
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.win.sentence.task=PowerShell script
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.nix.sentence.task=Bash script
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.win.sentence.inline=inline
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_wrapper.ccpp.nix.sentence.inline=inline
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.ccpp.sentence=Add a new {task} task {before} your build task
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp=In {additional} in the {advanced} section, add a new property to set the output directory to which the Build Wrapper should write its results: {property} {button}
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp.additional=Additional Properties
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare_additional.ccpp.advanced=Advanced
-onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build.ccpp.sentence=Add or modify your {task} task. For the analysis to happen, your build has to be run through a command line so that it can be wrapped-up by the build-wrapper.
-onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build.ccpp.sentence.task=Build Command Line
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build.ccpp.sentence=Add or modify your build {task} task. For the analysis to happen, your build has to be run through a command line so that it can be wrapped-up by the build-wrapper.
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build.ccpp.sentence.task=Command Line
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_script.ccpp.sentence=Run {build_wrapper} executable. Pass in as the arguments (1) the output directory configured in the previous task and (2) the command that runs a clean build of your project (not an incremental build). Example:
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.build_script.ccpp.sentence.build_wrapper=Build Wrapper
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.ccpp.sentence=Add a new {task} task {after} your build task. Consider running this task right after the previous one as the build environment should not be significantly altered before running the analysis.
-onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.sentence=In Azure DevOps, create or edit a {pipeline} and add a new {task} task {before} your build task
-onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.sentence.pipeline=Build Pipeline
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.sentence=In Azure DevOps, create or edit a build {pipeline} and add a new {task} task {before} your build task
+onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.sentence.pipeline=Pipeline
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.sentence.task=Prepare Analysis Configuration
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.sentence.before=before
 onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.endpoint.sentence=Select the {endpoint} you created in Step 2