@@ -20,7 +20,7 @@ | |||
import * as React from 'react'; | |||
import { WithRouterProps } from 'react-router'; | |||
import { getAlmDefinitionsNoCatch, getProjectAlmBinding } from '../../api/alm-settings'; | |||
import { AlmBindingDefinition, AlmKeys, ProjectAlmBindingResponse } from '../../types/alm-settings'; | |||
import { AlmBindingDefinition, ProjectAlmBindingResponse } from '../../types/alm-settings'; | |||
import { withRouter } from '../hoc/withRouter'; | |||
import TutorialSelectionRenderer from './TutorialSelectionRenderer'; | |||
import { TutorialModes } from './types'; | |||
@@ -58,11 +58,7 @@ export class TutorialSelection extends React.PureComponent<Props, State> { | |||
]); | |||
if (this.mounted) { | |||
// We only support Bitbucket, GitHub & Gitlab for now. | |||
if ( | |||
projectBinding === undefined || | |||
![AlmKeys.Bitbucket, AlmKeys.GitHub, AlmKeys.GitLab].includes(projectBinding.alm) | |||
) { | |||
if (projectBinding === undefined) { | |||
this.setState({ loading: false, forceManual: true }); | |||
} else { | |||
let almBinding; |
@@ -22,6 +22,7 @@ import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getBaseUrl } from 'sonar-ui-common/helpers/urls'; | |||
import { AlmBindingDefinition, AlmKeys, ProjectAlmBindingResponse } from '../../types/alm-settings'; | |||
import AzurePipelinesTutorial from './azure-pipelines/AzurePipelinesTutorial'; | |||
import GitLabCITutorial from './gitlabci/GitLabCITutorial'; | |||
import JenkinsTutorial from './jenkins/JenkinsTutorial'; | |||
import ManualTutorial from './manual/ManualTutorial'; | |||
@@ -74,6 +75,22 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender | |||
</button> | |||
)} | |||
{projectBinding?.alm === AlmKeys.Azure && ( | |||
<button | |||
className="button button-huge display-flex-column spacer-left spacer-right azure-pipelines" | |||
onClick={() => props.onSelectTutorial(TutorialModes.AzurePipelines)} | |||
type="button"> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
height={80} | |||
src={`${getBaseUrl()}/images/alm/azure.svg`} | |||
/> | |||
<div className="medium big-spacer-top"> | |||
{translate('onboarding.tutorial.choose_method.azure_pipelines')} | |||
</div> | |||
</button> | |||
)} | |||
{jenkinsAvailable && ( | |||
<button | |||
className="button button-huge display-flex-column spacer-left spacer-right tutorial-mode-jenkins" | |||
@@ -126,6 +143,14 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender | |||
projectBinding={projectBinding} | |||
/> | |||
)} | |||
{selectedTutorial === TutorialModes.AzurePipelines && projectBinding !== undefined && ( | |||
<AzurePipelinesTutorial | |||
component={component} | |||
currentUser={currentUser} | |||
projectBinding={projectBinding} | |||
/> | |||
)} | |||
</> | |||
); | |||
} |
@@ -50,20 +50,13 @@ it('should select manual if project is not bound', async () => { | |||
expect(wrapper.state().forceManual).toBe(true); | |||
}); | |||
it('should not select anything if project is bound to Bitbucket', async () => { | |||
it('should not select anything if project is bound', async () => { | |||
(getProjectAlmBinding as jest.Mock).mockResolvedValueOnce({ alm: AlmKeys.Bitbucket }); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().forceManual).toBe(false); | |||
}); | |||
it('should select manual if project is bound to unsupported ALM', async () => { | |||
(getProjectAlmBinding as jest.Mock).mockResolvedValueOnce({ alm: AlmKeys.Azure }); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().forceManual).toBe(true); | |||
}); | |||
it('should correctly find the global ALM binding definition', async () => { | |||
const key = 'foo'; | |||
const almBinding = mockBitbucketBindingDefinition({ key }); |
@@ -23,6 +23,7 @@ import * as React from 'react'; | |||
import { click } from 'sonar-ui-common/helpers/testUtils'; | |||
import { | |||
mockBitbucketBindingDefinition, | |||
mockProjectAzureBindingResponse, | |||
mockProjectBitbucketBindingResponse, | |||
mockProjectGitLabBindingResponse | |||
} from '../../../helpers/mocks/alm-settings'; | |||
@@ -53,6 +54,12 @@ it('should render correctly', () => { | |||
projectBinding: mockProjectGitLabBindingResponse() | |||
}) | |||
).toMatchSnapshot('gitlab tutorial'); | |||
expect( | |||
shallowRender({ | |||
selectedTutorial: TutorialModes.AzurePipelines, | |||
projectBinding: mockProjectAzureBindingResponse() | |||
}) | |||
).toMatchSnapshot('azure pipelines tutorial'); | |||
}); | |||
it('should allow mode selection', () => { | |||
@@ -80,6 +87,17 @@ it('should allow gitlab selection', () => { | |||
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.GitLabCI); | |||
}); | |||
it('should allow azure pipelines selection', () => { | |||
const onSelectTutorial = jest.fn(); | |||
const wrapper = shallowRender({ | |||
onSelectTutorial, | |||
projectBinding: mockProjectAzureBindingResponse() | |||
}); | |||
click(wrapper.find('button.azure-pipelines')); | |||
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.AzurePipelines); | |||
}); | |||
function shallowRender(props: Partial<TutorialSelectionRendererProps> = {}) { | |||
return shallow<TutorialSelectionRendererProps>( | |||
<TutorialSelectionRenderer |
@@ -1,5 +1,53 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: azure pipelines tutorial 1`] = ` | |||
<Fragment> | |||
<AzurePipelinesTutorial | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
currentUser={ | |||
Object { | |||
"groups": Array [], | |||
"isLoggedIn": true, | |||
"login": "luke", | |||
"name": "Skywalker", | |||
"scmAccounts": Array [], | |||
} | |||
} | |||
projectBinding={ | |||
Object { | |||
"alm": "azure", | |||
"key": "foo", | |||
"repository": "REPOSITORY_NAME", | |||
"slug": "PROJECT_NAME", | |||
"url": "https://ado.my_company.com/mycollection", | |||
} | |||
} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: gitlab tutorial 1`] = ` | |||
<Fragment> | |||
<GitLabCITutorial |
@@ -0,0 +1,130 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 * as React from 'react'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
isProjectAzureBindingResponse, | |||
ProjectAlmBindingResponse | |||
} from '../../../types/alm-settings'; | |||
import Step from '../components/Step'; | |||
import BranchAnalysisStepContent from './BranchAnalysisStepContent'; | |||
import ExtensionInstallationStepContent from './ExtensionInstallationStepContent'; | |||
import SaveAndRunStepContent from './SaveAndRunStepContent'; | |||
import ServiceEndpointStepContent from './ServiceEndpointStepContent'; | |||
export interface AzurePipelinesTutorialProps { | |||
component: T.Component; | |||
currentUser: T.LoggedInUser; | |||
projectBinding: ProjectAlmBindingResponse; | |||
} | |||
export enum Steps { | |||
ExtensionInstallation, | |||
ServiceEndpoint, | |||
BranchAnalysis, | |||
SaveAndRun | |||
} | |||
interface Step { | |||
step: Steps; | |||
content: JSX.Element; | |||
checkValidity?: boolean; | |||
} | |||
export default function AzurePipelinesTutorial(props: AzurePipelinesTutorialProps) { | |||
const { component, currentUser, projectBinding } = props; | |||
const [currentStep, setCurrentStep] = React.useState(Steps.ExtensionInstallation); | |||
const [isCurrentStepValid, setIsCurrentStepValid] = React.useState(false); | |||
// Failsafe; should never happen. | |||
if (!isProjectAzureBindingResponse(projectBinding)) { | |||
return ( | |||
<Alert variant="error"> | |||
{translate('onboarding.tutorial.with.azure_pipelines.unsupported')} | |||
</Alert> | |||
); | |||
} | |||
const steps: Array<Step> = [ | |||
{ step: Steps.ExtensionInstallation, content: <ExtensionInstallationStepContent /> }, | |||
{ | |||
step: Steps.ServiceEndpoint, | |||
content: <ServiceEndpointStepContent component={component} currentUser={currentUser} /> | |||
}, | |||
{ | |||
step: Steps.BranchAnalysis, | |||
content: ( | |||
<BranchAnalysisStepContent | |||
component={component} | |||
onStepValidationChange={isValid => setIsCurrentStepValid(isValid)} | |||
/> | |||
), | |||
checkValidity: true | |||
}, | |||
{ step: Steps.SaveAndRun, content: <SaveAndRunStepContent /> } | |||
]; | |||
const switchCurrentStep = (step: Steps) => { | |||
setCurrentStep(step); | |||
setIsCurrentStepValid(false); | |||
}; | |||
const canContinue = (step: Step, i: number) => | |||
i < steps.length - 1 && (!step.checkValidity || isCurrentStepValid); | |||
return ( | |||
<> | |||
<div className="page-header big-spacer-bottom"> | |||
<h1 className="page-title"> | |||
{translate('onboarding.tutorial.with.azure_pipelines.title')} | |||
</h1> | |||
</div> | |||
{steps.map((step, i) => ( | |||
<Step | |||
key={step.step} | |||
stepNumber={i + 1} | |||
stepTitle={translate( | |||
`onboarding.tutorial.with.azure_pipelines.${Steps[step.step]}.title` | |||
)} | |||
open={step.step === currentStep} | |||
finished={step.step < currentStep} | |||
onOpen={() => switchCurrentStep(step.step)} | |||
renderForm={() => ( | |||
<div className="boxed-group-inner"> | |||
<div>{step.content}</div> | |||
{canContinue(step, i) && ( | |||
<Button | |||
className="big-spacer-top spacer-bottom" | |||
onClick={() => switchCurrentStep(step.step + 1)}> | |||
{translate('continue')} | |||
</Button> | |||
)} | |||
</div> | |||
)} | |||
/> | |||
))} | |||
</> | |||
); | |||
} |
@@ -0,0 +1,208 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import { ClipboardIconButton } from 'sonar-ui-common/components/controls/clipboard'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n'; | |||
import CodeSnippet from '../../common/CodeSnippet'; | |||
import RenderOptions from '../components/RenderOptions'; | |||
import SentenceWithHighlights from '../components/SentenceWithHighlights'; | |||
export interface BranchesAnalysisStepProps { | |||
component: T.Component; | |||
onStepValidationChange: (isValid: boolean) => void; | |||
} | |||
export enum BuildTechnology { | |||
DotNet = 'dotnet', | |||
Maven = 'maven', | |||
Gradle = 'gradle', | |||
Other = 'other' | |||
} | |||
export default function BranchAnalysisStepContent(props: BranchesAnalysisStepProps) { | |||
const { component, onStepValidationChange } = props; | |||
const [buildTechnology, setBuildTechnology] = React.useState<BuildTechnology | undefined>(); | |||
React.useEffect(() => { | |||
if (buildTechnology) { | |||
onStepValidationChange(true); | |||
} | |||
}, [buildTechnology, onStepValidationChange]); | |||
const MAVEN_GRADLE_PROPS_SNIPPET = `# Additional properties that will be passed to the scanner, | |||
# Put one key=value per line, example: | |||
# sonar.exclusions=**/*.bin | |||
sonar.projectKey=${component.key}`; | |||
return ( | |||
<> | |||
<span>{translate('onboarding.build')}</span> | |||
<RenderOptions | |||
checked={buildTechnology} | |||
name="buildTechnology" | |||
onCheck={value => setBuildTechnology(value as BuildTechnology)} | |||
optionLabelKey="onboarding.build" | |||
options={Object.values(BuildTechnology)} | |||
/> | |||
<ol className="list-styled big-spacer-top"> | |||
{buildTechnology && ( | |||
<> | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare" | |||
highlightKeys={['pipeline', 'task', 'before']} | |||
/> | |||
</li> | |||
<ul className="list-styled"> | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.endpoint" | |||
highlightKeys={['endpoint']} | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis' | |||
)} | |||
values={{ | |||
section: ( | |||
<strong> | |||
{translate( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.section' | |||
)} | |||
</strong> | |||
), | |||
run_analysis_value: ( | |||
<strong> | |||
{translate( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values', | |||
buildTechnology | |||
)} | |||
</strong> | |||
) | |||
}} | |||
/> | |||
</li> | |||
{buildTechnology === BuildTechnology.Other && ( | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.manual" | |||
highlightKeys={['mode']} | |||
/> | |||
</li> | |||
)} | |||
{[BuildTechnology.DotNet, BuildTechnology.Other].includes(buildTechnology) && ( | |||
<li> | |||
<FormattedMessage | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence" | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence' | |||
)} | |||
values={{ | |||
key: <code className="rule">{component.key}</code>, | |||
button: <ClipboardIconButton copyValue={component.key} /> | |||
}} | |||
/> | |||
</li> | |||
)} | |||
{[BuildTechnology.Maven, BuildTechnology.Gradle].includes(buildTechnology) && ( | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.advanced_properties" | |||
highlightKeys={['section', 'properties']} | |||
/> | |||
: | |||
<CodeSnippet snippet={MAVEN_GRADLE_PROPS_SNIPPET} /> | |||
</li> | |||
)} | |||
</ul> | |||
{[BuildTechnology.DotNet, BuildTechnology.Other].includes(buildTechnology) && ( | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run" | |||
highlightKeys={['task', 'after']} | |||
/> | |||
</li> | |||
)} | |||
{[BuildTechnology.Maven, BuildTechnology.Gradle].includes(buildTechnology) && ( | |||
<> | |||
<li> | |||
{translateWithParameters( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java', | |||
translate('onboarding.build', buildTechnology) | |||
)} | |||
</li> | |||
<ul className="list-styled big-spacer-bottom"> | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.settings" | |||
highlightKeys={['section', 'option']} | |||
/> | |||
</li> | |||
</ul> | |||
</> | |||
)} | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg" | |||
highlightKeys={['task']} | |||
/> | |||
<Alert variant="info" className="spacer-top"> | |||
{translate( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.info.sentence1' | |||
)} | |||
</Alert> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration" | |||
highlightKeys={['tab', 'continuous_integration']} | |||
/> | |||
</li> | |||
<hr /> | |||
<FormattedMessage | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection' | |||
)} | |||
values={{ | |||
link: ( | |||
<Link to="/documentation/analysis/azuredevops-integration/" target="_blank"> | |||
{translate( | |||
'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link' | |||
)} | |||
</Link> | |||
) | |||
}} | |||
/> | |||
</> | |||
)} | |||
</ol> | |||
</> | |||
); | |||
} |
@@ -0,0 +1,55 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
export default function ExtensionInstallationStepContent() { | |||
return ( | |||
<span> | |||
<FormattedMessage | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence' | |||
)} | |||
id="onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence" | |||
values={{ | |||
link: ( | |||
<a | |||
href="https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarqube" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate( | |||
'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence.link' | |||
)} | |||
</a> | |||
), | |||
button: ( | |||
<strong> | |||
{translate( | |||
'onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence.button' | |||
)} | |||
</strong> | |||
) | |||
}} | |||
/> | |||
</span> | |||
); | |||
} |
@@ -0,0 +1,66 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getBaseUrl } from '../../../helpers/system'; | |||
export default function SaveAndRunStepContent() { | |||
return ( | |||
<> | |||
<div className="display-flex-row big-spacer-bottom"> | |||
<div> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
className="big-spacer-right" | |||
width={30} | |||
src={`${getBaseUrl()}/images/tutorials/commit.svg`} | |||
/> | |||
</div> | |||
<div> | |||
<p className="little-spacer-bottom"> | |||
<strong> | |||
{translate('onboarding.tutorial.with.azure_pipelines.SaveAndRun.commit')} | |||
</strong> | |||
</p> | |||
<p>{translate('onboarding.tutorial.with.azure_pipelines.SaveAndRun.commit.why')}</p> | |||
</div> | |||
</div> | |||
<div className="display-flex-row"> | |||
<div> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
className="big-spacer-right" | |||
width={30} | |||
src={`${getBaseUrl()}/images/tutorials/refresh.svg`} | |||
/> | |||
</div> | |||
<div> | |||
<p className="little-spacer-bottom"> | |||
<strong> | |||
{translate('onboarding.tutorial.with.azure_pipelines.SaveAndRun.refresh')} | |||
</strong> | |||
</p> | |||
<p>{translate('onboarding.tutorial.with.azure_pipelines.SaveAndRun.refresh.why')}</p> | |||
</div> | |||
</div> | |||
</> | |||
); | |||
} |
@@ -0,0 +1,92 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { ClipboardIconButton } from 'sonar-ui-common/components/controls/clipboard'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getHostUrl } from 'sonar-ui-common/helpers/urls'; | |||
import EditTokenModal from '../components/EditTokenModal'; | |||
import SentenceWithHighlights from '../components/SentenceWithHighlights'; | |||
export interface ServiceEndpointStepProps { | |||
component: T.Component; | |||
currentUser: T.LoggedInUser; | |||
} | |||
export default function ServiceEndpointStepContent(props: ServiceEndpointStepProps) { | |||
const { component, currentUser } = props; | |||
const [isModalVisible, toggleModal] = React.useState(false); | |||
return ( | |||
<> | |||
<ol className="list-styled"> | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step1" | |||
highlightKeys={['menu']} | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
translationKey="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step2" | |||
highlightKeys={['type']} | |||
/> | |||
</li> | |||
<li> | |||
{translate('onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step3.sentence')} | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step4.sentence' | |||
)} | |||
id="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step4.sentence" | |||
values={{ | |||
url: <code className="rule">{getHostUrl()}</code>, | |||
button: <ClipboardIconButton copyValue={getHostUrl()} /> | |||
}} | |||
/> | |||
</li> | |||
<li> | |||
<span> | |||
{translate('onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step5.sentence')}: | |||
</span> | |||
<Button className="spacer-left" onClick={() => toggleModal(true)}> | |||
{translate('onboarding.token.generate_token')} | |||
</Button> | |||
</li> | |||
<li> | |||
{translate('onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step6.sentence')} | |||
</li> | |||
</ol> | |||
{isModalVisible && ( | |||
<EditTokenModal | |||
component={component} | |||
currentUser={currentUser} | |||
onClose={() => toggleModal(false)} | |||
/> | |||
)} | |||
</> | |||
); | |||
} |
@@ -0,0 +1,111 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { click } from 'sonar-ui-common/helpers/testUtils'; | |||
import { | |||
mockProjectAzureBindingResponse, | |||
mockProjectGithubBindingResponse | |||
} from '../../../../helpers/mocks/alm-settings'; | |||
import { mockComponent, mockLoggedInUser } from '../../../../helpers/testMocks'; | |||
import Step from '../../components/Step'; | |||
import AzurePipelinesTutorial, { AzurePipelinesTutorialProps } from '../AzurePipelinesTutorial'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
expect( | |||
wrapper | |||
.find(Step) | |||
.first() | |||
.dive() | |||
).toMatchSnapshot('first-step-wrapper'); | |||
expect( | |||
wrapper | |||
.find(Step) | |||
.last() | |||
.dive() | |||
).toMatchSnapshot('last-step-wrapper'); | |||
expect(shallowRender({ projectBinding: mockProjectGithubBindingResponse() })).toMatchSnapshot( | |||
'wrong alm' | |||
); | |||
}); | |||
it('should display the next step when one is finished', () => { | |||
const wrapper = shallowRender(); | |||
expect( | |||
wrapper | |||
.find(Step) | |||
.filterWhere(elt => elt.props().open === true) | |||
.props().stepNumber | |||
).toBe(1); | |||
click( | |||
wrapper | |||
.find(Step) | |||
.first() | |||
.dive() | |||
.find(Button) | |||
); | |||
expect( | |||
wrapper | |||
.find(Step) | |||
.filterWhere(elt => elt.props().open === true) | |||
.props().stepNumber | |||
).toBe(2); | |||
}); | |||
it('should open a step when user click on it', () => { | |||
const wrapper = shallowRender(); | |||
expect( | |||
wrapper | |||
.find(Step) | |||
.filterWhere(elt => elt.props().open === true) | |||
.props().stepNumber | |||
).toBe(1); | |||
( | |||
wrapper | |||
.find(Step) | |||
.filterWhere(elt => elt.props().stepNumber === 3) | |||
.props().onOpen ?? (() => {}) | |||
)(); | |||
expect( | |||
wrapper | |||
.find(Step) | |||
.filterWhere(elt => elt.props().open === true) | |||
.props().stepNumber | |||
).toBe(3); | |||
}); | |||
function shallowRender(props: Partial<AzurePipelinesTutorialProps> = {}) { | |||
return shallow<AzurePipelinesTutorialProps>( | |||
<AzurePipelinesTutorial | |||
component={mockComponent()} | |||
currentUser={mockLoggedInUser()} | |||
projectBinding={mockProjectAzureBindingResponse()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,58 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../helpers/testMocks'; | |||
import RenderOptions from '../../components/RenderOptions'; | |||
import BranchAnalysisStepContent, { | |||
BranchesAnalysisStepProps, | |||
BuildTechnology | |||
} from '../BranchAnalysisStepContent'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it.each([ | |||
BuildTechnology.DotNet, | |||
BuildTechnology.Gradle, | |||
BuildTechnology.Maven, | |||
BuildTechnology.Other | |||
])('should render correctly', (buildTech: BuildTechnology) => { | |||
const wrapper = shallowRender(); | |||
wrapper | |||
.find(RenderOptions) | |||
.props() | |||
.onCheck(buildTech); | |||
expect(wrapper).toMatchSnapshot(buildTech); | |||
}); | |||
function shallowRender(props: Partial<BranchesAnalysisStepProps> = {}) { | |||
return shallow( | |||
<BranchAnalysisStepContent | |||
component={mockComponent()} | |||
onStepValidationChange={jest.fn()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import ExtensionInstallationStepContent from '../ExtensionInstallationStepContent'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
function shallowRender() { | |||
return shallow(<ExtensionInstallationStepContent />); | |||
} |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import SaveAndRunStepContent from '../SaveAndRunStepContent'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
function shallowRender() { | |||
return shallow(<SaveAndRunStepContent />); | |||
} |
@@ -0,0 +1,52 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { click } from 'sonar-ui-common/helpers/testUtils'; | |||
import { mockComponent, mockLoggedInUser } from '../../../../helpers/testMocks'; | |||
import EditTokenModal from '../../components/EditTokenModal'; | |||
import ServiceEndpointStepContent from '../ServiceEndpointStepContent'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it('should render open/close the token modal when asked to', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper.exists(EditTokenModal)).toBe(false); | |||
click(wrapper.find(Button)); | |||
expect(wrapper.exists(EditTokenModal)).toBe(true); | |||
wrapper | |||
.find(EditTokenModal) | |||
.props() | |||
.onClose(); | |||
expect(wrapper.exists(EditTokenModal)).toBe(false); | |||
}); | |||
function shallowRender() { | |||
return shallow( | |||
<ServiceEndpointStepContent component={mockComponent()} currentUser={mockLoggedInUser()} /> | |||
); | |||
} |
@@ -0,0 +1,128 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<div | |||
className="page-header big-spacer-bottom" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.title | |||
</h1> | |||
</div> | |||
<Step | |||
finished={false} | |||
key="0" | |||
onOpen={[Function]} | |||
open={true} | |||
renderForm={[Function]} | |||
stepNumber={1} | |||
stepTitle="onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title" | |||
/> | |||
<Step | |||
finished={false} | |||
key="1" | |||
onOpen={[Function]} | |||
open={false} | |||
renderForm={[Function]} | |||
stepNumber={2} | |||
stepTitle="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.title" | |||
/> | |||
<Step | |||
finished={false} | |||
key="2" | |||
onOpen={[Function]} | |||
open={false} | |||
renderForm={[Function]} | |||
stepNumber={3} | |||
stepTitle="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.title" | |||
/> | |||
<Step | |||
finished={false} | |||
key="3" | |||
onOpen={[Function]} | |||
open={false} | |||
renderForm={[Function]} | |||
stepNumber={4} | |||
stepTitle="onboarding.tutorial.with.azure_pipelines.SaveAndRun.title" | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: first-step-wrapper 1`] = ` | |||
<div | |||
className="boxed-group onboarding-step is-open" | |||
> | |||
<div | |||
className="onboarding-step-number" | |||
> | |||
1 | |||
</div> | |||
<div | |||
className="boxed-group-header" | |||
> | |||
<h2> | |||
onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title | |||
</h2> | |||
</div> | |||
<div | |||
className="" | |||
> | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<div> | |||
<ExtensionInstallationStepContent /> | |||
</div> | |||
<Button | |||
className="big-spacer-top spacer-bottom" | |||
onClick={[Function]} | |||
> | |||
continue | |||
</Button> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly: last-step-wrapper 1`] = ` | |||
<div | |||
className="boxed-group onboarding-step" | |||
> | |||
<div | |||
className="onboarding-step-number" | |||
> | |||
4 | |||
</div> | |||
<div | |||
className="boxed-group-header" | |||
> | |||
<h2> | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.title | |||
</h2> | |||
</div> | |||
<div | |||
className="boxed-group-inner" | |||
/> | |||
<div | |||
className="hidden" | |||
> | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<div> | |||
<SaveAndRunStepContent /> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly: wrong alm 1`] = ` | |||
<Alert | |||
variant="error" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.unsupported | |||
</Alert> | |||
`; |
@@ -0,0 +1,613 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<span> | |||
onboarding.build | |||
</span> | |||
<RenderOptions | |||
name="buildTechnology" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"dotnet", | |||
"maven", | |||
"gradle", | |||
"other", | |||
] | |||
} | |||
/> | |||
<ol | |||
className="list-styled big-spacer-top" | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: dotnet 1`] = ` | |||
<Fragment> | |||
<span> | |||
onboarding.build | |||
</span> | |||
<RenderOptions | |||
checked="dotnet" | |||
name="buildTechnology" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"dotnet", | |||
"maven", | |||
"gradle", | |||
"other", | |||
] | |||
} | |||
/> | |||
<ol | |||
className="list-styled big-spacer-top" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"pipeline", | |||
"task", | |||
"before", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare" | |||
/> | |||
</li> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"endpoint", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.endpoint" | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
values={ | |||
Object { | |||
"run_analysis_value": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.dotnet | |||
</strong>, | |||
"section": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.section | |||
</strong>, | |||
} | |||
} | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence" | |||
values={ | |||
Object { | |||
"button": <ClipboardIconButton | |||
copyValue="my-project" | |||
/>, | |||
"key": <code | |||
className="rule" | |||
> | |||
my-project | |||
</code>, | |||
} | |||
} | |||
/> | |||
</li> | |||
</ul> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"task", | |||
"after", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run" | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"task", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg" | |||
/> | |||
<Alert | |||
className="spacer-top" | |||
variant="info" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.info.sentence1 | |||
</Alert> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"tab", | |||
"continuous_integration", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration" | |||
/> | |||
</li> | |||
<hr /> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/azuredevops-integration/" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</ol> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: gradle 1`] = ` | |||
<Fragment> | |||
<span> | |||
onboarding.build | |||
</span> | |||
<RenderOptions | |||
checked="gradle" | |||
name="buildTechnology" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"dotnet", | |||
"maven", | |||
"gradle", | |||
"other", | |||
] | |||
} | |||
/> | |||
<ol | |||
className="list-styled big-spacer-top" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"pipeline", | |||
"task", | |||
"before", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare" | |||
/> | |||
</li> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"endpoint", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.endpoint" | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
values={ | |||
Object { | |||
"run_analysis_value": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.gradle | |||
</strong>, | |||
"section": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.section | |||
</strong>, | |||
} | |||
} | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"section", | |||
"properties", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.advanced_properties" | |||
/> | |||
: | |||
<CodeSnippet | |||
snippet="# Additional properties that will be passed to the scanner, | |||
# Put one key=value per line, example: | |||
# sonar.exclusions=**/*.bin | |||
sonar.projectKey=my-project" | |||
/> | |||
</li> | |||
</ul> | |||
<li> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.onboarding.build.gradle | |||
</li> | |||
<ul | |||
className="list-styled big-spacer-bottom" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"section", | |||
"option", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.settings" | |||
/> | |||
</li> | |||
</ul> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"task", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg" | |||
/> | |||
<Alert | |||
className="spacer-top" | |||
variant="info" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.info.sentence1 | |||
</Alert> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"tab", | |||
"continuous_integration", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration" | |||
/> | |||
</li> | |||
<hr /> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/azuredevops-integration/" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</ol> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: maven 1`] = ` | |||
<Fragment> | |||
<span> | |||
onboarding.build | |||
</span> | |||
<RenderOptions | |||
checked="maven" | |||
name="buildTechnology" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"dotnet", | |||
"maven", | |||
"gradle", | |||
"other", | |||
] | |||
} | |||
/> | |||
<ol | |||
className="list-styled big-spacer-top" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"pipeline", | |||
"task", | |||
"before", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare" | |||
/> | |||
</li> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"endpoint", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.endpoint" | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
values={ | |||
Object { | |||
"run_analysis_value": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.maven | |||
</strong>, | |||
"section": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.section | |||
</strong>, | |||
} | |||
} | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"section", | |||
"properties", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.advanced_properties" | |||
/> | |||
: | |||
<CodeSnippet | |||
snippet="# Additional properties that will be passed to the scanner, | |||
# Put one key=value per line, example: | |||
# sonar.exclusions=**/*.bin | |||
sonar.projectKey=my-project" | |||
/> | |||
</li> | |||
</ul> | |||
<li> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.onboarding.build.maven | |||
</li> | |||
<ul | |||
className="list-styled big-spacer-bottom" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"section", | |||
"option", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.settings" | |||
/> | |||
</li> | |||
</ul> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"task", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg" | |||
/> | |||
<Alert | |||
className="spacer-top" | |||
variant="info" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.info.sentence1 | |||
</Alert> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"tab", | |||
"continuous_integration", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration" | |||
/> | |||
</li> | |||
<hr /> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/azuredevops-integration/" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</ol> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: other 1`] = ` | |||
<Fragment> | |||
<span> | |||
onboarding.build | |||
</span> | |||
<RenderOptions | |||
checked="other" | |||
name="buildTechnology" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"dotnet", | |||
"maven", | |||
"gradle", | |||
"other", | |||
] | |||
} | |||
/> | |||
<ol | |||
className="list-styled big-spacer-top" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"pipeline", | |||
"task", | |||
"before", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare" | |||
/> | |||
</li> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"endpoint", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.endpoint" | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis" | |||
values={ | |||
Object { | |||
"run_analysis_value": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.values.other | |||
</strong>, | |||
"section": <strong> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.section | |||
</strong>, | |||
} | |||
} | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"mode", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.manual" | |||
/> | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence" | |||
values={ | |||
Object { | |||
"button": <ClipboardIconButton | |||
copyValue="my-project" | |||
/>, | |||
"key": <code | |||
className="rule" | |||
> | |||
my-project | |||
</code>, | |||
} | |||
} | |||
/> | |||
</li> | |||
</ul> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"task", | |||
"after", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run" | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"task", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg" | |||
/> | |||
<Alert | |||
className="spacer-top" | |||
variant="info" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.info.sentence1 | |||
</Alert> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"tab", | |||
"continuous_integration", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration" | |||
/> | |||
</li> | |||
<hr /> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
id="onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/azuredevops-integration/" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</ol> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,24 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<span> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence" | |||
id="onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence" | |||
values={ | |||
Object { | |||
"button": <strong> | |||
onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence.button | |||
</strong>, | |||
"link": <a | |||
href="https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarqube" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence.link | |||
</a>, | |||
} | |||
} | |||
/> | |||
</span> | |||
`; |
@@ -0,0 +1,54 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<div | |||
className="display-flex-row big-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/commit.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.commit | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.commit.why | |||
</p> | |||
</div> | |||
</div> | |||
<div | |||
className="display-flex-row" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/refresh.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.refresh | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.refresh.why | |||
</p> | |||
</div> | |||
</div> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,66 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"menu", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step1" | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"type", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step2" | |||
/> | |||
</li> | |||
<li> | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step3.sentence | |||
</li> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step4.sentence" | |||
id="onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step4.sentence" | |||
values={ | |||
Object { | |||
"button": <ClipboardIconButton | |||
copyValue="http://localhost" | |||
/>, | |||
"url": <code | |||
className="rule" | |||
> | |||
http://localhost | |||
</code>, | |||
} | |||
} | |||
/> | |||
</li> | |||
<li> | |||
<span> | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step5.sentence | |||
: | |||
</span> | |||
<Button | |||
className="spacer-left" | |||
onClick={[Function]} | |||
> | |||
onboarding.token.generate_token | |||
</Button> | |||
</li> | |||
<li> | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step6.sentence | |||
</li> | |||
</ol> | |||
</Fragment> | |||
`; |
@@ -20,8 +20,10 @@ | |||
import * as React from 'react'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { isProjectGitLabBindingResponse } from '../../../helpers/alm-settings'; | |||
import { ProjectAlmBindingResponse } from '../../../types/alm-settings'; | |||
import { | |||
isProjectGitLabBindingResponse, | |||
ProjectAlmBindingResponse | |||
} from '../../../types/alm-settings'; | |||
import EnvironmentVariablesStep from './EnvironmentVariablesStep'; | |||
import ProjectKeyStep from './ProjectKeyStep'; | |||
import { BuildTools } from './types'; |
@@ -21,13 +21,14 @@ import * as React from 'react'; | |||
import { connect } from 'react-redux'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
isProjectBitbucketBindingResponse, | |||
isProjectGitHubBindingResponse | |||
} from '../../../helpers/alm-settings'; | |||
import { getCurrentUserSetting, Store } from '../../../store/rootReducer'; | |||
import { setCurrentUserSetting } from '../../../store/users'; | |||
import { AlmBindingDefinition, ProjectAlmBindingResponse } from '../../../types/alm-settings'; | |||
import { | |||
AlmBindingDefinition, | |||
isProjectBitbucketBindingResponse, | |||
isProjectGitHubBindingResponse, | |||
ProjectAlmBindingResponse | |||
} from '../../../types/alm-settings'; | |||
import JenkinsfileStep from './JenkinsfileStep'; | |||
import MultiBranchPipelineStep from './MultiBranchPipelineStep'; | |||
import PreRequisitesStep from './PreRequisitesStep'; |
@@ -21,12 +21,10 @@ import * as React from 'react'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
AlmBindingDefinition, | |||
isGithubBindingDefinition, | |||
isProjectBitbucketBindingResponse, | |||
isProjectGitHubBindingResponse | |||
} from '../../../helpers/alm-settings'; | |||
import { | |||
AlmBindingDefinition, | |||
isProjectGitHubBindingResponse, | |||
ProjectBitbucketBindingResponse, | |||
ProjectGitHubBindingResponse | |||
} from '../../../types/alm-settings'; |
@@ -21,13 +21,11 @@ import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Button, ButtonLink } from 'sonar-ui-common/components/controls/buttons'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
isBitbucketBindingDefinition, | |||
isGithubBindingDefinition | |||
} from '../../../helpers/alm-settings'; | |||
import { | |||
AlmBindingDefinition, | |||
AlmKeys, | |||
isBitbucketBindingDefinition, | |||
isGithubBindingDefinition, | |||
ProjectAlmBindingResponse | |||
} from '../../../types/alm-settings'; | |||
import Step from '../components/Step'; |
@@ -20,7 +20,8 @@ | |||
export enum TutorialModes { | |||
Manual = 'manual', | |||
Jenkins = 'jenkins', | |||
GitLabCI = 'gitlab-ci' | |||
GitLabCI = 'gitlab-ci', | |||
AzurePipelines = 'azure-pipelines' | |||
} | |||
export enum BuildTools { |
@@ -1,67 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { AlmKeys } from '../../types/alm-settings'; | |||
import { | |||
isBitbucketBindingDefinition, | |||
isGithubBindingDefinition, | |||
isProjectBitbucketBindingResponse, | |||
isProjectGitHubBindingResponse | |||
} from '../alm-settings'; | |||
import { | |||
mockBitbucketBindingDefinition, | |||
mockGithubBindingDefinition, | |||
mockProjectAlmBindingResponse, | |||
mockProjectBitbucketBindingResponse, | |||
mockProjectGithubBindingResponse | |||
} from '../mocks/alm-settings'; | |||
/* eslint-disable sonarjs/no-duplicate-string */ | |||
describe('isProjectBitbucketBindingResponse', () => { | |||
it('works as expected', () => { | |||
expect(isProjectBitbucketBindingResponse(mockProjectAlmBindingResponse())).toBe(false); | |||
expect(isProjectBitbucketBindingResponse(mockProjectBitbucketBindingResponse())).toBe(true); | |||
}); | |||
}); | |||
describe('isBitbucketBindingDefinition', () => { | |||
it('works as expected', () => { | |||
expect(isBitbucketBindingDefinition(undefined)).toBe(false); | |||
expect(isBitbucketBindingDefinition(mockGithubBindingDefinition())).toBe(false); | |||
expect(isBitbucketBindingDefinition(mockBitbucketBindingDefinition())).toBe(true); | |||
}); | |||
}); | |||
describe('isProjectGithubBindingResponse', () => { | |||
it('works as expected', () => { | |||
expect( | |||
isProjectGitHubBindingResponse(mockProjectAlmBindingResponse({ alm: AlmKeys.Azure })) | |||
).toBe(false); | |||
expect(isProjectGitHubBindingResponse(mockProjectGithubBindingResponse())).toBe(true); | |||
}); | |||
}); | |||
describe('isGithubBindingDefinition', () => { | |||
it('works as expected', () => { | |||
expect(isGithubBindingDefinition(undefined)).toBe(false); | |||
expect(isGithubBindingDefinition(mockBitbucketBindingDefinition())).toBe(false); | |||
expect(isGithubBindingDefinition(mockGithubBindingDefinition())).toBe(true); | |||
}); | |||
}); |
@@ -1,66 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { | |||
AlmBindingDefinition, | |||
AlmKeys, | |||
BitbucketBindingDefinition, | |||
GithubBindingDefinition, | |||
ProjectAlmBindingResponse, | |||
ProjectBitbucketBindingResponse, | |||
ProjectGitHubBindingResponse, | |||
ProjectGitLabBindingResponse | |||
} from '../types/alm-settings'; | |||
export function isProjectBitbucketBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectBitbucketBindingResponse { | |||
return binding.alm === AlmKeys.Bitbucket; | |||
} | |||
export function isProjectGitHubBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectGitHubBindingResponse { | |||
return binding.alm === AlmKeys.GitHub; | |||
} | |||
export function isProjectGitLabBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectGitLabBindingResponse { | |||
return binding.alm === AlmKeys.GitLab; | |||
} | |||
export function isBitbucketBindingDefinition( | |||
binding?: AlmBindingDefinition & { url?: string; personalAccessToken?: string } | |||
): binding is BitbucketBindingDefinition { | |||
return ( | |||
binding !== undefined && binding.url !== undefined && binding.personalAccessToken !== undefined | |||
); | |||
} | |||
export function isGithubBindingDefinition( | |||
binding?: AlmBindingDefinition & { appId?: string; privateKey?: string; url?: string } | |||
): binding is GithubBindingDefinition { | |||
return ( | |||
binding !== undefined && | |||
binding.appId !== undefined && | |||
binding.privateKey !== undefined && | |||
binding.url !== undefined | |||
); | |||
} |
@@ -27,6 +27,7 @@ import { | |||
GithubBindingDefinition, | |||
GitlabBindingDefinition, | |||
ProjectAlmBindingResponse, | |||
ProjectAzureBindingResponse, | |||
ProjectBitbucketBindingResponse, | |||
ProjectGitHubBindingResponse, | |||
ProjectGitLabBindingResponse | |||
@@ -132,6 +133,19 @@ export function mockProjectGitLabBindingResponse( | |||
}; | |||
} | |||
export function mockProjectAzureBindingResponse( | |||
overrides: Partial<ProjectAzureBindingResponse> = {} | |||
): ProjectAzureBindingResponse { | |||
return { | |||
alm: AlmKeys.Azure, | |||
key: 'foo', | |||
slug: 'PROJECT_NAME', | |||
repository: 'REPOSITORY_NAME', | |||
url: 'https://ado.my_company.com/mycollection', | |||
...overrides | |||
}; | |||
} | |||
export function mockAlmSettingsBindingStatus( | |||
overrides: Partial<AlmSettingsBindingStatus> | |||
): AlmSettingsBindingStatus { |
@@ -60,6 +60,13 @@ export interface ProjectAlmBindingResponse { | |||
summaryCommentEnabled?: boolean; | |||
} | |||
export interface ProjectAzureBindingResponse extends ProjectAlmBindingResponse { | |||
alm: AlmKeys.Azure; | |||
repository: string; | |||
slug: string; | |||
url: string; | |||
} | |||
export interface ProjectBitbucketBindingResponse extends ProjectAlmBindingResponse { | |||
alm: AlmKeys.Bitbucket; | |||
repository: string; | |||
@@ -126,3 +133,46 @@ export enum AlmSettingsBindingStatusType { | |||
Failure, | |||
Warning | |||
} | |||
export function isProjectBitbucketBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectBitbucketBindingResponse { | |||
return binding.alm === AlmKeys.Bitbucket; | |||
} | |||
export function isProjectGitHubBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectGitHubBindingResponse { | |||
return binding.alm === AlmKeys.GitHub; | |||
} | |||
export function isProjectGitLabBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectGitLabBindingResponse { | |||
return binding.alm === AlmKeys.GitLab; | |||
} | |||
export function isProjectAzureBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectAzureBindingResponse { | |||
return binding.alm === AlmKeys.Azure; | |||
} | |||
export function isBitbucketBindingDefinition( | |||
binding?: AlmBindingDefinition & { url?: string; personalAccessToken?: string } | |||
): binding is BitbucketBindingDefinition { | |||
return ( | |||
binding !== undefined && binding.url !== undefined && binding.personalAccessToken !== undefined | |||
); | |||
} | |||
export function isGithubBindingDefinition( | |||
binding?: AlmBindingDefinition & { appId?: string; privateKey?: string; url?: string } | |||
): binding is GithubBindingDefinition { | |||
return ( | |||
binding !== undefined && | |||
binding.appId !== undefined && | |||
binding.privateKey !== undefined && | |||
binding.url !== undefined | |||
); | |||
} |
@@ -3447,6 +3447,7 @@ onboarding.tutorial.choose_method=How do you want to analyze your repository? | |||
onboarding.tutorial.choose_method.manual=Manually | |||
onboarding.tutorial.choose_method.jenkins=With Jenkins | |||
onboarding.tutorial.choose_method.gitlab_ci=With GitLab CI | |||
onboarding.tutorial.choose_method.azure_pipelines=With Azure Pipelines | |||
onboarding.tutorial.with.gitlab_ci.title=Analyze your project with GitLab CI | |||
onboarding.tutorial.with.gitlab_ci.unsupported=This tutorial is only available for projects bound to GitLab. | |||
@@ -3598,6 +3599,63 @@ onboarding.tutorial.with.jenkins.commit.why=Each new push you make on your branc | |||
onboarding.tutorial.with.jenkins.refresh=This page will then refresh with your analysis results. | |||
onboarding.tutorial.with.jenkins.refresh.why=If the page doesn't refresh after a while, please double-check the analysis configuration. | |||
onboarding.tutorial.with.azure_pipelines.title=Analyze your project with Azure DevOps Pipelines | |||
onboarding.tutorial.with.azure_pipelines.unsupported=This tutorial is only available for projects bound to Azure DevOps Server. | |||
onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.title=Install SonarQube extension for Azure DevOps Server | |||
onboarding.tutorial.with.azure_pipelines.ExtensionInstallation.sentence=From your Azure DevOps Server 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.step1.sentence=In Azure DevOps Server, 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} | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step2.sentence.type=SonarQube | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step3.sentence=Enter a memorable connection name | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step4.sentence=Enter your SonarQube server url: {url} {button} | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step5.sentence=Enter an existing token, or a newly generated one | |||
onboarding.tutorial.with.azure_pipelines.ServiceEndpoint.step6.sentence=Create the service connection | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.title=Configure Branch analysis | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.sentence=In Azure DevOps Server, 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.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 | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.endpoint.sentence.endpoint=SonarQube server endpoint | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis=Under {section}, select {run_analysis_value} | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.prepare.run_analysis.section=Choose the way to run the analysis | |||
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.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 | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.sentence=Add a new {task} task {after} your build task | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.sentence.task=Run Code Analysis | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.sentence.after=after | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.run.key.sentence=In the project key field, enter {key} {button} | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.advanced_properties.sentence=Expand the {section} and replace the {properties} with the following snippet | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.advanced_properties.sentence.section=Advanced section | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.advanced_properties.sentence.properties=Additional Properties | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java=Edit or add a new {0} task | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.settings.sentence=Under {section}, check {option} | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.settings.sentence.section=Code Analysis | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.java.settings.sentence.option=Run SonarQube or SonarCloud Analysis | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.sentence=Add a new {task} task to publish SonarQube's Quality Gate results on your build pipeline summary | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.info.sentence1=This task may increase your build time as your pipeline will have to wait for SonarQube to process the analysis report. It is highly recommended but optional. | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.publish_qg.sentence.task=Publish Quality Gate Result | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration.sentence=Under the {tab} tab of your pipeline, check {continuous_integration} and select all the branches for which you want the SonarQube analysis to run automatically | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration.sentence.tab=Triggers | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration.sentence.continuous_integration=Enable continuous integration | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection=To make sure your Pull Requests are analyzed automatically and aren't merged when they're failing their quality gate, check out the {link}. | |||
onboarding.tutorial.with.azure_pipelines.BranchAnalysis.branch_protection.link=documentation | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.title=Save and run your pipeline | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.commit=Save your pipeline and push your code to start the analysis | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.commit.why=Each new push you make on your branches will trigger a new analysis in SonarQube | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.refresh=This page will then refresh with your analysis results | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.refresh.why=If this page doesn't refresh after a while, please double-check your pipeline configuration | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.then={what} Checkout our {link} to make sure SonarQube analyze and decorate all of your Pull Requests | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.then.what=Then what? | |||
onboarding.tutorial.with.azure_pipelines.SaveAndRun.then.link=Azure integration documentation | |||
#------------------------------------------------------------------------------ | |||
# | |||
# BRANCHES |