Parcourir la source

SONAR-13480 Add jenkins tutorial for GitHub imported projects

tags/8.5.0.37579
Jeremy Davis il y a 3 ans
Parent
révision
0a90ec05aa
29 fichiers modifiés avec 1329 ajouts et 518 suppressions
  1. 7
    3
      server/sonar-web/src/main/js/components/tutorials/TutorialSelection.tsx
  2. 2
    2
      server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx
  3. 41
    15
      server/sonar-web/src/main/js/components/tutorials/__tests__/utils-test.ts
  4. 0
    143
      server/sonar-web/src/main/js/components/tutorials/jenkins/BitbucketWebhookStep.tsx
  5. 17
    12
      server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx
  6. 54
    22
      server/sonar-web/src/main/js/components/tutorials/jenkins/MultiBranchPipelineStep.tsx
  7. 6
    2
      server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx
  8. 102
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStep.tsx
  9. 98
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepBitbucket.tsx
  10. 88
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGithub.tsx
  11. 14
    13
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-test.tsx
  12. 9
    3
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/MultiBranchPipelineStep-test.tsx
  13. 2
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/PreRequisitesStep-test.tsx
  14. 67
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/WebhookStep-test.tsx
  15. 8
    17
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/WebhookStepBitbucket-test.tsx
  16. 42
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/WebhookStepGithub-test.tsx
  17. 0
    228
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/BitbucketWebhookStep-test.tsx.snap
  18. 4
    3
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/JenkinsTutorial-test.tsx.snap
  19. 112
    13
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/MultiBranchPipelineStep-test.tsx.snap
  20. 1
    1
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/PreRequisitesStep-test.tsx.snap
  21. 211
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/WebhookStep-test.tsx.snap
  22. 161
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/WebhookStepBitbucket-test.tsx.snap
  23. 143
    0
      server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/WebhookStepGithub-test.tsx.snap
  24. 14
    0
      server/sonar-web/src/main/js/components/tutorials/utils.ts
  25. 30
    4
      server/sonar-web/src/main/js/helpers/__tests__/alm-settings-test.ts
  26. 24
    3
      server/sonar-web/src/main/js/helpers/alm-settings.ts
  27. 14
    2
      server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts
  28. 5
    0
      server/sonar-web/src/main/js/types/alm-settings.ts
  29. 53
    32
      sonar-core/src/main/resources/org/sonar/l10n/core.properties

+ 7
- 3
server/sonar-web/src/main/js/components/tutorials/TutorialSelection.tsx Voir le fichier

@@ -59,13 +59,17 @@ export class TutorialSelection extends React.PureComponent<Props, State> {
]);

if (this.mounted) {
// We only support Bitbucket for now.
if (projectBinding === undefined || projectBinding.alm !== AlmKeys.Bitbucket) {
// We only support Bitbucket & GitHub for now.
if (
projectBinding === undefined ||
(projectBinding.alm !== AlmKeys.Bitbucket && projectBinding.alm !== AlmKeys.GitHub)
) {
this.setState({ loading: false, forceManual: true });
} else {
let almBinding;
if (almDefinitions !== undefined) {
almBinding = almDefinitions[projectBinding.alm].find(d => d.key === projectBinding.key);
const specificDefinitions = almDefinitions[projectBinding.alm] as AlmBindingDefinition[];
almBinding = specificDefinitions.find(d => d.key === projectBinding.key);
}
this.setState({ almBinding, forceManual: false, projectBinding, loading: false });
}

+ 2
- 2
server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx Voir le fichier

@@ -23,7 +23,7 @@ import * as React from 'react';
import { click } from 'sonar-ui-common/helpers/testUtils';
import {
mockBitbucketBindingDefinition,
mockProjectBitbucketBindingGet
mockProjectBitbucketBindingResponse
} from '../../../helpers/mocks/alm-settings';
import { mockComponent, mockLoggedInUser } from '../../../helpers/testMocks';
import TutorialSelectionRenderer, {
@@ -40,7 +40,7 @@ it('should render correctly', () => {
expect(
shallowRender({
selectedTutorial: TutorialModes.Jenkins,
projectBinding: mockProjectBitbucketBindingGet()
projectBinding: mockProjectBitbucketBindingResponse()
})
).toMatchSnapshot('jenkins tutorial');
});

+ 41
- 15
server/sonar-web/src/main/js/components/tutorials/__tests__/utils-test.ts Voir le fichier

@@ -17,27 +17,53 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { getUniqueTokenName } from '../utils';
import {
mockGithubBindingDefinition,
mockProjectGithubBindingResponse
} from '../../../helpers/mocks/alm-settings';
import { buildGithubLink, getUniqueTokenName } from '../utils';

const initialTokenName = 'Analyze "lightsaber"';
describe('getUniqueTokenName', () => {
const initialTokenName = 'Analyze "lightsaber"';

it('should return the given name when the user has no token', () => {
const userTokens: T.UserToken[] = [];
it('should return the given name when the user has no token', () => {
const userTokens: T.UserToken[] = [];

expect(getUniqueTokenName(userTokens, initialTokenName)).toBe(initialTokenName);
});
expect(getUniqueTokenName(userTokens, initialTokenName)).toBe(initialTokenName);
});

it('should generate a token with the given name', () => {
const userTokens = [{ name: initialTokenName, createdAt: '2019-06-14T09:45:52+0200' }];

expect(getUniqueTokenName(userTokens, 'Analyze "project"')).toBe('Analyze "project"');
});

it('should generate a token with the given name', () => {
const userTokens = [{ name: initialTokenName, createdAt: '2019-06-14T09:45:52+0200' }];
it('should generate a unique token when the name already exists', () => {
const userTokens = [
{ name: initialTokenName, createdAt: '2019-06-15T09:45:52+0200' },
{ name: `${initialTokenName} 1`, createdAt: '2019-06-15T09:45:53+0200' }
];

expect(getUniqueTokenName(userTokens, 'Analyze "project"')).toBe('Analyze "project"');
expect(getUniqueTokenName(userTokens, initialTokenName)).toBe('Analyze "lightsaber" 2');
});
});

it('should generate a unique token when the name already exists', () => {
const userTokens = [
{ name: initialTokenName, createdAt: '2019-06-14T09:45:52+0200' },
{ name: `${initialTokenName} 1`, createdAt: '2019-06-14T09:45:52+0200' }
];
describe('buildGithubLink', () => {
it('should work for GitHub Enterprise', () => {
expect(
buildGithubLink(
mockGithubBindingDefinition({ url: 'https://github.company.com/api/v3/' }),
mockProjectGithubBindingResponse({ repository: 'owner/reponame' })
)
).toBe('https://github.company.com/owner/reponame');
});

expect(getUniqueTokenName(userTokens, initialTokenName)).toBe('Analyze "lightsaber" 2');
it('should work for github.com', () => {
expect(
buildGithubLink(
mockGithubBindingDefinition({ url: 'https://api.github.com/' }),
mockProjectGithubBindingResponse({ repository: 'owner/reponame' })
)
).toBe('https://github.com/owner/reponame');
});
});

+ 0
- 143
server/sonar-web/src/main/js/components/tutorials/jenkins/BitbucketWebhookStep.tsx Voir le fichier

@@ -1,143 +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 * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { Button, ButtonLink } 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 {
BitbucketBindingDefinition,
ProjectBitbucketBindingResponse
} from '../../../types/alm-settings';
import CodeSnippet from '../../common/CodeSnippet';
import LabelActionPair from '../components/LabelActionPair';
import SentenceWithHighlights from '../components/SentenceWithHighlights';
import Step from '../components/Step';

export interface BitbucketWebhookStepProps {
almBinding?: BitbucketBindingDefinition;
finished: boolean;
onDone: () => void;
onOpen: () => void;
open: boolean;
projectBinding: ProjectBitbucketBindingResponse;
}

export default function BitbucketWebhookStep(props: BitbucketWebhookStepProps) {
const { almBinding, finished, open, projectBinding } = props;
return (
<Step
finished={finished}
onOpen={props.onOpen}
open={open}
renderForm={() => (
<div className="boxed-group-inner">
<p className="big-spacer-bottom">
<FormattedMessage
defaultMessage={translate(
'onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence'
)}
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence"
values={{
link: (
<ButtonLink onClick={props.onDone}>
{translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link')}
</ButtonLink>
)
}}
/>
</p>
<ol className="list-styled">
<li>
<FormattedMessage
defaultMessage={translate(
'onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence'
)}
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence"
values={{
link:
almBinding !== undefined ? (
<a
href={`${almBinding.url.replace(
/\/$/,
''
)}/plugins/servlet/webhooks/projects/${projectBinding.repository}/repos/${
projectBinding.slug
}/create`}
rel="noopener noreferrer"
target="_blank">
{translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link')}
</a>
) : (
translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link')
)
}}
/>
<ul className="list-styled">
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name" />
</li>
<li className="abs-width-600">
<p>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url" />
</p>
<CodeSnippet
isOneLine={true}
snippet={`***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=${
almBinding !== undefined ? almBinding.url : '***BITBUCKET_URL***'
}`}
/>
<Alert variant="info">
{translate(
'onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning'
)}
</Alert>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={['events']}
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2"
/>
<ul className="list-styled">
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo" />
</li>
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr" />
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={['create']}
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step3"
/>
</li>
</ol>
<Button onClick={props.onDone}>{translate('continue')}</Button>
</div>
)}
stepNumber={2}
stepTitle={translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.title')}
/>
);
}

+ 17
- 12
server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsTutorial.tsx Voir le fichier

@@ -22,16 +22,16 @@ import { connect } from 'react-redux';
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import { translate } from 'sonar-ui-common/helpers/l10n';
import {
isBitbucketBindingDefinition,
isProjectBitbucketBindingResponse
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 BitbucketWebhookStep from './BitbucketWebhookStep';
import JenkinsfileStep from './JenkinsfileStep';
import MultiBranchPipelineStep from './MultiBranchPipelineStep';
import PreRequisitesStep from './PreRequisitesStep';
import WebhookStep from './WebhookStep';

export interface JenkinsTutorialProps {
almBinding?: AlmBindingDefinition;
@@ -44,7 +44,7 @@ export interface JenkinsTutorialProps {
enum Steps {
PreRequisites = 0,
MultiBranchPipeline = 1,
BitbucketWebhook = 2,
Webhook = 2,
Jenkinsfile = 3
}

@@ -57,9 +57,12 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) {
);

// Failsafe; should never happen.
if (!isProjectBitbucketBindingResponse(projectBinding)) {
if (
!isProjectBitbucketBindingResponse(projectBinding) &&
!isProjectGitHubBindingResponse(projectBinding)
) {
return (
<Alert variant="error">{translate('onboarding.tutorial.with.jenkins.only_bitbucket')}</Alert>
<Alert variant="error">{translate('onboarding.tutorial.with.jenkins.unsupported')}</Alert>
);
}

@@ -70,6 +73,7 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) {
</div>

<PreRequisitesStep
alm={projectBinding.alm}
onDone={() => setStep(Steps.MultiBranchPipeline)}
onOpen={() => setStep(Steps.PreRequisites)}
onChangeSkipNextTime={skip => {
@@ -83,19 +87,20 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) {
/>

<MultiBranchPipelineStep
almBinding={almBinding}
finished={step > Steps.MultiBranchPipeline}
onDone={() => setStep(Steps.BitbucketWebhook)}
onDone={() => setStep(Steps.Webhook)}
onOpen={() => setStep(Steps.MultiBranchPipeline)}
open={step === Steps.MultiBranchPipeline}
projectBinding={projectBinding}
/>

<BitbucketWebhookStep
almBinding={almBinding && isBitbucketBindingDefinition(almBinding) ? almBinding : undefined}
finished={step > Steps.BitbucketWebhook}
<WebhookStep
almBinding={almBinding}
finished={step > Steps.Webhook}
onDone={() => setStep(Steps.Jenkinsfile)}
onOpen={() => setStep(Steps.BitbucketWebhook)}
open={step === Steps.BitbucketWebhook}
onOpen={() => setStep(Steps.Webhook)}
open={step === Steps.Webhook}
projectBinding={projectBinding}
/>


+ 54
- 22
server/sonar-web/src/main/js/components/tutorials/jenkins/MultiBranchPipelineStep.tsx Voir le fichier

@@ -20,22 +20,33 @@
import * as React from 'react';
import { Button } from 'sonar-ui-common/components/controls/buttons';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { ProjectBitbucketBindingResponse } from '../../../types/alm-settings';
import {
isGithubBindingDefinition,
isProjectBitbucketBindingResponse,
isProjectGitHubBindingResponse
} from '../../../helpers/alm-settings';
import {
AlmBindingDefinition,
ProjectBitbucketBindingResponse,
ProjectGitHubBindingResponse
} from '../../../types/alm-settings';
import LabelActionPair from '../components/LabelActionPair';
import LabelValuePair from '../components/LabelValuePair';
import SentenceWithHighlights from '../components/SentenceWithHighlights';
import Step from '../components/Step';
import { buildGithubLink } from '../utils';

export interface MultiBranchPipelineStepProps {
almBinding?: AlmBindingDefinition;
finished: boolean;
onDone: () => void;
onOpen: () => void;
open: boolean;
projectBinding: ProjectBitbucketBindingResponse;
projectBinding: ProjectBitbucketBindingResponse | ProjectGitHubBindingResponse;
}

export default function MultiBranchPipelineStep(props: MultiBranchPipelineStepProps) {
const { finished, open, projectBinding } = props;
const { almBinding, finished, open, projectBinding } = props;
return (
<Step
finished={finished}
@@ -56,27 +67,48 @@ export default function MultiBranchPipelineStep(props: MultiBranchPipelineStepPr
<li>
<SentenceWithHighlights
highlightKeys={['tab']}
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2"
translationKey={`onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.${projectBinding.alm}`}
/>
<ul className="list-styled">
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server" />
</li>
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds" />
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner"
value={projectBinding.repository}
/>
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo"
value={projectBinding.slug}
/>
</li>
{isProjectBitbucketBindingResponse(projectBinding) && (
<>
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.server" />
</li>
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.creds" />
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner"
value={projectBinding.repository}
/>
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo"
value={projectBinding.slug}
/>
</li>
</>
)}
{isProjectGitHubBindingResponse(projectBinding) && (
<>
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.creds" />
</li>
<li>
{isGithubBindingDefinition(almBinding) ? (
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url"
value={buildGithubLink(almBinding, projectBinding)}
/>
) : (
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url" />
)}
</li>
</>
)}
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour" />
</li>

+ 6
- 2
server/sonar-web/src/main/js/components/tutorials/jenkins/PreRequisitesStep.tsx Voir le fichier

@@ -23,10 +23,12 @@ import { Link } from 'react-router';
import { Button } from 'sonar-ui-common/components/controls/buttons';
import Checkbox from 'sonar-ui-common/components/controls/Checkbox';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { AlmKeys } from '../../../types/alm-settings';
import SentenceWithHighlights from '../components/SentenceWithHighlights';
import Step from '../components/Step';

export interface PreRequisitesStepProps {
alm: AlmKeys;
onChangeSkipNextTime: (skip: boolean) => void;
onDone: () => void;
onOpen: () => void;
@@ -35,7 +37,7 @@ export interface PreRequisitesStepProps {
}

export default function PreRequisitesStep(props: PreRequisitesStepProps) {
const { open, skipNextTime } = props;
const { alm, open, skipNextTime } = props;
return (
<Step
finished={!open}
@@ -50,7 +52,9 @@ export default function PreRequisitesStep(props: PreRequisitesStepProps) {
/>
</p>
<ul className="list-styled big-spacer-bottom">
<li>{translate('onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source')}</li>
<li>
{translate('onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source', alm)}
</li>
<li>{translate('onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner')}</li>
</ul>
<p className="big-spacer-bottom">

+ 102
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStep.tsx Voir le fichier

@@ -0,0 +1,102 @@
/*
* 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, 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,
ProjectAlmBindingResponse
} from '../../../types/alm-settings';
import Step from '../components/Step';
import WebhookStepBitbucket from './WebhookStepBitbucket';
import WebhookStepGithub from './WebhookStepGithub';

export interface WebhookStepProps {
almBinding?: AlmBindingDefinition;
finished: boolean;
onDone: () => void;
onOpen: () => void;
open: boolean;
projectBinding: ProjectAlmBindingResponse;
}

function renderAlmSpecificInstructions(props: WebhookStepProps) {
const { almBinding, projectBinding } = props;

switch (projectBinding.alm) {
case AlmKeys.Bitbucket:
return (
<WebhookStepBitbucket
almBinding={isBitbucketBindingDefinition(almBinding) ? almBinding : undefined}
projectBinding={projectBinding}
/>
);

case AlmKeys.GitHub:
return (
<WebhookStepGithub
almBinding={isGithubBindingDefinition(almBinding) ? almBinding : undefined}
projectBinding={projectBinding}
/>
);

default:
return null;
}
}

export default function WebhookStep(props: WebhookStepProps) {
const { finished, open, projectBinding } = props;

return (
<Step
finished={finished}
onOpen={props.onOpen}
open={open}
renderForm={() => (
<div className="boxed-group-inner">
<p className="big-spacer-bottom">
<FormattedMessage
defaultMessage={translate('onboarding.tutorial.with.jenkins.webhook.intro.sentence')}
id="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
values={{
link: (
<ButtonLink onClick={props.onDone}>
{translate('onboarding.tutorial.with.jenkins.webhook.intro.link')}
</ButtonLink>
)
}}
/>
</p>
<ol className="list-styled">{renderAlmSpecificInstructions(props)}</ol>
<Button onClick={props.onDone}>{translate('continue')}</Button>
</div>
)}
stepNumber={2}
stepTitle={translate('onboarding.tutorial.with.jenkins.webhook', projectBinding.alm, 'title')}
/>
);
}

+ 98
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepBitbucket.tsx Voir le fichier

@@ -0,0 +1,98 @@
/*
* 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 { Alert } from 'sonar-ui-common/components/ui/Alert';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { BitbucketBindingDefinition, ProjectAlmBindingResponse } from '../../../types/alm-settings';
import CodeSnippet from '../../common/CodeSnippet';
import LabelActionPair from '../components/LabelActionPair';
import SentenceWithHighlights from '../components/SentenceWithHighlights';

export interface WebhookStepBitbucketProps {
almBinding?: BitbucketBindingDefinition;
projectBinding: ProjectAlmBindingResponse;
}

function buildUrlSnippet(ownUrl = '***BITBUCKET_URL***') {
return `***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=${ownUrl}`;
}

export default function WebhookStepBitbucket(props: WebhookStepBitbucketProps) {
const { almBinding, projectBinding } = props;

const linkUrl =
almBinding &&
`${almBinding.url}/plugins/servlet/webhooks/projects/${projectBinding.repository}/repos/${projectBinding.slug}/create`;

return (
<>
<li>
<FormattedMessage
defaultMessage={translate('onboarding.tutorial.with.jenkins.webhook.step1.sentence')}
id="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
values={{
link: linkUrl ? (
<a href={linkUrl} rel="noopener noreferrer" target="_blank">
{translate('onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.link')}
</a>
) : (
translate('onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.link')
)
}}
/>
<ul className="list-styled">
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.step1.name" />
</li>
<li className="abs-width-600">
<p>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url" />
</p>
<CodeSnippet isOneLine={true} snippet={buildUrlSnippet(almBinding && almBinding.url)} />
<Alert variant="info">
{translate('onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url.warning')}
</Alert>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={['events']}
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2"
/>
<ul className="list-styled">
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.repo" />
</li>
<li>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.pr" />
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={['create']}
translationKey="onboarding.tutorial.with.jenkins.webhook.step3"
/>
</li>
</>
);
}

+ 88
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/WebhookStepGithub.tsx Voir le fichier

@@ -0,0 +1,88 @@
/*
* 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';
import { GithubBindingDefinition, ProjectAlmBindingResponse } from '../../../types/alm-settings';
import CodeSnippet from '../../common/CodeSnippet';
import LabelActionPair from '../components/LabelActionPair';
import SentenceWithHighlights from '../components/SentenceWithHighlights';
import { buildGithubLink } from '../utils';

export interface WebhookStepGithubProps {
almBinding?: GithubBindingDefinition;
projectBinding: ProjectAlmBindingResponse;
}

export default function WebhookStepGithub(props: WebhookStepGithubProps) {
const { almBinding, projectBinding } = props;

const linkUrl = almBinding && `${buildGithubLink(almBinding, projectBinding)}/settings/hooks`;

return (
<>
<li>
<FormattedMessage
defaultMessage={translate('onboarding.tutorial.with.jenkins.webhook.step1.sentence')}
id="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
values={{
link: linkUrl ? (
<a href={linkUrl} rel="noopener noreferrer" target="_blank">
{translate('onboarding.tutorial.with.jenkins.webhook.github.step1.link')}
</a>
) : (
translate('onboarding.tutorial.with.jenkins.webhook.github.step1.link')
)
}}
/>
<ul className="list-styled">
<li className="abs-width-600">
<p>
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.webhook.github.step1.url" />
</p>
<CodeSnippet isOneLine={true} snippet="/github-webhook/" />
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={['events', 'option']}
translationKey="onboarding.tutorial.with.jenkins.webhook.github.step2"
/>
<ul className="list-styled">
<li>
<strong>
{translate('onboarding.tutorial.with.jenkins.webhook.github.step2.repo')}
</strong>
</li>
<li>
<strong>{translate('onboarding.tutorial.with.jenkins.webhook.github.step2.pr')}</strong>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={['create']}
translationKey="onboarding.tutorial.with.jenkins.webhook.step3"
/>
</li>
</>
);
}

+ 14
- 13
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-test.tsx Voir le fichier

@@ -22,20 +22,21 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import {
mockProjectAlmBindingResponse,
mockProjectBitbucketBindingGet
mockProjectBitbucketBindingResponse
} from '../../../../helpers/mocks/alm-settings';
import { mockComponent } from '../../../../helpers/testMocks';
import BitbucketWebhookStep from '../BitbucketWebhookStep';
import { AlmKeys } from '../../../../types/alm-settings';
import JenkinsfileStep from '../JenkinsfileStep';
import { JenkinsTutorial, JenkinsTutorialProps } from '../JenkinsTutorial';
import MultiBranchPipelineStep from '../MultiBranchPipelineStep';
import PreRequisitesStep from '../PreRequisitesStep';
import WebhookStep from '../WebhookStep';

it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('default');
expect(shallowRender({ projectBinding: mockProjectAlmBindingResponse() })).toMatchSnapshot(
'not Bitbucket binding'
);
expect(
shallowRender({ projectBinding: mockProjectAlmBindingResponse({ alm: AlmKeys.Azure }) })
).toMatchSnapshot('unsupported alm');
});

it('should correctly navigate between steps', () => {
@@ -43,28 +44,28 @@ it('should correctly navigate between steps', () => {

expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(true);
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(false);
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(false);
expect(wrapper.find(WebhookStep).prop('open')).toBe(false);
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(false);

// Pre-reqs done.
wrapper.find(PreRequisitesStep).prop('onDone')();
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(false);
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(true);
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(false);
expect(wrapper.find(WebhookStep).prop('open')).toBe(false);
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(false);

// Multibranch done.
wrapper.find(MultiBranchPipelineStep).prop('onDone')();
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(false);
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(false);
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(true);
expect(wrapper.find(WebhookStep).prop('open')).toBe(true);
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(false);

// Webhook done.
wrapper.find(BitbucketWebhookStep).prop('onDone')();
wrapper.find(WebhookStep).prop('onDone')();
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(false);
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(false);
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(false);
expect(wrapper.find(WebhookStep).prop('open')).toBe(false);
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(true);

// Open Pre-reqs.
@@ -76,8 +77,8 @@ it('should correctly navigate between steps', () => {
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(true);

// Open Webhook.
wrapper.find(BitbucketWebhookStep).prop('onOpen')();
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(true);
wrapper.find(WebhookStep).prop('onOpen')();
expect(wrapper.find(WebhookStep).prop('open')).toBe(true);
});

it('should correctly store the user setting', () => {
@@ -107,7 +108,7 @@ function shallowRender(props: Partial<JenkinsTutorialProps> = {}) {
return shallow<JenkinsTutorialProps>(
<JenkinsTutorial
component={mockComponent()}
projectBinding={mockProjectBitbucketBindingGet()}
projectBinding={mockProjectBitbucketBindingResponse()}
setCurrentUserSetting={jest.fn()}
skipPreReqs={false}
{...props}

+ 9
- 3
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/MultiBranchPipelineStep-test.tsx Voir le fichier

@@ -20,14 +20,20 @@

import { shallow } from 'enzyme';
import * as React from 'react';
import { mockProjectBitbucketBindingGet } from '../../../../helpers/mocks/alm-settings';
import {
mockProjectBitbucketBindingResponse,
mockProjectGithubBindingResponse
} from '../../../../helpers/mocks/alm-settings';
import MultiBranchPipelineStep, { MultiBranchPipelineStepProps } from '../MultiBranchPipelineStep';
import { renderStepContent } from '../test-utils';

it('should render correctly', () => {
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot('Step wrapper');
expect(renderStepContent(wrapper)).toMatchSnapshot('content');
expect(renderStepContent(wrapper)).toMatchSnapshot('content for bitbucket');
expect(
renderStepContent(shallowRender({ projectBinding: mockProjectGithubBindingResponse() }))
).toMatchSnapshot('content for github');
});

function shallowRender(props: Partial<MultiBranchPipelineStepProps> = {}) {
@@ -37,7 +43,7 @@ function shallowRender(props: Partial<MultiBranchPipelineStepProps> = {}) {
onDone={jest.fn()}
onOpen={jest.fn()}
open={true}
projectBinding={mockProjectBitbucketBindingGet()}
projectBinding={mockProjectBitbucketBindingResponse()}
{...props}
/>
);

+ 2
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/PreRequisitesStep-test.tsx Voir le fichier

@@ -20,6 +20,7 @@

import { shallow } from 'enzyme';
import * as React from 'react';
import { AlmKeys } from '../../../../types/alm-settings';
import PreRequisitesStep, { PreRequisitesStepProps } from '../PreRequisitesStep';
import { renderStepContent } from '../test-utils';

@@ -32,6 +33,7 @@ it('should render correctly', () => {
function shallowRender(props: Partial<PreRequisitesStepProps> = {}) {
return shallow<PreRequisitesStepProps>(
<PreRequisitesStep
alm={AlmKeys.Bitbucket}
onChangeSkipNextTime={jest.fn()}
onDone={jest.fn()}
onOpen={jest.fn()}

+ 67
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/WebhookStep-test.tsx Voir le fichier

@@ -0,0 +1,67 @@
/*
* 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 {
mockAzureBindingDefinition,
mockBitbucketBindingDefinition,
mockGithubBindingDefinition,
mockGitlabBindingDefinition,
mockProjectAlmBindingResponse,
mockProjectBitbucketBindingResponse,
mockProjectGithubBindingResponse
} from '../../../../helpers/mocks/alm-settings';
import { AlmKeys } from '../../../../types/alm-settings';
import { renderStepContent } from '../test-utils';
import WebhookStep, { WebhookStepProps } from '../WebhookStep';

it.each([
[
AlmKeys.Azure,
mockAzureBindingDefinition(),
mockProjectAlmBindingResponse({ alm: AlmKeys.Azure })
],
[AlmKeys.Bitbucket, mockBitbucketBindingDefinition(), mockProjectBitbucketBindingResponse()],
[AlmKeys.GitHub, mockGithubBindingDefinition(), mockProjectGithubBindingResponse()],
[
AlmKeys.GitLab,
mockGitlabBindingDefinition(),
mockProjectAlmBindingResponse({ alm: AlmKeys.GitLab })
]
])('it should render correctly for %s', (_, almBinding, projectBinding) => {
const wrapper = shallowRender({ almBinding, projectBinding });
expect(wrapper).toMatchSnapshot('wrapper');
expect(renderStepContent(wrapper)).toMatchSnapshot('content');
});

function shallowRender(props: Partial<WebhookStepProps> = {}) {
return shallow<WebhookStepProps>(
<WebhookStep
almBinding={mockBitbucketBindingDefinition()}
finished={false}
onDone={jest.fn()}
onOpen={jest.fn()}
open={false}
projectBinding={mockProjectBitbucketBindingResponse()}
{...props}
/>
);
}

server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/BitbucketWebhookStep-test.tsx → server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/WebhookStepBitbucket-test.tsx Voir le fichier

@@ -22,29 +22,20 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import {
mockBitbucketBindingDefinition,
mockProjectBitbucketBindingGet
mockProjectBitbucketBindingResponse
} from '../../../../helpers/mocks/alm-settings';
import BitbucketWebhookStep, { BitbucketWebhookStepProps } from '../BitbucketWebhookStep';
import { renderStepContent } from '../test-utils';
import WebhookStepBitbucket, { WebhookStepBitbucketProps } from '../WebhookStepBitbucket';

it('should render correctly', () => {
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot('Step wrapper');
expect(renderStepContent(wrapper)).toMatchSnapshot('content');
expect(renderStepContent(wrapper.setProps({ almBinding: undefined }))).toMatchSnapshot(
'no alm binding'
);
expect(shallowRender()).toMatchSnapshot();
expect(shallowRender({ almBinding: undefined })).toMatchSnapshot('with no alm binding');
});

function shallowRender(props: Partial<BitbucketWebhookStepProps> = {}) {
return shallow<BitbucketWebhookStepProps>(
<BitbucketWebhookStep
function shallowRender(props: Partial<WebhookStepBitbucketProps> = {}) {
return shallow<WebhookStepBitbucketProps>(
<WebhookStepBitbucket
almBinding={mockBitbucketBindingDefinition()}
finished={false}
onDone={jest.fn()}
onOpen={jest.fn()}
open={true}
projectBinding={mockProjectBitbucketBindingGet()}
projectBinding={mockProjectBitbucketBindingResponse()}
{...props}
/>
);

+ 42
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/WebhookStepGithub-test.tsx Voir le fichier

@@ -0,0 +1,42 @@
/*
* 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 {
mockGithubBindingDefinition,
mockProjectGithubBindingResponse
} from '../../../../helpers/mocks/alm-settings';
import WebhookStepGithub, { WebhookStepGithubProps } from '../WebhookStepGithub';

it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
expect(shallowRender({ almBinding: undefined })).toMatchSnapshot('with no alm binding');
});

function shallowRender(props: Partial<WebhookStepGithubProps> = {}) {
return shallow<WebhookStepGithubProps>(
<WebhookStepGithub
almBinding={mockGithubBindingDefinition()}
projectBinding={mockProjectGithubBindingResponse()}
{...props}
/>
);
}

+ 0
- 228
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/BitbucketWebhookStep-test.tsx.snap Voir le fichier

@@ -1,228 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly: Step wrapper 1`] = `
<Step
finished={false}
onOpen={[MockFunction]}
open={true}
renderForm={[Function]}
stepNumber={2}
stepTitle="onboarding.tutorial.with.jenkins.bitbucket_webhook.title"
/>
`;

exports[`should render correctly: content 1`] = `
<div
className="boxed-group-inner"
>
<p
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence"
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence"
values={
Object {
"link": <ButtonLink
onClick={[MockFunction]}
>
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link
</ButtonLink>,
}
}
/>
</p>
<ol
className="list-styled"
>
<li>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence"
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence"
values={
Object {
"link": <a
href="http://bbs.enterprise.com/plugins/servlet/webhooks/projects/PROJECT_KEY/repos/repo-slug/create"
rel="noopener noreferrer"
target="_blank"
>
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link
</a>,
}
}
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name"
/>
</li>
<li
className="abs-width-600"
>
<p>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url"
/>
</p>
<CodeSnippet
isOneLine={true}
snippet="***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=http://bbs.enterprise.com"
/>
<Alert
variant="info"
>
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning
</Alert>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"events",
]
}
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2"
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo"
/>
</li>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"create",
]
}
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step3"
/>
</li>
</ol>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

exports[`should render correctly: no alm binding 1`] = `
<div
className="boxed-group-inner"
>
<p
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence"
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence"
values={
Object {
"link": <ButtonLink
onClick={[MockFunction]}
>
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link
</ButtonLink>,
}
}
/>
</p>
<ol
className="list-styled"
>
<li>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence"
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence"
values={
Object {
"link": "onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link",
}
}
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name"
/>
</li>
<li
className="abs-width-600"
>
<p>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url"
/>
</p>
<CodeSnippet
isOneLine={true}
snippet="***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=***BITBUCKET_URL***"
/>
<Alert
variant="info"
>
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning
</Alert>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"events",
]
}
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2"
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo"
/>
</li>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"create",
]
}
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step3"
/>
</li>
</ol>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

+ 4
- 3
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/JenkinsTutorial-test.tsx.snap Voir le fichier

@@ -12,6 +12,7 @@ exports[`should render correctly: default 1`] = `
</h1>
</div>
<PreRequisitesStep
alm="bitbucket"
onChangeSkipNextTime={[Function]}
onDone={[Function]}
onOpen={[Function]}
@@ -32,7 +33,7 @@ exports[`should render correctly: default 1`] = `
}
}
/>
<BitbucketWebhookStep
<WebhookStep
finished={false}
onDone={[Function]}
onOpen={[Function]}
@@ -75,10 +76,10 @@ exports[`should render correctly: default 1`] = `
</Fragment>
`;

exports[`should render correctly: not Bitbucket binding 1`] = `
exports[`should render correctly: unsupported alm 1`] = `
<Alert
variant="error"
>
onboarding.tutorial.with.jenkins.only_bitbucket
onboarding.tutorial.with.jenkins.unsupported
</Alert>
`;

+ 112
- 13
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/MultiBranchPipelineStep-test.tsx.snap Voir le fichier

@@ -11,7 +11,7 @@ exports[`should render correctly: Step wrapper 1`] = `
/>
`;

exports[`should render correctly: content 1`] = `
exports[`should render correctly: content for bitbucket 1`] = `
<div
className="boxed-group-inner"
>
@@ -41,33 +41,132 @@ exports[`should render correctly: content 1`] = `
"tab",
]
}
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2"
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket"
/>
<ul
className="list-styled"
>
<React.Fragment>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.server"
/>
</li>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.creds"
/>
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner"
value="PROJECT_KEY"
/>
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo"
value="repo-slug"
/>
</li>
</React.Fragment>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server"
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"tab",
]
}
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3"
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds"
/>
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner"
value="PROJECT_KEY"
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode"
/>
</li>
<li>
<LabelValuePair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo"
value="repo-slug"
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"save",
]
}
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4"
/>
</li>
</ol>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

exports[`should render correctly: content for github 1`] = `
<div
className="boxed-group-inner"
>
<p
className="big-spacer-bottom"
>
onboarding.tutorial.with.jenkins.multi_branch_pipeline.intro
</p>
<ol
className="list-styled"
>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"new_item",
"type",
]
}
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1"
/>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"tab",
]
}
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github"
/>
<ul
className="list-styled"
>
<React.Fragment>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.creds"
/>
</li>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url"
/>
</li>
</React.Fragment>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour"

+ 1
- 1
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/PreRequisitesStep-test.tsx.snap Voir le fichier

@@ -30,7 +30,7 @@ exports[`should render correctly: content 1`] = `
className="list-styled big-spacer-bottom"
>
<li>
onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source
onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source.bitbucket
</li>
<li>
onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner

+ 211
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/WebhookStep-test.tsx.snap Voir le fichier

@@ -0,0 +1,211 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`it should render correctly for azure: content 1`] = `
<div
className="boxed-group-inner"
>
<p
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
id="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
values={
Object {
"link": <ButtonLink
onClick={[MockFunction]}
>
onboarding.tutorial.with.jenkins.webhook.intro.link
</ButtonLink>,
}
}
/>
</p>
<ol
className="list-styled"
/>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

exports[`it should render correctly for azure: wrapper 1`] = `
<Step
finished={false}
onOpen={[MockFunction]}
open={false}
renderForm={[Function]}
stepNumber={2}
stepTitle="onboarding.tutorial.with.jenkins.webhook.azure.title"
/>
`;

exports[`it should render correctly for bitbucket: content 1`] = `
<div
className="boxed-group-inner"
>
<p
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
id="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
values={
Object {
"link": <ButtonLink
onClick={[MockFunction]}
>
onboarding.tutorial.with.jenkins.webhook.intro.link
</ButtonLink>,
}
}
/>
</p>
<ol
className="list-styled"
>
<WebhookStepBitbucket
almBinding={
Object {
"key": "key",
"personalAccessToken": "asdf1234",
"url": "http://bbs.enterprise.com",
}
}
projectBinding={
Object {
"alm": "bitbucket",
"key": "foo",
"repository": "PROJECT_KEY",
"slug": "repo-slug",
}
}
/>
</ol>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

exports[`it should render correctly for bitbucket: wrapper 1`] = `
<Step
finished={false}
onOpen={[MockFunction]}
open={false}
renderForm={[Function]}
stepNumber={2}
stepTitle="onboarding.tutorial.with.jenkins.webhook.bitbucket.title"
/>
`;

exports[`it should render correctly for github: content 1`] = `
<div
className="boxed-group-inner"
>
<p
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
id="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
values={
Object {
"link": <ButtonLink
onClick={[MockFunction]}
>
onboarding.tutorial.with.jenkins.webhook.intro.link
</ButtonLink>,
}
}
/>
</p>
<ol
className="list-styled"
>
<WebhookStepGithub
almBinding={
Object {
"appId": "123456",
"clientId": "client1",
"clientSecret": "**clientsecret**",
"key": "key",
"privateKey": "asdf1234",
"url": "http://github.enterprise.com",
}
}
projectBinding={
Object {
"alm": "github",
"key": "foo",
"repository": "PROJECT_KEY",
}
}
/>
</ol>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

exports[`it should render correctly for github: wrapper 1`] = `
<Step
finished={false}
onOpen={[MockFunction]}
open={false}
renderForm={[Function]}
stepNumber={2}
stepTitle="onboarding.tutorial.with.jenkins.webhook.github.title"
/>
`;

exports[`it should render correctly for gitlab: content 1`] = `
<div
className="boxed-group-inner"
>
<p
className="big-spacer-bottom"
>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
id="onboarding.tutorial.with.jenkins.webhook.intro.sentence"
values={
Object {
"link": <ButtonLink
onClick={[MockFunction]}
>
onboarding.tutorial.with.jenkins.webhook.intro.link
</ButtonLink>,
}
}
/>
</p>
<ol
className="list-styled"
/>
<Button
onClick={[MockFunction]}
>
continue
</Button>
</div>
`;

exports[`it should render correctly for gitlab: wrapper 1`] = `
<Step
finished={false}
onOpen={[MockFunction]}
open={false}
renderForm={[Function]}
stepNumber={2}
stepTitle="onboarding.tutorial.with.jenkins.webhook.gitlab.title"
/>
`;

+ 161
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/WebhookStepBitbucket-test.tsx.snap Voir le fichier

@@ -0,0 +1,161 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly 1`] = `
<Fragment>
<li>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
id="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
values={
Object {
"link": <a
href="http://bbs.enterprise.com/plugins/servlet/webhooks/projects/PROJECT_KEY/repos/repo-slug/create"
rel="noopener noreferrer"
target="_blank"
>
onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.link
</a>,
}
}
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.step1.name"
/>
</li>
<li
className="abs-width-600"
>
<p>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url"
/>
</p>
<CodeSnippet
isOneLine={true}
snippet="***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=http://bbs.enterprise.com"
/>
<Alert
variant="info"
>
onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url.warning
</Alert>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"events",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2"
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.repo"
/>
</li>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.pr"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"create",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.step3"
/>
</li>
</Fragment>
`;

exports[`should render correctly: with no alm binding 1`] = `
<Fragment>
<li>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
id="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
values={
Object {
"link": "onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.link",
}
}
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.step1.name"
/>
</li>
<li
className="abs-width-600"
>
<p>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url"
/>
</p>
<CodeSnippet
isOneLine={true}
snippet="***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=***BITBUCKET_URL***"
/>
<Alert
variant="info"
>
onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url.warning
</Alert>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"events",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2"
/>
<ul
className="list-styled"
>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.repo"
/>
</li>
<li>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.pr"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"create",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.step3"
/>
</li>
</Fragment>
`;

+ 143
- 0
server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/__snapshots__/WebhookStepGithub-test.tsx.snap Voir le fichier

@@ -0,0 +1,143 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly 1`] = `
<Fragment>
<li>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
id="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
values={
Object {
"link": <a
href="http://github.enterprise.com/PROJECT_KEY/settings/hooks"
rel="noopener noreferrer"
target="_blank"
>
onboarding.tutorial.with.jenkins.webhook.github.step1.link
</a>,
}
}
/>
<ul
className="list-styled"
>
<li
className="abs-width-600"
>
<p>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.github.step1.url"
/>
</p>
<CodeSnippet
isOneLine={true}
snippet="/github-webhook/"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"events",
"option",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.github.step2"
/>
<ul
className="list-styled"
>
<li>
<strong>
onboarding.tutorial.with.jenkins.webhook.github.step2.repo
</strong>
</li>
<li>
<strong>
onboarding.tutorial.with.jenkins.webhook.github.step2.pr
</strong>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"create",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.step3"
/>
</li>
</Fragment>
`;

exports[`should render correctly: with no alm binding 1`] = `
<Fragment>
<li>
<FormattedMessage
defaultMessage="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
id="onboarding.tutorial.with.jenkins.webhook.step1.sentence"
values={
Object {
"link": "onboarding.tutorial.with.jenkins.webhook.github.step1.link",
}
}
/>
<ul
className="list-styled"
>
<li
className="abs-width-600"
>
<p>
<LabelActionPair
translationKey="onboarding.tutorial.with.jenkins.webhook.github.step1.url"
/>
</p>
<CodeSnippet
isOneLine={true}
snippet="/github-webhook/"
/>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"events",
"option",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.github.step2"
/>
<ul
className="list-styled"
>
<li>
<strong>
onboarding.tutorial.with.jenkins.webhook.github.step2.repo
</strong>
</li>
<li>
<strong>
onboarding.tutorial.with.jenkins.webhook.github.step2.pr
</strong>
</li>
</ul>
</li>
<li>
<SentenceWithHighlights
highlightKeys={
Array [
"create",
]
}
translationKey="onboarding.tutorial.with.jenkins.webhook.step3"
/>
</li>
</Fragment>
`;

+ 14
- 0
server/sonar-web/src/main/js/components/tutorials/utils.ts Voir le fichier

@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { GithubBindingDefinition, ProjectAlmBindingResponse } from '../../types/alm-settings';
import { LanguageConfig } from './types';

export function isLanguageConfigured(config?: LanguageConfig) {
@@ -50,3 +51,16 @@ export function getUniqueTokenName(tokens: T.UserToken[], initialTokenName = '')
}
return `${initialTokenName} ${i}`;
}

export function buildGithubLink(
almBinding: GithubBindingDefinition,
projectBinding: ProjectAlmBindingResponse
) {
// strip the api path:
const urlRoot = almBinding.url
.replace('/api/v3', '') // GH Enterprise
.replace('api.', '') // GH.com
.replace(/\/$/, '');

return `${urlRoot}/${projectBinding.repository}`;
}

server/sonar-web/src/main/js/helpers/__tests__/alm-settings.ts → server/sonar-web/src/main/js/helpers/__tests__/alm-settings-test.ts Voir le fichier

@@ -17,25 +17,51 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { isBitbucketBindingDefinition, isProjectBitbucketBindingResponse } from '../alm-settings';
import { AlmKeys } from '../../types/alm-settings';
import {
isBitbucketBindingDefinition,
isGithubBindingDefinition,
isProjectBitbucketBindingResponse,
isProjectGitHubBindingResponse
} from '../alm-settings';
import {
mockBitbucketBindingDefinition,
mockGithubBindingDefinition,
mockProjectAlmBindingResponse,
mockProjectBitbucketBindingGet
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(mockProjectBitbucketBindingGet())).toBe(true);
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);
});
});

+ 24
- 3
server/sonar-web/src/main/js/helpers/alm-settings.ts Voir le fichier

@@ -21,8 +21,10 @@ import {
AlmBindingDefinition,
AlmKeys,
BitbucketBindingDefinition,
GithubBindingDefinition,
ProjectAlmBindingResponse,
ProjectBitbucketBindingResponse
ProjectBitbucketBindingResponse,
ProjectGitHubBindingResponse
} from '../types/alm-settings';

export function isProjectBitbucketBindingResponse(
@@ -31,8 +33,27 @@ export function isProjectBitbucketBindingResponse(
return binding.alm === AlmKeys.Bitbucket;
}

export function isProjectGitHubBindingResponse(
binding: ProjectAlmBindingResponse
): binding is ProjectGitHubBindingResponse {
return binding.alm === AlmKeys.GitHub;
}

export function isBitbucketBindingDefinition(
binding: AlmBindingDefinition & { url?: string; personalAccessToken?: string }
binding?: AlmBindingDefinition & { url?: string; personalAccessToken?: string }
): binding is BitbucketBindingDefinition {
return binding.url !== undefined && binding.personalAccessToken !== undefined;
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
);
}

+ 14
- 2
server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts Voir le fichier

@@ -25,7 +25,8 @@ import {
GithubBindingDefinition,
GitlabBindingDefinition,
ProjectAlmBindingResponse,
ProjectBitbucketBindingResponse
ProjectBitbucketBindingResponse,
ProjectGitHubBindingResponse
} from '../../types/alm-settings';

export function mockAlmSettingsInstance(
@@ -93,7 +94,7 @@ export function mockProjectAlmBindingResponse(
};
}

export function mockProjectBitbucketBindingGet(
export function mockProjectBitbucketBindingResponse(
overrides: Partial<ProjectBitbucketBindingResponse> = {}
): ProjectBitbucketBindingResponse {
return {
@@ -104,3 +105,14 @@ export function mockProjectBitbucketBindingGet(
...overrides
};
}

export function mockProjectGithubBindingResponse(
overrides: Partial<ProjectGitHubBindingResponse> = {}
): ProjectGitHubBindingResponse {
return {
alm: AlmKeys.GitHub,
key: 'foo',
repository: 'PROJECT_KEY',
...overrides
};
}

+ 5
- 0
server/sonar-web/src/main/js/types/alm-settings.ts Voir le fichier

@@ -64,6 +64,11 @@ export interface ProjectBitbucketBindingResponse extends ProjectAlmBindingRespon
slug: string;
}

export interface ProjectGitHubBindingResponse extends ProjectAlmBindingResponse {
alm: AlmKeys.GitHub;
repository: string;
}

export interface ProjectAlmBindingParams {
almSetting: string;
project: string;

+ 53
- 32
sonar-core/src/main/resources/org/sonar/l10n/core.properties Voir le fichier

@@ -3306,11 +3306,12 @@ onboarding.tutorial.choose_method.manual=Manually
onboarding.tutorial.choose_method.jenkins=With Jenkins

onboarding.tutorial.with.jenkins.title=Analyze your project with Jenkins
onboarding.tutorial.with.jenkins.only_bitbucket=This tutorial is only available for projects bound to Bitbucket Server.
onboarding.tutorial.with.jenkins.unsupported=This tutorial is only available for projects bound to Bitbucket Server or GitHub.
onboarding.tutorial.with.jenkins.prereqs.title=Prerequisites
onboarding.tutorial.with.jenkins.prereqs.intro.sentence=To run your project analyses with Jenkins, the following plugins {must_have}
onboarding.tutorial.with.jenkins.prereqs.intro.sentence.must_have=must be installed and configured:
onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source=Bitbucket Branch Source plugin for Jenkins - version 2.7 or later
onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source.bitbucket=Bitbucket Branch Source plugin for Jenkins - version 2.7 or later
onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source.github=GitHub Branch Source plugin for Jenkins - version 2.7.1 or later
onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner=SonarQube Scanner plugin for Jenkins - version 2.11 or later
onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide=For a step by step guide on installing and configuring those plugins in Jenkins, visit the {link} documentation page.
onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide.link=Analysis Prerequisites
@@ -3322,44 +3323,64 @@ onboarding.tutorial.with.jenkins.multi_branch_pipeline.intro=Create a Multibranc
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1.sentence=From Jenkins' dashboard, click {new_item} and create a {type}.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1.sentence.new_item=New Item
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1.sentence.type=Multibranch Pipeline Job
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.sentence=Under {tab}, add a Bitbucket source and enter the following information:
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.sentence.tab=Branch Sources
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server.label=Server
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server.action=select the instance hosting the repository you want to analyze.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds.label=Credentials
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds.action=select the Bitbucket Server credentials.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner.label=Owner
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner.action=enter your project key.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo.label=Repository
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo.action=select the repository you want to analyze.

onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.sentence=Under {tab}, add a Bitbucket source and enter the following information:
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.sentence.tab=Branch Sources
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.server.label=Server
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.server.action=select the instance hosting the repository you want to analyze.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.creds.label=Credentials
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.creds.action=select the Bitbucket Server credentials.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner.label=Owner
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.owner.action=enter your project key.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo.label=Repository
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.bitbucket.repo.action=select the repository you want to analyze.

onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.sentence=Under {tab}, add a GitHub source and enter the following information:
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.sentence.tab=Branch Sources
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.creds.label=Credentials
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.creds.action=select or add your GitHub credentials.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url.label=Repository HTTPS URL
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.github.repo_url.action=enter your repository URL.

onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour.label=Behavior
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour.action=select Exclude branches that are also filed as PRs.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.sentence=Jump to the {tab} section and set the following parameters:
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour.action=make sure Exclude branches that are also filed as PRs is selected.

onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.sentence=Jump to the {tab} section and make sure the parameters are set as follows:
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.sentence.tab=Build Configuration
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode.label=Mode
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode.action=by Jenkinsfile
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path.label=Script Path
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path.action=Jenkinsfile

onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4.sentence=Click {save}.
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4.sentence.save=Save
onboarding.tutorial.with.jenkins.bitbucket_webhook.title=Create a Bitbucket Server Webhook
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence=Create a Webhook in your repository to trigger the Jenkins job on push. Already have a Webhook configured? {link}
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link=Skip this step.
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence=Go to the {link} and enter the following information:
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link=Bitbucket Server Webhook creation page for your repository
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name.label=Name
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name.action=give a unique name.
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.label=URL
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.action=Enter the following URL, replacing the tokens as needed:
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning=The Bitbucket Server URL must be identical to the one in your Jenkins configuration. Watch out for any missing or extra "/" at the end.
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.sentence=Under {events}, make sure the following options are checked:
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.sentence.events=Events
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo.label=Repository
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo.action=Push
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr.label=Pull Request
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr.action=Opened
onboarding.tutorial.with.jenkins.bitbucket_webhook.step3.sentence=Click {create}.
onboarding.tutorial.with.jenkins.bitbucket_webhook.step3.sentence.create=Create
onboarding.tutorial.with.jenkins.webhook.bitbucket.title=Create a Bitbucket Server Webhook
onboarding.tutorial.with.jenkins.webhook.github.title=Create a GitHub Webhook
onboarding.tutorial.with.jenkins.webhook.intro.sentence=Create a Webhook in your repository to trigger the Jenkins job on push. Already have a Webhook configured? {link}
onboarding.tutorial.with.jenkins.webhook.intro.link=Skip this step.
onboarding.tutorial.with.jenkins.webhook.step1.sentence=Go to the {link} and enter the following information:
onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.link=Bitbucket Server Webhook creation page for your repository
onboarding.tutorial.with.jenkins.webhook.github.step1.link=GitHub Webhook creation page for your repository
onboarding.tutorial.with.jenkins.webhook.step1.name.label=Name
onboarding.tutorial.with.jenkins.webhook.step1.name.action=give a unique name.
onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url.label=URL
onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url.action=Enter the following URL, replacing the tokens as needed:
onboarding.tutorial.with.jenkins.webhook.bitbucket.step1.url.warning=The Bitbucket Server URL must be identical to the one in your Jenkins configuration. Watch out for any missing or extra "/" at the end.
onboarding.tutorial.with.jenkins.webhook.github.step1.url.label=URL
onboarding.tutorial.with.jenkins.webhook.github.step1.url.action=Enter your Jenkins instance URL and add the following path:
onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.sentence=Under {events}, make sure the following options are checked:
onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.sentence.events=Events
onboarding.tutorial.with.jenkins.webhook.github.step2.sentence=Under {events} select {option} and check the following:
onboarding.tutorial.with.jenkins.webhook.github.step2.sentence.events=Which events would you like to trigger this webhook?
onboarding.tutorial.with.jenkins.webhook.github.step2.sentence.option=Let me select individual events
onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.repo.label=Repository
onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.repo.action=Push
onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.pr.label=Pull Request
onboarding.tutorial.with.jenkins.webhook.bitbucket.step2.pr.action=Opened
onboarding.tutorial.with.jenkins.webhook.github.step2.repo=Pushes
onboarding.tutorial.with.jenkins.webhook.github.step2.pr=Pull Requests
onboarding.tutorial.with.jenkins.webhook.step3.sentence=Click {create}.
onboarding.tutorial.with.jenkins.webhook.step3.sentence.create=Create
onboarding.tutorial.with.jenkins.jenkinsfile.title=Create a Jenkinsfile
onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step.sentence=Create a {file} file in your repository and paste the following code:
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step2.sentence=Add the following to your {file} file:

Chargement…
Annuler
Enregistrer