Browse Source

SONAR-14495 Add the .NET tutorial for gitlab CI

tags/8.8.0.42792
Mathieu Suen 3 years ago
parent
commit
cf5b5df5a0

+ 3
- 3
server/sonar-web/src/main/js/components/tutorials/gitlabci/GitLabCITutorial.tsx View File

@@ -26,7 +26,7 @@ import {
} from '../../../types/alm-settings';
import EnvironmentVariablesStep from './EnvironmentVariablesStep';
import ProjectKeyStep from './ProjectKeyStep';
import { BuildTools } from './types';
import { GitlabBuildTools } from './types';
import YmlFileStep from './YmlFileStep';

export enum Steps {
@@ -46,7 +46,7 @@ export default function GitLabCITutorial(props: GitLabCITutorialProps) {
const { baseUrl, component, currentUser, projectBinding } = props;

const [step, setStep] = React.useState(Steps.PROJECT_KEY);
const [buildTool, setBuildTool] = React.useState<BuildTools | undefined>();
const [buildTool, setBuildTool] = React.useState<GitlabBuildTools | undefined>();

// Failsafe; should never happen.
if (!isProjectGitLabBindingResponse(projectBinding)) {
@@ -81,7 +81,7 @@ export default function GitLabCITutorial(props: GitLabCITutorialProps) {
open={step === Steps.ENV_VARIABLES}
/>

<YmlFileStep buildTool={buildTool} open={step === Steps.YML} />
<YmlFileStep buildTool={buildTool} open={step === Steps.YML} projectKey={component.key} />
</>
);
}

+ 14
- 6
server/sonar-web/src/main/js/components/tutorials/gitlabci/ProjectKeyStep.tsx View File

@@ -25,16 +25,17 @@ import { translate } from 'sonar-ui-common/helpers/l10n';
import CodeSnippet from '../../common/CodeSnippet';
import RenderOptions from '../components/RenderOptions';
import Step from '../components/Step';
import { BuildTools } from './types';
import { BuildTools } from '../types';
import { GitlabBuildTools, GITLAB_BUILDTOOLS_LIST } from './types';

export interface ProjectKeyStepProps {
buildTool?: BuildTools;
buildTool?: GitlabBuildTools;
component: T.Component;
finished: boolean;
onDone: () => void;
onOpen: () => void;
open: boolean;
setBuildTool: (tool: BuildTools) => void;
setBuildTool: (tool: GitlabBuildTools) => void;
}

const mavenSnippet = (key: string) => `<properties>
@@ -72,6 +73,13 @@ const filenameForBuildTool = {
export default function ProjectKeyStep(props: ProjectKeyStepProps) {
const { buildTool, component, finished, open } = props;

const buildToolSelect = (value: GitlabBuildTools) => {
props.setBuildTool(value);
if (value === BuildTools.DotNet) {
props.onDone();
}
};

const renderForm = () => (
<div className="boxed-group-inner">
<ol className="list-styled">
@@ -80,12 +88,12 @@ export default function ProjectKeyStep(props: ProjectKeyStepProps) {
<RenderOptions
checked={buildTool}
name="buildtool"
onCheck={value => props.setBuildTool(value as BuildTools)}
onCheck={buildToolSelect}
optionLabelKey="onboarding.build"
options={Object.values(BuildTools)}
options={GITLAB_BUILDTOOLS_LIST}
/>
</li>
{buildTool !== undefined && (
{buildTool !== undefined && buildTool !== BuildTools.DotNet && (
<li className="abs-width-600">
<FormattedMessage
defaultMessage={translate(

+ 14
- 4
server/sonar-web/src/main/js/components/tutorials/gitlabci/YmlFileStep.tsx View File

@@ -25,15 +25,21 @@ import { translate } from 'sonar-ui-common/helpers/l10n';
import { withAppState } from '../../hoc/withAppState';
import Step from '../components/Step';
import PipeCommand from './commands/PipeCommand';
import { BuildTools } from './types';
import { GitlabBuildTools } from './types';

export interface YmlFileStepProps {
appState: T.AppState;
buildTool?: BuildTools;
buildTool?: GitlabBuildTools;
open: boolean;
projectKey: string;
}

export function YmlFileStep({ appState: { branchesEnabled }, buildTool, open }: YmlFileStepProps) {
export function YmlFileStep({
appState: { branchesEnabled },
buildTool,
open,
projectKey
}: YmlFileStepProps) {
const renderForm = () => (
<div className="boxed-group-inner">
<div className="flex-columns">
@@ -61,7 +67,11 @@ export function YmlFileStep({ appState: { branchesEnabled }, buildTool, open }:
</div>

<div className="big-spacer-bottom">
<PipeCommand buildTool={buildTool} branchesEnabled={branchesEnabled} />
<PipeCommand
buildTool={buildTool}
branchesEnabled={branchesEnabled}
projectKey={projectKey}
/>
</div>

<p className="little-spacer-bottom">

+ 3
- 2
server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/ProjectKeyStep-test.tsx View File

@@ -22,8 +22,9 @@ import * as React from 'react';
import { mockComponent } from '../../../../helpers/testMocks';
import RenderOptions from '../../components/RenderOptions';
import { renderStepContent } from '../../jenkins/test-utils';
import { BuildTools } from '../../types';
import ProjectKeyStep, { ProjectKeyStepProps } from '../ProjectKeyStep';
import { BuildTools } from '../types';
import { GITLAB_BUILDTOOLS_LIST } from '../types';

it('should render correctly', () => {
const wrapper = shallowRender();
@@ -31,7 +32,7 @@ it('should render correctly', () => {
expect(renderStepContent(wrapper)).toMatchSnapshot('initial content');
});

it.each([[BuildTools.Maven], [BuildTools.Gradle], [BuildTools.Other]])(
it.each(GITLAB_BUILDTOOLS_LIST.map(tool => [tool]))(
'should render correctly for build tool %s',
buildTool => {
expect(renderStepContent(shallowRender({ buildTool }))).toMatchSnapshot();

+ 8
- 3
server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx View File

@@ -21,7 +21,7 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import { mockAppState } from '../../../../helpers/testMocks';
import { renderStepContent } from '../../jenkins/test-utils';
import { BuildTools } from '../types';
import { GITLAB_BUILDTOOLS_LIST } from '../types';
import { YmlFileStep, YmlFileStepProps } from '../YmlFileStep';

it('should render correctly', () => {
@@ -30,7 +30,7 @@ it('should render correctly', () => {
expect(renderStepContent(wrapper)).toMatchSnapshot('initial content');
});

it.each([[BuildTools.Maven], [BuildTools.Gradle], [BuildTools.Other]])(
it.each(GITLAB_BUILDTOOLS_LIST.map(tool => [tool]))(
'should render correctly for build tool %s',
buildTool => {
expect(renderStepContent(shallowRender({ buildTool }))).toMatchSnapshot();
@@ -39,6 +39,11 @@ it.each([[BuildTools.Maven], [BuildTools.Gradle], [BuildTools.Other]])(

function shallowRender(props: Partial<YmlFileStepProps> = {}) {
return shallow<YmlFileStepProps>(
<YmlFileStep appState={mockAppState({ branchesEnabled: true })} open={true} {...props} />
<YmlFileStep
appState={mockAppState({ branchesEnabled: true })}
open={true}
projectKey="test"
{...props}
/>
);
}

+ 1
- 0
server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/GitLabCITutorial-test.tsx.snap View File

@@ -80,6 +80,7 @@ exports[`should render correctly 1`] = `
/>
<Connect(withAppState(YmlFileStep))
open={false}
projectKey="my-project"
/>
</Fragment>
`;

+ 37
- 0
server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/ProjectKeyStep-test.tsx.snap View File

@@ -1,5 +1,38 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly for build tool dotnet 1`] = `
<div
className="boxed-group-inner"
>
<ol
className="list-styled"
>
<li>
onboarding.build
<RenderOptions
checked="dotnet"
name="buildtool"
onCheck={[Function]}
optionLabelKey="onboarding.build"
options={
Array [
"maven",
"gradle",
"dotnet",
"other",
]
}
/>
</li>
</ol>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

exports[`should render correctly for build tool gradle 1`] = `
<div
className="boxed-group-inner"
@@ -18,6 +51,7 @@ exports[`should render correctly for build tool gradle 1`] = `
Array [
"maven",
"gradle",
"dotnet",
"other",
]
}
@@ -85,6 +119,7 @@ exports[`should render correctly for build tool maven 1`] = `
Array [
"maven",
"gradle",
"dotnet",
"other",
]
}
@@ -146,6 +181,7 @@ exports[`should render correctly for build tool other 1`] = `
Array [
"maven",
"gradle",
"dotnet",
"other",
]
}
@@ -216,6 +252,7 @@ exports[`should render correctly: initial content 1`] = `
Array [
"maven",
"gradle",
"dotnet",
"other",
]
}

+ 115
- 0
server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/YmlFileStep-test.tsx.snap View File

@@ -1,5 +1,117 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly for build tool dotnet 1`] = `
<div
className="boxed-group-inner"
>
<div
className="flex-columns"
>
<div
className="flex-column-full"
>
<React.Fragment>
<div
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.gitlab_ci.yml.description"
id="onboarding.tutorial.with.gitlab_ci.yml.description"
values={
Object {
"filename": <React.Fragment>
<code
className="rule"
>
onboarding.tutorial.with.gitlab_ci.yml.filename
</code>
<ClipboardIconButton
className="little-spacer-left"
copyValue="onboarding.tutorial.with.gitlab_ci.yml.filename"
/>
</React.Fragment>,
}
}
/>
</div>
<div
className="big-spacer-bottom"
>
<PipeCommand
branchesEnabled={true}
buildTool="dotnet"
projectKey="test"
/>
</div>
<p
className="little-spacer-bottom"
>
onboarding.tutorial.with.gitlab_ci.yml.baseconfig
</p>
<p
className="huge-spacer-bottom"
>
onboarding.tutorial.with.gitlab_ci.yml.existing
</p>
<hr
className="no-horizontal-margins"
/>
<div>
<p
className="big-spacer-bottom"
>
<strong>
onboarding.tutorial.with.gitlab_ci.yml.done
</strong>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.gitlab_ci.yml.done.description"
id="onboarding.tutorial.with.gitlab_ci.yml.done.description"
values={
Object {
"link": "onboarding.tutorial.with.gitlab_ci.yml.done.description.link",
}
}
/>
</p>
<p
className="big-spacer-bottom"
>
<strong>
onboarding.tutorial.with.gitlab_ci.yml.done.then-what
</strong>
onboarding.tutorial.with.gitlab_ci.yml.done.then-what.description
</p>
<p
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.gitlab_ci.yml.done.links.title"
id="onboarding.tutorial.with.gitlab_ci.yml.done.links.title"
values={
Object {
"links": <Link
onlyActiveOnIndex={false}
rel="noopener noreferrer"
style={Object {}}
target="_blank"
to="/documentation/user-guide/quality-gates/"
>
onboarding.tutorial.with.gitlab_ci.yml.done.links.QG
</Link>,
}
}
/>
</p>
</div>
</React.Fragment>
</div>
</div>
</div>
`;

exports[`should render correctly for build tool gradle 1`] = `
<div
className="boxed-group-inner"
@@ -40,6 +152,7 @@ exports[`should render correctly for build tool gradle 1`] = `
<PipeCommand
branchesEnabled={true}
buildTool="gradle"
projectKey="test"
/>
</div>
<p
@@ -151,6 +264,7 @@ exports[`should render correctly for build tool maven 1`] = `
<PipeCommand
branchesEnabled={true}
buildTool="maven"
projectKey="test"
/>
</div>
<p
@@ -262,6 +376,7 @@ exports[`should render correctly for build tool other 1`] = `
<PipeCommand
branchesEnabled={true}
buildTool="other"
projectKey="test"
/>
</div>
<p

+ 20
- 7
server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx View File

@@ -19,30 +19,43 @@
*/
import * as React from 'react';
import CodeSnippet from '../../../common/CodeSnippet';
import { BuildTools } from '../types';
import { BuildTools } from '../../types';
import { GitlabBuildTools } from '../types';

export interface PipeCommandProps {
branchesEnabled?: boolean;
buildTool: BuildTools;
buildTool: GitlabBuildTools;
projectKey: string;
}

const BUILD_TOOL_SPECIFIC = {
[BuildTools.Gradle]: { image: 'gradle:jre11-slim', script: 'gradle sonarqube' },
[BuildTools.Gradle]: { image: 'gradle:jre11-slim', script: () => 'gradle sonarqube' },
[BuildTools.Maven]: {
image: 'maven:3.6.3-jdk-11',
script: `
script: () => `
- mvn verify sonar:sonar`
},
[BuildTools.DotNet]: {
image: 'mcr.microsoft.com/dotnet/core/sdk:latest',
script: (projectKey: string) => `
- "apt-get update"
- "apt-get install --yes openjdk-11-jre"
- "dotnet tool install --global dotnet-sonarscanner"
- "export PATH=\\"$PATH:$HOME/.dotnet/tools\\""
- "dotnet sonarscanner begin /k:\\"${projectKey}\\" /d:sonar.login=\\"$SONAR_TOKEN\\" /d:\\"sonar.host.url=$SONAR_HOST_URL\\" "
- "dotnet build"
- "dotnet sonarscanner end /d:sonar.login=\\"$SONAR_TOKEN\\""`
},
[BuildTools.Other]: {
image: `
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]`,
script: `
script: () => `
- sonar-scanner`
}
};

export default function PipeCommand({ branchesEnabled, buildTool }: PipeCommandProps) {
export default function PipeCommand({ projectKey, branchesEnabled, buildTool }: PipeCommandProps) {
const onlyBlock = branchesEnabled
? `- merge_requests
- master
@@ -60,7 +73,7 @@ export default function PipeCommand({ branchesEnabled, buildTool }: PipeCommandP
key: "\${CI_JOB_NAME}"
paths:
- .sonar/cache
script: ${script}
script: ${script(projectKey)}
allow_failure: true
only:
${onlyBlock}

+ 9
- 12
server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/PipeCommand-test.tsx View File

@@ -19,17 +19,14 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
import { BuildTools } from '../../types';
import { GITLAB_BUILDTOOLS_LIST } from '../../types';
import PipeCommand from '../PipeCommand';

it.each([[BuildTools.Gradle], [BuildTools.Maven], [BuildTools.Other]])(
'should render correctly for %s',
buildTool => {
expect(shallow(<PipeCommand buildTool={buildTool} branchesEnabled={true} />)).toMatchSnapshot(
'branches enabled'
);
expect(shallow(<PipeCommand buildTool={buildTool} branchesEnabled={true} />)).toMatchSnapshot(
'branches not enabled'
);
}
);
it.each(GITLAB_BUILDTOOLS_LIST.map(tool => [tool]))('should render correctly for %s', buildTool => {
expect(
shallow(<PipeCommand buildTool={buildTool} branchesEnabled={true} projectKey="test" />)
).toMatchSnapshot('branches enabled');
expect(
shallow(<PipeCommand buildTool={buildTool} branchesEnabled={true} projectKey="test" />)
).toMatchSnapshot('branches not enabled');
});

+ 56
- 0
server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/__snapshots__/PipeCommand-test.tsx.snap View File

@@ -1,5 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly for dotnet: branches enabled 1`] = `
<CodeSnippet
snippet="sonarqube-check:
image: mcr.microsoft.com/dotnet/core/sdk:latest
variables:
SONAR_USER_HOME: \\"\${CI_PROJECT_DIR}/.sonar\\" # Defines the location of the analysis task cache
GIT_DEPTH: \\"0\\" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: \\"\${CI_JOB_NAME}\\"
paths:
- .sonar/cache
script:
- \\"apt-get update\\"
- \\"apt-get install --yes openjdk-11-jre\\"
- \\"dotnet tool install --global dotnet-sonarscanner\\"
- \\"export PATH=\\\\\\"$PATH:$HOME/.dotnet/tools\\\\\\"\\"
- \\"dotnet sonarscanner begin /k:\\\\\\"test\\\\\\" /d:sonar.login=\\\\\\"$SONAR_TOKEN\\\\\\" /d:\\\\\\"sonar.host.url=$SONAR_HOST_URL\\\\\\" \\"
- \\"dotnet build\\"
- \\"dotnet sonarscanner end /d:sonar.login=\\\\\\"$SONAR_TOKEN\\\\\\"\\"
allow_failure: true
only:
- merge_requests
- master
- develop
"
/>
`;

exports[`should render correctly for dotnet: branches not enabled 1`] = `
<CodeSnippet
snippet="sonarqube-check:
image: mcr.microsoft.com/dotnet/core/sdk:latest
variables:
SONAR_USER_HOME: \\"\${CI_PROJECT_DIR}/.sonar\\" # Defines the location of the analysis task cache
GIT_DEPTH: \\"0\\" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: \\"\${CI_JOB_NAME}\\"
paths:
- .sonar/cache
script:
- \\"apt-get update\\"
- \\"apt-get install --yes openjdk-11-jre\\"
- \\"dotnet tool install --global dotnet-sonarscanner\\"
- \\"export PATH=\\\\\\"$PATH:$HOME/.dotnet/tools\\\\\\"\\"
- \\"dotnet sonarscanner begin /k:\\\\\\"test\\\\\\" /d:sonar.login=\\\\\\"$SONAR_TOKEN\\\\\\" /d:\\\\\\"sonar.host.url=$SONAR_HOST_URL\\\\\\" \\"
- \\"dotnet build\\"
- \\"dotnet sonarscanner end /d:sonar.login=\\\\\\"$SONAR_TOKEN\\\\\\"\\"
allow_failure: true
only:
- merge_requests
- master
- develop
"
/>
`;

exports[`should render correctly for gradle: branches enabled 1`] = `
<CodeSnippet
snippet="sonarqube-check:

+ 15
- 6
server/sonar-web/src/main/js/components/tutorials/gitlabci/types.ts View File

@@ -17,9 +17,18 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
export enum BuildTools {
Maven = 'maven',
Gradle = 'gradle',
// MSBuild = 'msbuild', // Not yet supported
Other = 'other'
}

import { BuildTools } from '../types';

export type GitlabBuildTools =
| BuildTools.Maven
| BuildTools.Gradle
| BuildTools.DotNet
| BuildTools.Other;

export const GITLAB_BUILDTOOLS_LIST: GitlabBuildTools[] = [
BuildTools.Maven,
BuildTools.Gradle,
BuildTools.DotNet,
BuildTools.Other
];

+ 2
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties View File

@@ -3396,6 +3396,8 @@ onboarding.tutorial.with.gitlab_ci.project_key.title=Set your project key
onboarding.tutorial.with.gitlab_ci.project_key.maven.step2=Add the following to your {file} file:
onboarding.tutorial.with.gitlab_ci.project_key.gradle.step2=Add the following to your {file} 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.env_variables.title=Add environment variables
onboarding.tutorial.with.gitlab_ci.env_variables.enter_field_value=In the {field} field, enter {value} {extra}

Loading…
Cancel
Save