import { HousekeepingPolicy } from '../../apps/audit-logs/utils';
import { BranchParameters } from '../../types/branch-like';
import { SettingsKey, SettingValue } from '../../types/settings';
-import { getValue } from '../settings';
+import { getAllValues, getValue, getValues } from '../settings';
export default class SettingsServiceMock {
settingValues: SettingValue[];
constructor() {
this.settingValues = cloneDeep(this.defaultValues);
- (getValue as jest.Mock).mockImplementation(this.handleGetValues);
+ (getValue as jest.Mock).mockImplementation(this.handleGetValue);
+ (getValues as jest.Mock).mockImplementation(this.handleGetValues);
+ (getAllValues as jest.Mock).mockImplementation(this.handleGetAllValues);
}
- handleGetValues = (data: { key: string; component?: string } & BranchParameters) => {
+ handleGetValue = (data: { key: string; component?: string } & BranchParameters) => {
const setting = this.settingValues.find(s => s.key === data.key);
-
return this.reply(setting);
};
- emptySettings() {
+ handleGetValues = (data: { keys: string[]; component?: string } & BranchParameters) => {
+ const settings = this.settingValues.filter(s => data.keys.includes(s.key));
+ return this.reply(settings);
+ };
+
+ handleGetAllValues = () => {
+ return this.reply(this.settingValues);
+ };
+
+ emptySettings = () => {
this.settingValues = [];
- }
+ return this;
+ };
- setYearlyHousekeepingPolicy() {
- const auditSetting = this.settingValues.find(s => s.key === SettingsKey.AuditHouseKeeping);
- if (auditSetting) {
- auditSetting.value = HousekeepingPolicy.Yearly;
+ set = (key: SettingsKey, value: string) => {
+ const setting = this.settingValues.find(s => s.key === key);
+ if (setting) {
+ setting.value = value;
+ } else {
+ this.settingValues.push({ key, value });
}
- }
+ return this;
+ };
- resetSettingvalues = () => {
+ reset = () => {
this.settingValues = cloneDeep(this.defaultValues);
+ return this;
};
reply<T>(response: T): Promise<T> {
import { getShortMonthName } from '../../../../helpers/l10n';
import { renderAppWithAdminContext } from '../../../../helpers/testReactTestingUtils';
import { AdminPageExtension } from '../../../../types/extension';
+import { SettingsKey } from '../../../../types/settings';
import routes from '../../routes';
+import { HousekeepingPolicy } from '../../utils';
jest.mock('../../../../api/settings');
handler = new SettingsServiceMock();
});
-afterEach(() => handler.resetSettingvalues());
+afterEach(() => handler.reset());
it('should handle download button click', async () => {
const user = userEvent.setup();
- handler.setYearlyHousekeepingPolicy();
+ handler.set(SettingsKey.AuditHouseKeeping, HousekeepingPolicy.Yearly);
renderAuditLogs();
const downloadButton = await ui.downloadButton.find();
expect(downloadButton).toBeInTheDocument();
});
it('should show right option when keeping log for year', async () => {
- handler.setYearlyHousekeepingPolicy();
+ handler.set(SettingsKey.AuditHouseKeeping, HousekeepingPolicy.Yearly);
renderAuditLogs();
expect(await ui.pageTitle.find()).toBeInTheDocument();
expect(ui.todayRadio.get()).toBeInTheDocument();
import { getAlmSettingsNoCatch } from '../../api/alm-settings';
import { getScannableProjects } from '../../api/components';
import { getValue } from '../../api/settings';
+import { ComponentContext } from '../../app/components/componentContext/ComponentContext';
+import { isMainBranch } from '../../helpers/branch-like';
import { getHostUrl } from '../../helpers/urls';
import { hasGlobalPermission } from '../../helpers/users';
import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../types/alm-settings';
+import { MainBranch } from '../../types/branch-like';
import { Permissions } from '../../types/permissions';
import { SettingsKey } from '../../types/settings';
import { Component } from '../../types/types';
loading: boolean;
}
+const DEFAULT_MAIN_BRANCH_NAME = 'main';
+
export class TutorialSelection extends React.PureComponent<Props, State> {
mounted = false;
state: State = {
const selectedTutorial: TutorialModes | undefined = location.query?.selectedTutorial;
return (
- <TutorialSelectionRenderer
- almBinding={almBinding}
- baseUrl={baseUrl}
- component={component}
- currentUser={currentUser}
- currentUserCanScanProject={currentUserCanScanProject}
- loading={loading}
- onSelectTutorial={this.handleSelectTutorial}
- projectBinding={projectBinding}
- selectedTutorial={selectedTutorial}
- willRefreshAutomatically={willRefreshAutomatically}
- />
+ <ComponentContext.Consumer>
+ {({ branchLikes }) => (
+ <TutorialSelectionRenderer
+ almBinding={almBinding}
+ baseUrl={baseUrl}
+ component={component}
+ currentUser={currentUser}
+ currentUserCanScanProject={currentUserCanScanProject}
+ loading={loading}
+ mainBranchName={
+ (branchLikes.find(b => isMainBranch(b)) as MainBranch | undefined)?.name ||
+ DEFAULT_MAIN_BRANCH_NAME
+ }
+ onSelectTutorial={this.handleSelectTutorial}
+ projectBinding={projectBinding}
+ selectedTutorial={selectedTutorial}
+ willRefreshAutomatically={willRefreshAutomatically}
+ />
+ )}
+ </ComponentContext.Consumer>
);
}
}
currentUser: LoggedInUser;
currentUserCanScanProject: boolean;
loading: boolean;
+ mainBranchName: string;
onSelectTutorial: (mode: TutorialModes) => void;
projectBinding?: ProjectAlmBindingResponse;
selectedTutorial?: TutorialModes;
currentUser,
currentUserCanScanProject,
loading,
+ mainBranchName,
projectBinding,
selectedTutorial,
willRefreshAutomatically
} = props;
if (loading) {
- return <i className="spinner" />;
+ return <i aria-label={translate('loading')} className="spinner" />;
}
if (!currentUserCanScanProject) {
if (projectBinding !== undefined) {
showGitHubActions = projectBinding.alm === AlmKeys.GitHub;
showGitLabCICD = projectBinding.alm === AlmKeys.GitLab;
- showBitbucketPipelines = projectBinding?.alm === AlmKeys.BitbucketCloud;
+ showBitbucketPipelines = projectBinding.alm === AlmKeys.BitbucketCloud;
showAzurePipelines = [AlmKeys.Azure, AlmKeys.GitHub].includes(projectBinding.alm);
showJenkins = [
AlmKeys.BitbucketCloud,
baseUrl={baseUrl}
component={component}
currentUser={currentUser}
+ mainBranchName={mainBranchName}
projectBinding={projectBinding}
willRefreshAutomatically={willRefreshAutomatically}
/>
baseUrl={baseUrl}
component={component}
currentUser={currentUser}
+ mainBranchName={mainBranchName}
willRefreshAutomatically={willRefreshAutomatically}
/>
)}
{selectedTutorial === TutorialModes.AzurePipelines && (
<AzurePipelinesTutorial
- alm={almBinding?.alm}
+ alm={projectBinding?.alm}
baseUrl={baseUrl}
component={component}
currentUser={currentUser}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { UserEvent } from '@testing-library/user-event/dist/types/setup';
+import * as React from 'react';
+import { byLabelText, byRole, byText } from 'testing-library-selector';
+import { getAlmSettingsNoCatch } from '../../../api/alm-settings';
+import { getScannableProjects } from '../../../api/components';
+import SettingsServiceMock from '../../../api/mocks/SettingsServiceMock';
+import UserTokensMock from '../../../api/mocks/UserTokensMock';
+import {
+ mockGithubBindingDefinition,
+ mockProjectAlmBindingResponse
+} from '../../../helpers/mocks/alm-settings';
+import { mockComponent } from '../../../helpers/mocks/component';
+import { mockLoggedInUser } from '../../../helpers/testMocks';
+import { renderApp } from '../../../helpers/testReactTestingUtils';
+import { AlmKeys } from '../../../types/alm-settings';
+import { Feature } from '../../../types/features';
+import { Permissions } from '../../../types/permissions';
+import { SettingsKey } from '../../../types/settings';
+import { withRouter } from '../../hoc/withRouter';
+import { TutorialSelection } from '../TutorialSelection';
+import { TutorialModes } from '../types';
+
+jest.mock('../../../api/settings');
+jest.mock('../../../api/user-tokens');
+
+jest.mock('../../../helpers/urls', () => ({
+ ...jest.requireActual('../../../helpers/urls'),
+ getHostUrl: jest.fn().mockReturnValue('http://host.url')
+}));
+
+jest.mock('../../../api/alm-settings', () => ({
+ getAlmSettingsNoCatch: jest.fn().mockRejectedValue(null)
+}));
+
+jest.mock('../../../api/components', () => ({
+ getScannableProjects: jest.fn().mockResolvedValue({ projects: [] })
+}));
+
+let settingsMock: SettingsServiceMock;
+let tokenMock: UserTokensMock;
+
+beforeAll(() => {
+ settingsMock = new SettingsServiceMock();
+ tokenMock = new UserTokensMock();
+});
+
+afterEach(() => {
+ tokenMock.reset();
+ settingsMock.reset();
+});
+
+beforeEach(jest.clearAllMocks);
+
+const ui = {
+ loading: byLabelText('loading'),
+ noScanRights: byText('onboarding.tutorial.no_scan_rights'),
+ chooseTutorialBtn: (mode: TutorialModes) =>
+ byRole('button', { name: `onboarding.tutorial.choose_method.${mode}` })
+};
+
+it.each([
+ [TutorialModes.Jenkins, 'onboarding.tutorial.with.jenkins.title'],
+ [TutorialModes.AzurePipelines, 'onboarding.tutorial.with.azure_pipelines.title'],
+ [
+ TutorialModes.BitbucketPipelines,
+ 'onboarding.tutorial.with.bitbucket_pipelines.create_secret.title'
+ ],
+ [TutorialModes.GitHubActions, 'onboarding.tutorial.with.github_action.create_secret.title'],
+ [TutorialModes.GitLabCI, 'onboarding.tutorial.with.gitlab_ci.title'],
+ [TutorialModes.Local, 'onboarding.project_analysis.header'],
+ [TutorialModes.OtherCI, 'onboarding.project_analysis.header']
+])('should behave correctly for %s', async (mode, title) => {
+ const user = userEvent.setup();
+ renderTutorialSelection();
+ await waitOnDataLoaded();
+
+ expect(screen.getByText('onboarding.tutorial.choose_method')).toBeInTheDocument();
+
+ await user.click(ui.chooseTutorialBtn(mode).get());
+ expect(screen.getByText(title)).toBeInTheDocument();
+});
+
+it.each([
+ [
+ AlmKeys.GitHub,
+ [TutorialModes.GitHubActions, TutorialModes.Jenkins, TutorialModes.AzurePipelines]
+ ],
+ [AlmKeys.GitLab, [TutorialModes.GitLabCI, TutorialModes.Jenkins]],
+ [AlmKeys.Azure, [TutorialModes.AzurePipelines]],
+ [AlmKeys.BitbucketServer, [TutorialModes.Jenkins]],
+ [AlmKeys.BitbucketCloud, [TutorialModes.BitbucketPipelines, TutorialModes.Jenkins]]
+])('should show correct buttons if project is bound to %s', async (alm, modes) => {
+ renderTutorialSelection({ projectBinding: mockProjectAlmBindingResponse({ alm }) });
+ await waitOnDataLoaded();
+
+ modes.forEach(mode => expect(ui.chooseTutorialBtn(mode).get()).toBeInTheDocument());
+});
+
+it('should correctly fetch the corresponding ALM setting', async () => {
+ (getAlmSettingsNoCatch as jest.Mock).mockResolvedValueOnce([
+ mockGithubBindingDefinition({ key: 'binding', url: 'https://enterprise.github.com' })
+ ]);
+ const user = userEvent.setup();
+ renderTutorialSelection({
+ projectBinding: mockProjectAlmBindingResponse({ alm: AlmKeys.GitHub, key: 'binding' })
+ });
+ await waitOnDataLoaded();
+
+ await startJenkinsTutorial(user);
+ expect(screen.getByText('https://enterprise.github.com', { exact: false })).toBeInTheDocument();
+});
+
+it('should correctly fetch the instance URL', async () => {
+ settingsMock.set(SettingsKey.ServerBaseUrl, 'http://sq.example.com');
+ const user = userEvent.setup();
+ renderTutorialSelection();
+ await waitOnDataLoaded();
+
+ await startLocalTutorial(user);
+ expect(
+ screen.getByText('-Dsonar.host.url=http://sq.example.com', { exact: false })
+ ).toBeInTheDocument();
+});
+
+it('should fallback on the host URL', async () => {
+ const user = userEvent.setup();
+ renderTutorialSelection();
+ await waitOnDataLoaded();
+
+ await startLocalTutorial(user);
+ expect(
+ screen.getByText('-Dsonar.host.url=http://host.url', { exact: false })
+ ).toBeInTheDocument();
+});
+
+it('should not display a warning if the user has no global scan permission, but can scan the project', async () => {
+ (getScannableProjects as jest.Mock).mockResolvedValueOnce({ projects: [{ key: 'foo' }] });
+ renderTutorialSelection({ currentUser: mockLoggedInUser() });
+ await waitOnDataLoaded();
+
+ expect(ui.noScanRights.query()).not.toBeInTheDocument();
+});
+
+it('should correctly display a warning if the user has no scan permissions', async () => {
+ renderTutorialSelection({ currentUser: mockLoggedInUser() });
+ await waitOnDataLoaded();
+
+ expect(ui.noScanRights.query()).toBeInTheDocument();
+});
+
+async function waitOnDataLoaded() {
+ await waitFor(() => {
+ expect(ui.loading.query()).not.toBeInTheDocument();
+ });
+}
+
+async function startLocalTutorial(user: UserEvent) {
+ await user.click(ui.chooseTutorialBtn(TutorialModes.Local).get());
+ await user.click(screen.getByRole('button', { name: 'onboarding.token.generate' }));
+ await user.click(screen.getByRole('button', { name: 'continue' }));
+ await user.click(screen.getByRole('button', { name: 'onboarding.build.maven' }));
+}
+
+async function startJenkinsTutorial(user: UserEvent) {
+ await user.click(ui.chooseTutorialBtn(TutorialModes.Jenkins).get());
+ await user.click(
+ screen.getByRole('button', { name: 'onboarding.tutorial.with.jenkins.prereqs.done' })
+ );
+}
+
+function renderTutorialSelection(props: Partial<TutorialSelection['props']> = {}) {
+ const Wrapper = withRouter(({ router, location, ...subProps }: TutorialSelection['props']) => {
+ return <TutorialSelection location={location} router={router} {...subProps} />;
+ });
+
+ return renderApp(
+ '/',
+ <Wrapper
+ component={mockComponent({ key: 'foo' })}
+ currentUser={mockLoggedInUser({ permissions: { global: [Permissions.Scan] } })}
+ {...props}
+ />,
+ { featureList: [Feature.BranchSupport] }
+ );
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { getAlmSettingsNoCatch } from '../../../api/alm-settings';
-import { getScannableProjects } from '../../../api/components';
-import { getValue } from '../../../api/settings';
-import {
- mockAlmSettingsInstance,
- mockProjectBitbucketBindingResponse
-} from '../../../helpers/mocks/alm-settings';
-import { mockComponent } from '../../../helpers/mocks/component';
-import { mockLocation, mockLoggedInUser, mockRouter } from '../../../helpers/testMocks';
-import { waitAndUpdate } from '../../../helpers/testUtils';
-import { getHostUrl } from '../../../helpers/urls';
-import { Permissions } from '../../../types/permissions';
-import { SettingsKey } from '../../../types/settings';
-import { TutorialSelection } from '../TutorialSelection';
-import { TutorialModes } from '../types';
-
-jest.mock('../../../helpers/urls', () => ({
- getHostUrl: jest.fn().mockReturnValue('http://host.url')
-}));
-
-jest.mock('../../../api/alm-settings', () => ({
- getAlmSettingsNoCatch: jest.fn().mockRejectedValue(null)
-}));
-
-jest.mock('../../../api/settings', () => ({
- getValue: jest.fn().mockResolvedValue({})
-}));
-
-jest.mock('../../../api/components', () => ({
- getScannableProjects: jest.fn().mockResolvedValue({ projects: [] })
-}));
-
-beforeEach(jest.clearAllMocks);
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should correctly find the global ALM binding definition', async () => {
- const key = 'foo';
- const almBinding = mockAlmSettingsInstance({ key });
- (getAlmSettingsNoCatch as jest.Mock).mockResolvedValueOnce([
- almBinding,
- mockAlmSettingsInstance({ key: 'bar' })
- ]);
- const wrapper = shallowRender({ projectBinding: mockProjectBitbucketBindingResponse({ key }) });
- await waitAndUpdate(wrapper);
- expect(wrapper.state().almBinding).toBe(almBinding);
-});
-
-it('should handle selection', () => {
- const push = jest.fn();
- const wrapper = shallowRender({ router: mockRouter({ push }) });
- const instance = wrapper.instance();
-
- instance.handleSelectTutorial(TutorialModes.Local);
- expect(push).toHaveBeenLastCalledWith(
- expect.objectContaining({
- query: { selectedTutorial: TutorialModes.Local }
- })
- );
-
- instance.handleSelectTutorial(TutorialModes.Jenkins);
- expect(push).toHaveBeenLastCalledWith(
- expect.objectContaining({
- query: { selectedTutorial: TutorialModes.Jenkins }
- })
- );
-});
-
-it('should fetch the correct baseUrl', async () => {
- (getValue as jest.Mock)
- .mockResolvedValueOnce({ key: SettingsKey.ServerBaseUrl, value: '' })
- .mockResolvedValueOnce({ key: SettingsKey.ServerBaseUrl, value: 'http://sq.example.com' })
- .mockRejectedValueOnce(null);
-
- let wrapper = shallowRender();
-
- expect(getValue).toHaveBeenCalled();
- expect(getHostUrl).toHaveBeenCalled();
-
- // No baseURL, fallback to the URL in the browser.
- await waitAndUpdate(wrapper);
- expect(wrapper.state().baseUrl).toBe('http://host.url');
-
- // A baseURL was set.
- wrapper = shallowRender();
- await waitAndUpdate(wrapper);
- expect(wrapper.state().baseUrl).toBe('http://sq.example.com');
-
- // Access denied, fallback to the URL in the browser.
- wrapper = shallowRender();
- await waitAndUpdate(wrapper);
- expect(wrapper.state().baseUrl).toBe('http://host.url');
-});
-
-it("should correctly determine the user's permission", async () => {
- const component = mockComponent({ key: 'bar', name: 'Bar' });
- (getScannableProjects as jest.Mock)
- .mockResolvedValueOnce({
- projects: [
- { key: 'foo', name: 'Foo' },
- { key: component.key, name: component.name }
- ]
- })
- .mockResolvedValueOnce({ projects: [{ key: 'foo', name: 'Foo' }] });
-
- // Global scan permission.
- let wrapper = shallowRender({
- component,
- currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Scan] } })
- });
- await waitAndUpdate(wrapper);
- expect(wrapper.state().currentUserCanScanProject).toBe(true);
- expect(getScannableProjects).not.toHaveBeenCalled();
-
- // Project scan permission.
- wrapper = shallowRender({ component });
- await waitAndUpdate(wrapper);
- expect(getScannableProjects).toHaveBeenCalled();
- expect(wrapper.state().currentUserCanScanProject).toBe(true);
-
- // No scan permission.
- wrapper = shallowRender({ component });
- await waitAndUpdate(wrapper);
- expect(getScannableProjects).toHaveBeenCalledTimes(2);
- expect(wrapper.state().currentUserCanScanProject).toBe(false);
-});
-
-function shallowRender(props: Partial<TutorialSelection['props']> = {}) {
- return shallow<TutorialSelection>(
- <TutorialSelection
- component={mockComponent()}
- currentUser={mockLoggedInUser()}
- location={mockLocation()}
- router={mockRouter()}
- {...props}
- />
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 {
- mockAlmSettingsInstance,
- mockProjectAzureBindingResponse,
- mockProjectBitbucketBindingResponse,
- mockProjectBitbucketCloudBindingResponse,
- mockProjectGithubBindingResponse,
- mockProjectGitLabBindingResponse
-} from '../../../helpers/mocks/alm-settings';
-import { mockComponent } from '../../../helpers/mocks/component';
-import { mockLoggedInUser } from '../../../helpers/testMocks';
-import { click } from '../../../helpers/testUtils';
-import TutorialSelectionRenderer, {
- TutorialSelectionRendererProps
-} from '../TutorialSelectionRenderer';
-import { TutorialModes } from '../types';
-
-it.each([
- ['bitbucket server', mockProjectBitbucketBindingResponse()],
- ['github', mockProjectGithubBindingResponse()],
- ['gitlab', mockProjectGitLabBindingResponse()],
- ['azure', mockProjectAzureBindingResponse()]
-])('should render correctly for %s', (_, projectBinding) => {
- expect(shallowRender({ projectBinding })).toMatchSnapshot();
-});
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('selection');
- expect(shallowRender({ loading: true })).toMatchSnapshot('loading');
- expect(shallowRender({ selectedTutorial: TutorialModes.Local })).toMatchSnapshot(
- 'manual tutorial'
- );
- expect(
- shallowRender({
- selectedTutorial: TutorialModes.Jenkins,
- projectBinding: mockProjectBitbucketBindingResponse()
- })
- ).toMatchSnapshot('jenkins tutorial');
- expect(
- shallowRender({
- selectedTutorial: TutorialModes.GitHubActions,
- projectBinding: mockProjectGithubBindingResponse()
- })
- ).toMatchSnapshot('github actions tutorial');
- expect(
- shallowRender({
- selectedTutorial: TutorialModes.GitLabCI,
- projectBinding: mockProjectGitLabBindingResponse()
- })
- ).toMatchSnapshot('gitlab tutorial');
- expect(
- shallowRender({
- selectedTutorial: TutorialModes.AzurePipelines,
- projectBinding: mockProjectAzureBindingResponse()
- })
- ).toMatchSnapshot('azure pipelines tutorial');
- expect(shallowRender({ currentUserCanScanProject: false })).toMatchSnapshot(
- 'user has no scan permission'
- );
-});
-
-it('should allow mode selection for Bitbucket', () => {
- const onSelectTutorial = jest.fn();
- const wrapper = shallowRender({
- onSelectTutorial,
- projectBinding: mockProjectBitbucketBindingResponse()
- });
-
- click(wrapper.find('button.tutorial-mode-jenkins'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins);
-
- click(wrapper.find('button.tutorial-mode-local'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local);
-});
-
-it('should allow mode selection for Github', () => {
- const onSelectTutorial = jest.fn();
- const wrapper = shallowRender({
- onSelectTutorial,
- projectBinding: mockProjectGithubBindingResponse()
- });
-
- click(wrapper.find('button.tutorial-mode-jenkins'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins);
-
- click(wrapper.find('button.tutorial-mode-local'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local);
-
- click(wrapper.find('button.tutorial-mode-github-actions'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.GitHubActions);
-
- click(wrapper.find('button.tutorial-mode-azure-pipelines'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.AzurePipelines);
-});
-
-it('should allow mode selection for GitLab', () => {
- const onSelectTutorial = jest.fn();
- const wrapper = shallowRender({
- onSelectTutorial,
- projectBinding: mockProjectGitLabBindingResponse()
- });
-
- click(wrapper.find('button.tutorial-mode-jenkins'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins);
-
- click(wrapper.find('button.tutorial-mode-gitlab-ci'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.GitLabCI);
-
- click(wrapper.find('button.tutorial-mode-local'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local);
-});
-
-it('should allow mode selection for Bitbucket pipepline', () => {
- const onSelectTutorial = jest.fn();
- const wrapper = shallowRender({
- onSelectTutorial,
- projectBinding: mockProjectBitbucketCloudBindingResponse()
- });
-
- click(wrapper.find('button.tutorial-mode-jenkins'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins);
-
- click(wrapper.find('button.tutorial-mode-bitbucket-pipelines'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.BitbucketPipelines);
-
- click(wrapper.find('button.tutorial-mode-local'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local);
-});
-
-it('should allow mode selection for Azure DevOps', () => {
- const onSelectTutorial = jest.fn();
- const wrapper = shallowRender({
- onSelectTutorial,
- projectBinding: mockProjectAzureBindingResponse()
- });
-
- click(wrapper.find('button.tutorial-mode-azure-pipelines'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.AzurePipelines);
-
- click(wrapper.find('button.tutorial-mode-local'));
- expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local);
-});
-
-function shallowRender(props: Partial<TutorialSelectionRendererProps> = {}) {
- return shallow<TutorialSelectionRendererProps>(
- <TutorialSelectionRenderer
- almBinding={mockAlmSettingsInstance()}
- baseUrl="http://localhost:9000"
- component={mockComponent()}
- currentUser={mockLoggedInUser()}
- currentUserCanScanProject={true}
- loading={false}
- onSelectTutorial={jest.fn()}
- {...props}
- />
- );
-}
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<TutorialSelectionRenderer
- baseUrl="http://host.url"
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "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 {
- "dismissedNotices": Object {
- "educationPrinciples": false,
- },
- "groups": Array [],
- "isLoggedIn": true,
- "login": "luke",
- "name": "Skywalker",
- "scmAccounts": Array [],
- }
- }
- currentUserCanScanProject={false}
- loading={true}
- onSelectTutorial={[Function]}
-/>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly for azure 1`] = `
-<Fragment>
- <h2
- className="spacer-top huge-spacer-bottom"
- >
- onboarding.tutorial.choose_method
- </h2>
- <div
- className="tutorial-selection"
- >
- <p
- className="big-spacer-bottom"
- >
- onboarding.tutorial.choose_method.devops_platform.description
- </p>
- <div
- className="display-flex-start display-flex-wrap"
- >
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-azure-pipelines"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/azure-pipelines.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.azure-pipelines
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-other-ci"
- onClick={[Function]}
- type="button"
- >
- <EllipsisIcon
- size={60}
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.other-ci
- </div>
- </button>
- </div>
- <p
- className="big-spacer-bottom spacer-top"
- >
- onboarding.tutorial.choose_method.local.description
- </p>
- <div>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-local"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/manual.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.local
- </div>
- </button>
- </div>
- </div>
-</Fragment>
-`;
-
-exports[`should render correctly for bitbucket server 1`] = `
-<Fragment>
- <h2
- className="spacer-top huge-spacer-bottom"
- >
- onboarding.tutorial.choose_method
- </h2>
- <div
- className="tutorial-selection"
- >
- <p
- className="big-spacer-bottom"
- >
- onboarding.tutorial.choose_method.devops_platform.description
- </p>
- <div
- className="display-flex-start display-flex-wrap"
- >
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-jenkins"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/jenkins.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.jenkins
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-other-ci"
- onClick={[Function]}
- type="button"
- >
- <EllipsisIcon
- size={60}
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.other-ci
- </div>
- </button>
- </div>
- <p
- className="big-spacer-bottom spacer-top"
- >
- onboarding.tutorial.choose_method.local.description
- </p>
- <div>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-local"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/manual.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.local
- </div>
- </button>
- </div>
- </div>
-</Fragment>
-`;
-
-exports[`should render correctly for github 1`] = `
-<Fragment>
- <h2
- className="spacer-top huge-spacer-bottom"
- >
- onboarding.tutorial.choose_method
- </h2>
- <div
- className="tutorial-selection"
- >
- <p
- className="big-spacer-bottom"
- >
- onboarding.tutorial.choose_method.devops_platform.description
- </p>
- <div
- className="display-flex-start display-flex-wrap"
- >
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-jenkins"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/jenkins.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.jenkins
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-github-actions"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- className="spacer-bottom spacer-top"
- height={46}
- src="/images/tutorials/github-actions.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.github-actions
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-azure-pipelines"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/azure-pipelines.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.azure-pipelines
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-other-ci"
- onClick={[Function]}
- type="button"
- >
- <EllipsisIcon
- size={60}
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.other-ci
- </div>
- </button>
- </div>
- <p
- className="big-spacer-bottom spacer-top"
- >
- onboarding.tutorial.choose_method.local.description
- </p>
- <div>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-local"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/manual.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.local
- </div>
- </button>
- </div>
- </div>
-</Fragment>
-`;
-
-exports[`should render correctly for gitlab 1`] = `
-<Fragment>
- <h2
- className="spacer-top huge-spacer-bottom"
- >
- onboarding.tutorial.choose_method
- </h2>
- <div
- className="tutorial-selection"
- >
- <p
- className="big-spacer-bottom"
- >
- onboarding.tutorial.choose_method.devops_platform.description
- </p>
- <div
- className="display-flex-start display-flex-wrap"
- >
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-jenkins"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/jenkins.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.jenkins
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-gitlab-ci"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/alm/gitlab.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.gitlab-ci
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-other-ci"
- onClick={[Function]}
- type="button"
- >
- <EllipsisIcon
- size={60}
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.other-ci
- </div>
- </button>
- </div>
- <p
- className="big-spacer-bottom spacer-top"
- >
- onboarding.tutorial.choose_method.local.description
- </p>
- <div>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-local"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/manual.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.local
- </div>
- </button>
- </div>
- </div>
-</Fragment>
-`;
-
-exports[`should render correctly: azure pipelines tutorial 1`] = `
-<Fragment>
- <AzurePipelinesTutorial
- alm="github"
- baseUrl="http://localhost:9000"
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "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 {
- "dismissedNotices": Object {
- "educationPrinciples": false,
- },
- "groups": Array [],
- "isLoggedIn": true,
- "login": "luke",
- "name": "Skywalker",
- "scmAccounts": Array [],
- }
- }
- />
-</Fragment>
-`;
-
-exports[`should render correctly: github actions tutorial 1`] = `
-<Fragment>
- <GitHubActionTutorial
- almBinding={
- Object {
- "alm": "github",
- "key": "key",
- }
- }
- baseUrl="http://localhost:9000"
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "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 {
- "dismissedNotices": Object {
- "educationPrinciples": false,
- },
- "groups": Array [],
- "isLoggedIn": true,
- "login": "luke",
- "name": "Skywalker",
- "scmAccounts": Array [],
- }
- }
- projectBinding={
- Object {
- "alm": "github",
- "key": "foo",
- "monorepo": true,
- "repository": "PROJECT_KEY",
- }
- }
- />
-</Fragment>
-`;
-
-exports[`should render correctly: gitlab tutorial 1`] = `
-<Fragment>
- <GitLabCITutorial
- baseUrl="http://localhost:9000"
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "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 {
- "dismissedNotices": Object {
- "educationPrinciples": false,
- },
- "groups": Array [],
- "isLoggedIn": true,
- "login": "luke",
- "name": "Skywalker",
- "scmAccounts": Array [],
- }
- }
- />
-</Fragment>
-`;
-
-exports[`should render correctly: jenkins tutorial 1`] = `
-<Fragment>
- <withAvailableFeaturesContext(JenkinsTutorial)
- almBinding={
- Object {
- "alm": "github",
- "key": "key",
- }
- }
- baseUrl="http://localhost:9000"
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "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 [],
- }
- }
- projectBinding={
- Object {
- "alm": "bitbucket",
- "key": "foo",
- "monorepo": true,
- "repository": "PROJECT_KEY",
- "slug": "repo-slug",
- }
- }
- />
-</Fragment>
-`;
-
-exports[`should render correctly: loading 1`] = `
-<i
- className="spinner"
-/>
-`;
-
-exports[`should render correctly: manual tutorial 1`] = `
-<Fragment>
- <OtherTutorial
- baseUrl="http://localhost:9000"
- component={
- Object {
- "breadcrumbs": Array [],
- "key": "my-project",
- "name": "MyProject",
- "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 {
- "dismissedNotices": Object {
- "educationPrinciples": false,
- },
- "groups": Array [],
- "isLoggedIn": true,
- "login": "luke",
- "name": "Skywalker",
- "scmAccounts": Array [],
- }
- }
- isLocal={true}
- />
-</Fragment>
-`;
-
-exports[`should render correctly: selection 1`] = `
-<Fragment>
- <h2
- className="spacer-top huge-spacer-bottom"
- >
- onboarding.tutorial.choose_method
- </h2>
- <div
- className="tutorial-selection"
- >
- <p
- className="big-spacer-bottom"
- >
- onboarding.tutorial.choose_method.devops_platform.description
- </p>
- <div
- className="display-flex-start display-flex-wrap"
- >
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-jenkins"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/jenkins.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.jenkins
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-github-actions"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- className="spacer-bottom spacer-top"
- height={46}
- src="/images/tutorials/github-actions.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.github-actions
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-bitbucket-pipelines"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/alm/bitbucket.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.bitbucket-pipelines
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-gitlab-ci"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/alm/gitlab.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.gitlab-ci
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-azure-pipelines"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/azure-pipelines.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.azure-pipelines
- </div>
- </button>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-other-ci"
- onClick={[Function]}
- type="button"
- >
- <EllipsisIcon
- size={60}
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.other-ci
- </div>
- </button>
- </div>
- <p
- className="big-spacer-bottom spacer-top"
- >
- onboarding.tutorial.choose_method.local.description
- </p>
- <div>
- <button
- className="button button-huge display-flex-column big-spacer-right big-spacer-bottom tutorial-mode-local"
- onClick={[Function]}
- type="button"
- >
- <img
- alt=""
- height={60}
- src="/images/tutorials/manual.svg"
- />
- <div
- className="medium big-spacer-top"
- >
- onboarding.tutorial.choose_method.local
- </div>
- </button>
- </div>
- </div>
-</Fragment>
-`;
-
-exports[`should render correctly: user has no scan permission 1`] = `
-<Alert
- variant="warning"
->
- onboarding.tutorial.no_scan_rights
-</Alert>
-`;
export interface AnalysisCommandProps extends WithAvailableFeaturesProps {
buildTool: BuildTools;
+ mainBranchName: string;
component: Component;
onDone: () => void;
}
export function AnalysisCommand(props: AnalysisCommandProps) {
- const { buildTool, component } = props;
+ const { buildTool, component, mainBranchName } = props;
const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
if (!buildTool) {
return (
<JavaMaven
branchesEnabled={branchSupportEnabled}
+ mainBranchName={mainBranchName}
component={component}
onDone={props.onDone}
/>
return (
<Gradle
branchesEnabled={branchSupportEnabled}
+ mainBranchName={mainBranchName}
component={component}
onDone={props.onDone}
/>
return (
<DotNet
branchesEnabled={branchSupportEnabled}
+ mainBranchName={mainBranchName}
component={component}
onDone={props.onDone}
/>
return (
<CFamily
branchesEnabled={branchSupportEnabled}
+ mainBranchName={mainBranchName}
component={component}
onDone={props.onDone}
/>
return (
<Others
branchesEnabled={branchSupportEnabled}
+ mainBranchName={mainBranchName}
component={component}
onDone={props.onDone}
/>
);
}
- return null;
}
export default withAvailableFeatures(AnalysisCommand);
baseUrl: string;
component: Component;
currentUser: LoggedInUser;
+ mainBranchName: string;
projectBinding?: ProjectAlmBindingResponse;
willRefreshAutomatically?: boolean;
}
currentUser,
component,
projectBinding,
+ mainBranchName,
willRefreshAutomatically
} = props;
{buildTool => (
<AnalysisCommand
buildTool={buildTool}
+ mainBranchName={mainBranchName}
component={component}
onDone={() => setStep(Steps.ALL_SET)}
/>
return shallow<AnalysisCommandProps>(
<AnalysisCommand
hasFeature={jest.fn().mockReturnValue(false)}
+ mainBranchName="main"
component={mockComponent()}
buildTool={BuildTools.DotNet}
onDone={jest.fn()}
baseUrl="test"
currentUser={mockLoggedInUser()}
component={mockComponent()}
+ mainBranchName="master"
projectBinding={mockProjectGithubBindingResponse()}
willRefreshAutomatically={true}
{...props}
"tags": Array [],
}
}
+ mainBranchName="main"
onDone={[MockFunction]}
/>
`;
"tags": Array [],
}
}
+ mainBranchName="main"
onDone={[MockFunction]}
/>
`;
"tags": Array [],
}
}
+ mainBranchName="main"
onDone={[MockFunction]}
/>
`;
"tags": Array [],
}
}
+ mainBranchName="main"
onDone={[MockFunction]}
/>
`;
"tags": Array [],
}
}
+ mainBranchName="main"
onDone={[MockFunction]}
/>
`;
import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories';
import RenderOptions from '../../components/RenderOptions';
import { OSs, TutorialModes } from '../../types';
+import { generateGitHubActionsYaml } from '../utils';
export interface CFamilyProps {
branchesEnabled?: boolean;
+ mainBranchName: string;
component: Component;
onDone: () => void;
}
const STEPS = {
- [OSs.Linux]: `steps:
- - name: Checkout code
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
-
+ [OSs.Linux]: `
- name: Download and install the build wrapper, build the project
run: |
mkdir $HOME/.sonar
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}`,
- [OSs.MacOS]: `steps:
- - name: Checkout code
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
-
+ [OSs.MacOS]: `
- name: Download and install the build wrapper
run: |
mkdir $HOME/.sonar
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}`,
- [OSs.Windows]: `steps:
- - name: Checkout code
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
-
+ [OSs.Windows]: `
- name: Download and install the build wrapper
shell: powershell
run: |
SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}`
};
-const cfamilyYamlTemplate = (branchesEnabled: boolean, os: OSs) => `name: Build
-on:
- push:
- branches:
- - master # or the name of your main branch
-${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''}
-
-jobs:
- build:
- runs-on: <image ready for your build toolchain>
- ${STEPS[os]}
-`;
-
export default function CFamily(props: CFamilyProps) {
- const { component, branchesEnabled } = props;
+ const { component, branchesEnabled, mainBranchName } = props;
const [os, setOs] = React.useState<undefined | OSs>();
return (
<>
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
- yamlTemplate={cfamilyYamlTemplate(!!branchesEnabled, os)}
+ yamlTemplate={generateGitHubActionsYaml(
+ mainBranchName,
+ !!branchesEnabled,
+ '<image ready for your build toolchain>',
+ STEPS[os]
+ )}
/>
<CompilationInfo className="abs-width-800" />
<FinishButton onClick={props.onDone} />
import { Component } from '../../../../types/types';
import CreateYmlFile from '../../components/CreateYmlFile';
import FinishButton from '../../components/FinishButton';
+import { GITHUB_ACTIONS_RUNS_ON_WINDOWS } from '../constants';
+import { generateGitHubActionsYaml } from '../utils';
export interface DotNetProps {
branchesEnabled?: boolean;
+ mainBranchName: string;
component: Component;
onDone: () => void;
}
-const dotnetYamlTemplate = (projectKey: string, branchesEnabled: boolean) => `name: Build
-on:
- push:
- branches:
- - master # or the name of your main branch
-${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''}
-jobs:
- build:
- name: Build
- runs-on: windows-latest
- steps:
+function dotnetYamlSteps(projectKey: string) {
+ return `
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.11
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Cache SonarQube packages
uses: actions/cache@v1
with:
.\\.sonar\\scanner\\dotnet-sonarscanner begin /k:"${projectKey}" /d:sonar.login="\${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="\${{ secrets.SONAR_HOST_URL }}"
dotnet build
.\\.sonar\\scanner\\dotnet-sonarscanner end /d:sonar.login="\${{ secrets.SONAR_TOKEN }}"`;
+}
export default function DotNet(props: DotNetProps) {
- const { component, branchesEnabled } = props;
+ const { component, branchesEnabled, mainBranchName } = props;
return (
<>
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
- yamlTemplate={dotnetYamlTemplate(component.key, !!branchesEnabled)}
+ yamlTemplate={generateGitHubActionsYaml(
+ mainBranchName,
+ !!branchesEnabled,
+ GITHUB_ACTIONS_RUNS_ON_WINDOWS,
+ dotnetYamlSteps(component.key)
+ )}
/>
<FinishButton onClick={props.onDone} />
</>
import CreateYmlFile from '../../components/CreateYmlFile';
import FinishButton from '../../components/FinishButton';
import { buildGradleSnippet } from '../../utils';
+import { GITHUB_ACTIONS_RUNS_ON_LINUX } from '../constants';
+import { generateGitHubActionsYaml } from '../utils';
export interface GradleProps {
branchesEnabled?: boolean;
+ mainBranchName: string;
component: Component;
onDone: () => void;
}
-const gradleYamlTemplate = (branchesEnabled: boolean) => `name: Build
-on:
- push:
- branches:
- - master # or the name of your main branch
-${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''}
-jobs:
- build:
- name: Build
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+
+const GRADLE_YAML_STEPS = `
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
run: ./gradlew build sonarqube --info`;
export default function Gradle(props: GradleProps) {
- const { component, branchesEnabled } = props;
+ const { component, branchesEnabled, mainBranchName } = props;
return (
<>
</li>
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
- yamlTemplate={gradleYamlTemplate(!!branchesEnabled)}
+ yamlTemplate={generateGitHubActionsYaml(
+ mainBranchName,
+ !!branchesEnabled,
+ GITHUB_ACTIONS_RUNS_ON_LINUX,
+ GRADLE_YAML_STEPS
+ )}
/>
<FinishButton onClick={props.onDone} />
</>
import { Component } from '../../../../types/types';
import CreateYmlFile from '../../components/CreateYmlFile';
import FinishButton from '../../components/FinishButton';
+import { GITHUB_ACTIONS_RUNS_ON_LINUX } from '../constants';
+import { generateGitHubActionsYaml } from '../utils';
export interface JavaMavenProps {
branchesEnabled?: boolean;
+ mainBranchName: string;
component: Component;
onDone: () => void;
}
-const mavenYamlTemplte = (branchesEnabled: boolean, projectKey: string) => `name: Build
-on:
- push:
- branches:
- - master # or the name of your main branch
-${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''}
-jobs:
- build:
- name: Build
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+function mavenYamlSteps(projectKey: string) {
+ return `
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=${projectKey}`;
+}
export default function JavaMaven(props: JavaMavenProps) {
- const { component, branchesEnabled } = props;
+ const { component, branchesEnabled, mainBranchName } = props;
return (
<>
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
- yamlTemplate={mavenYamlTemplte(!!branchesEnabled, component.key)}
+ yamlTemplate={generateGitHubActionsYaml(
+ mainBranchName,
+ !!branchesEnabled,
+ GITHUB_ACTIONS_RUNS_ON_LINUX,
+ mavenYamlSteps(component.key)
+ )}
/>
<FinishButton onClick={props.onDone} />
</>
import CreateYmlFile from '../../components/CreateYmlFile';
import DefaultProjectKey from '../../components/DefaultProjectKey';
import FinishButton from '../../components/FinishButton';
+import { GITHUB_ACTIONS_RUNS_ON_LINUX } from '../constants';
+import { generateGitHubActionsYaml } from '../utils';
export interface OthersProps {
branchesEnabled?: boolean;
+ mainBranchName: string;
component: Component;
onDone: () => void;
}
-const yamlTemplate = (branchesEnabled: boolean) => {
- let output = `name: Build
-on:
- push:
- branches:
- - master # or the name of your main branch`;
-
- if (branchesEnabled) {
- output += `
- pull_request:
- types: [opened, synchronize, reopened]`;
- }
-
- output += `
-jobs:
- build:
- name: Build
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0
+function otherYamlSteps(branchesEnabled: boolean) {
+ let output = `
- uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
# SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}`;
return output;
-};
+}
export default function Others(props: OthersProps) {
- const { component, branchesEnabled } = props;
+ const { component, branchesEnabled, mainBranchName } = props;
return (
<>
<DefaultProjectKey component={component} />
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
- yamlTemplate={yamlTemplate(!!branchesEnabled)}
+ yamlTemplate={generateGitHubActionsYaml(
+ mainBranchName,
+ !!branchesEnabled,
+ GITHUB_ACTIONS_RUNS_ON_LINUX,
+ otherYamlSteps(!!branchesEnabled)
+ )}
/>
<FinishButton onClick={props.onDone} />
</>
function shallowRender(props: Partial<CFamilyProps> = {}) {
return shallow<CFamilyProps>(
- <CFamily branchesEnabled={true} component={mockComponent()} {...props} onDone={jest.fn()} />
+ <CFamily
+ branchesEnabled={true}
+ component={mockComponent()}
+ mainBranchName="main"
+ onDone={jest.fn()}
+ {...props}
+ />
);
}
function shallowRender(props: Partial<DotNetProps> = {}) {
return shallow<DotNetProps>(
- <DotNet branchesEnabled={true} component={mockComponent()} {...props} onDone={jest.fn()} />
+ <DotNet
+ branchesEnabled={true}
+ component={mockComponent()}
+ mainBranchName="main"
+ {...props}
+ onDone={jest.fn()}
+ />
);
}
function shallowRender(props: Partial<GradleProps> = {}) {
return shallow<GradleProps>(
- <Gradle branchesEnabled={true} component={mockComponent()} {...props} onDone={jest.fn()} />
+ <Gradle
+ branchesEnabled={true}
+ component={mockComponent()}
+ mainBranchName="main"
+ onDone={jest.fn()}
+ {...props}
+ />
);
}
function shallowRender(props: Partial<JavaMavenProps> = {}) {
return shallow<JavaMavenProps>(
- <JavaMaven branchesEnabled={true} component={mockComponent()} {...props} onDone={jest.fn()} />
+ <JavaMaven
+ branchesEnabled={true}
+ component={mockComponent()}
+ mainBranchName="main"
+ onDone={jest.fn()}
+ {...props}
+ />
);
}
function shallowRender(props: Partial<OthersProps> = {}) {
return shallow<OthersProps>(
- <Others branchesEnabled={true} component={mockComponent()} {...props} onDone={jest.fn()} />
+ <Others
+ branchesEnabled={true}
+ component={mockComponent()}
+ mainBranchName="main"
+ onDone={jest.fn()}
+ {...props}
+ />
);
}
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
jobs:
build:
+ name: Build
runs-on: <image ready for your build toolchain>
steps:
- - name: Checkout code
- uses: actions/checkout@v2
+ - uses: actions/checkout@v2
with:
- fetch-depth: 0
-
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Download and install the build wrapper, build the project
run: |
mkdir $HOME/.sonar
sonar-scanner --define sonar.cfamily.build-wrapper-output=bw-output
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
- SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}
-"
+ SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}"
/>
<CompilationInfo
className="abs-width-800"
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
+ name: Build
runs-on: <image ready for your build toolchain>
steps:
- - name: Checkout code
- uses: actions/checkout@v2
+ - uses: actions/checkout@v2
with:
- fetch-depth: 0
-
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Download and install the build wrapper
run: |
mkdir $HOME/.sonar
$HOME/.sonar/sonar-scanner-4.6.2.2472-macosx/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
- SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}
-"
+ SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}"
/>
<CompilationInfo
className="abs-width-800"
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
+ name: Build
runs-on: <image ready for your build toolchain>
steps:
- - name: Checkout code
- uses: actions/checkout@v2
+ - uses: actions/checkout@v2
with:
- fetch-depth: 0
-
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Download and install the build wrapper
shell: powershell
run: |
sonar-scanner.bat \\"-Dsonar.cfamily.build-wrapper-output=bw-output\\"
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
- SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}
-"
+ SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}"
/>
<CompilationInfo
className="abs-width-800"
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
pull_request:
types: [opened, synchronize, reopened]
+
jobs:
build:
name: Build
runs-on: windows-latest
steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.11
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Cache SonarQube packages
uses: actions/cache@v1
with:
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
+
jobs:
build:
name: Build
runs-on: windows-latest
steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.11
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Cache SonarQube packages
uses: actions/cache@v1
with:
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
pull_request:
types: [opened, synchronize, reopened]
+
jobs:
build:
name: Build
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
+
jobs:
build:
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
pull_request:
types: [opened, synchronize, reopened]
+
jobs:
build:
name: Build
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
+
jobs:
build:
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
pull_request:
types: [opened, synchronize, reopened]
+
jobs:
build:
name: Build
steps:
- uses: actions/checkout@v2
with:
- fetch-depth: 0
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
yamlTemplate="name: Build
+
on:
push:
branches:
- - master # or the name of your main branch
+ - main
+
+
jobs:
build:
name: Build
steps:
- uses: actions/checkout@v2
with:
- fetch-depth: 0
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.
+ */
+export const GITHUB_ACTIONS_RUNS_ON_LINUX = 'ubuntu-latest';
+export const GITHUB_ACTIONS_RUNS_ON_WINDOWS = 'windows-latest';
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.
+ */
+export function generateGitHubActionsYaml(
+ mainBranchName: string,
+ branchesEnabled: boolean,
+ runsOn: string,
+ steps: string
+) {
+ return `name: Build
+
+on:
+ push:
+ branches:
+ - ${mainBranchName}
+${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''}
+
+jobs:
+ build:
+ name: Build
+ runs-on: ${runsOn}
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis${steps}`;
+}
baseUrl: string;
component: Component;
currentUser: LoggedInUser;
+ mainBranchName: string;
willRefreshAutomatically?: boolean;
}
export default function GitLabCITutorial(props: GitLabCITutorialProps) {
- const { baseUrl, component, currentUser, willRefreshAutomatically } = props;
+ const { baseUrl, component, currentUser, willRefreshAutomatically, mainBranchName } = props;
const [step, setStep] = React.useState(Steps.PROJECT_KEY);
const [buildTool, setBuildTool] = React.useState<BuildTools>();
<YmlFileStep
buildTool={buildTool}
finished={step > Steps.YML}
+ mainBranchName={mainBranchName}
onDone={() => setStep(Steps.ALL_SET)}
onOpen={() => setStep(Steps.YML)}
open={step === Steps.YML}
import { FormattedMessage } from 'react-intl';
import { Button } from '../../../components/controls/buttons';
import { ClipboardIconButton } from '../../../components/controls/clipboard';
+import { GRADLE_SCANNER_VERSION } from '../../../helpers/constants';
import { translate } from '../../../helpers/l10n';
import { Component } from '../../../types/types';
import CodeSnippet from '../../common/CodeSnippet';
</properties>`;
const gradleSnippet = (key: string) => `plugins {
- id "org.sonarqube" version "3.4.0.2513"
+ id "org.sonarqube" version "${GRADLE_SCANNER_VERSION}"
}
sonarqube {
onOpen: () => void;
open: boolean;
projectKey: string;
+ mainBranchName: string;
}
export function YmlFileStep(props: YmlFileStepProps) {
- const { buildTool, open, finished, projectKey } = props;
+ const { buildTool, open, finished, projectKey, mainBranchName } = props;
const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
const renderForm = () => (
<PipeCommand
buildTool={buildTool}
branchesEnabled={branchSupportEnabled}
+ mainBranchName={mainBranchName}
projectKey={projectKey}
/>
</div>
baseUrl="http://localhost:9000"
component={mockComponent()}
currentUser={mockLoggedInUser()}
+ mainBranchName="main"
willRefreshAutomatically={true}
{...props}
/>
open={true}
projectKey="test"
finished={true}
+ mainBranchName="main"
onDone={jest.fn()}
onOpen={jest.fn()}
{...props}
/>
<withAvailableFeaturesContext(YmlFileStep)
finished={false}
+ mainBranchName="main"
onDone={[Function]}
onOpen={[Function]}
open={false}
<PipeCommand
branchesEnabled={true}
buildTool="cfamily"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={false}
buildTool="cfamily"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={true}
buildTool="dotnet"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={false}
buildTool="dotnet"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={true}
buildTool="gradle"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={false}
buildTool="gradle"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={true}
buildTool="maven"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={false}
buildTool="maven"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={true}
buildTool="other"
+ mainBranchName="main"
projectKey="test"
/>
</div>
<PipeCommand
branchesEnabled={false}
buildTool="other"
+ mainBranchName="main"
projectKey="test"
/>
</div>
export interface PipeCommandProps {
branchesEnabled?: boolean;
buildTool: BuildTools;
+ mainBranchName: string;
projectKey: string;
}
}
};
-export default function PipeCommand({ projectKey, branchesEnabled, buildTool }: PipeCommandProps) {
+export default function PipeCommand(props: PipeCommandProps) {
+ const { projectKey, branchesEnabled, buildTool, mainBranchName } = props;
let command: string;
if (buildTool === BuildTools.CFamily) {
command = `image: <image ready for your build toolchain>
} else {
const onlyBlock = branchesEnabled
? `- merge_requests
- - master # or the name of your main branch
+ - ${mainBranchName}
- develop`
- : '- master # or the name of your main branch';
+ : `- ${mainBranchName}`;
const { image, script } = BUILD_TOOL_SPECIFIC[buildTool];
[BuildTools.Other]
])('should render correctly for %s', buildTool => {
expect(
- shallow(<PipeCommand buildTool={buildTool} branchesEnabled={true} projectKey="test" />)
+ shallow(
+ <PipeCommand
+ buildTool={buildTool}
+ branchesEnabled={true}
+ mainBranchName="main"
+ projectKey="test"
+ />
+ )
).toMatchSnapshot('branches enabled');
expect(
- shallow(<PipeCommand buildTool={buildTool} branchesEnabled={true} projectKey="test" />)
+ shallow(
+ <PipeCommand
+ buildTool={buildTool}
+ branchesEnabled={true}
+ mainBranchName="main"
+ projectKey="test"
+ />
+ )
).toMatchSnapshot('branches not enabled');
});
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
allow_failure: true
only:
- merge_requests
- - master # or the name of your main branch
+ - main
- develop
"
/>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { getHostUrl } from '../../../../helpers/urls';
import { Component } from '../../../../types/types';
import { BuildTools, ManualTutorialConfig } from '../../types';
import ClangGCCCustom from './ClangGCCCommand';
return null;
}
- const host = getHostUrl();
-
switch (languageConfig.buildTool) {
case BuildTools.Maven:
- return <JavaMaven host={host} component={component} token={token} />;
+ return <JavaMaven baseUrl={baseUrl} component={component} token={token} />;
case BuildTools.Gradle:
- return <JavaGradle host={host} component={component} token={token} />;
+ return <JavaGradle baseUrl={baseUrl} component={component} token={token} />;
case BuildTools.DotNet:
- return <DotNet host={host} component={component} token={token} />;
+ return <DotNet baseUrl={baseUrl} component={component} token={token} />;
case BuildTools.CFamily:
return languageConfig.os !== undefined ? (
<ClangGCCCustom
os={languageConfig.os}
baseUrl={baseUrl}
- host={host}
component={component}
isLocal={isLocal}
token={token}
case BuildTools.Other:
return languageConfig.os !== undefined ? (
<Other
- host={host}
+ baseUrl={baseUrl}
os={languageConfig.os}
component={component}
isLocal={isLocal}
component: Component;
baseUrl: string;
isLocal: boolean;
- host: string;
os: OSs;
token: string;
}
export default function ClangGCCCustom(props: ClangGCCCustomProps) {
- const { os, baseUrl, host, component, isLocal, token } = props;
+ const { os, baseUrl, component, isLocal, token } = props;
return (
<div>
<ExecBuildWrapper os={os} />
<CompilationInfo />
<ExecScanner
- host={host}
+ baseUrl={baseUrl}
isLocal={isLocal}
component={component}
os={os}
export interface DotNetProps {
component: Component;
- host: string;
+ baseUrl: string;
token: string;
}
import DotNetExecute from './DotNetExecute';
export default function DotNetCore(props: DotNetProps) {
- const { host, component, token } = props;
+ const { baseUrl, component, token } = props;
const commands = [
- `dotnet sonarscanner begin /k:"${component.key}" /d:sonar.host.url="${host}" /d:sonar.login="${token}"`,
+ `dotnet sonarscanner begin /k:"${component.key}" /d:sonar.host.url="${baseUrl}" /d:sonar.login="${token}"`,
'dotnet build',
`dotnet sonarscanner end /d:sonar.login="${token}"`
];
import DotNetExecute from './DotNetExecute';
export default function DotNetFramework(props: DotNetProps) {
- const { host, component, token } = props;
+ const { baseUrl, component, token } = props;
const commands = [
- `SonarScanner.MSBuild.exe begin /k:"${component.key}" /d:sonar.host.url="${host}" /d:sonar.login="${token}"`,
+ `SonarScanner.MSBuild.exe begin /k:"${component.key}" /d:sonar.host.url="${baseUrl}" /d:sonar.login="${token}"`,
'MsBuild.exe /t:Rebuild',
`SonarScanner.MSBuild.exe end /d:sonar.login="${token}"`
];
export interface ExecScannerProps {
component: Component;
- host: string;
+ baseUrl: string;
isLocal: boolean;
os: OSs;
token: string;
}
export default function ExecScanner(props: ExecScannerProps) {
- const { host, os, isLocal, component, token, cfamily } = props;
+ const { baseUrl, os, isLocal, component, token, cfamily } = props;
const q = quote(os);
const command = [
'-D' + q(`sonar.projectKey=${component.key}`),
'-D' + q('sonar.sources=.'),
cfamily ? '-D' + q('sonar.cfamily.build-wrapper-output=bw-output') : undefined,
- '-D' + q(`sonar.host.url=${host}`),
+ '-D' + q(`sonar.host.url=${baseUrl}`),
isLocal ? '-D' + q(`sonar.login=${token}`) : undefined
];
*/
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
+import { GRADLE_SCANNER_VERSION } from '../../../../helpers/constants';
import { translate } from '../../../../helpers/l10n';
import { Component } from '../../../../types/types';
import CodeSnippet from '../../../common/CodeSnippet';
export interface JavaGradleProps {
component: Component;
- host: string;
+ baseUrl: string;
token: string;
}
export default function JavaGradle(props: JavaGradleProps) {
- const { host, component, token } = props;
- const config = 'plugins {\n id "org.sonarqube" version "3.4.0.2513"\n}';
+ const { baseUrl, component, token } = props;
+ const config = `plugins {
+ id "org.sonarqube" version "${GRADLE_SCANNER_VERSION}"
+}`;
const command = [
'./gradlew sonarqube',
`-Dsonar.projectKey=${component.key}`,
- `-Dsonar.host.url=${host}`,
+ `-Dsonar.host.url=${baseUrl}`,
`-Dsonar.login=${token}`
];
export interface JavaMavenProps {
component: Component;
- host: string;
+ baseUrl: string;
token: string;
}
export default function JavaMaven(props: JavaMavenProps) {
- const { host, component, token } = props;
+ const { baseUrl, component, token } = props;
const command = [
'mvn clean verify sonar:sonar',
`-Dsonar.projectKey=${component.key}`,
- `-Dsonar.host.url=${host}`,
+ `-Dsonar.host.url=${baseUrl}`,
`-Dsonar.login=${token}`
];
export interface OtherProps {
component: Component;
isLocal: boolean;
- host: string;
+ baseUrl: string;
os: OSs;
token: string;
}
export default function Other(props: OtherProps) {
- const { host, os, component, isLocal, token } = props;
+ const { baseUrl, os, component, isLocal, token } = props;
return (
<div>
<DownloadScanner isLocal={isLocal} os={os} token={token} />
- <ExecScanner host={host} isLocal={isLocal} os={os} component={component} token={token} />
+ <ExecScanner
+ baseUrl={baseUrl}
+ isLocal={isLocal}
+ os={os}
+ component={component}
+ token={token}
+ />
</div>
);
}
os={OSs.Linux}
baseUrl="http://example.com"
isLocal={true}
- host="host"
component={mockComponent({ key: 'projectKey' })}
token="token"
/>
it('should render correctly', () => {
expect(
- shallow(<DotNet host="host" component={mockComponent({ key: 'projectKey' })} token="token" />)
+ shallow(
+ <DotNet baseUrl="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ )
).toMatchSnapshot();
});
it('should render correctly', () => {
expect(
shallow(
- <DotNetFramework host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ <DotNetFramework
+ baseUrl="host"
+ component={mockComponent({ key: 'projectKey' })}
+ token="token"
+ />
)
).toMatchSnapshot();
});
it('should render correctly', () => {
expect(
shallow(
- <DotNetCore host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ <DotNetCore baseUrl="host" component={mockComponent({ key: 'projectKey' })} token="token" />
)
).toMatchSnapshot();
});
function shallowRender(props: Partial<ExecScannerProps> = {}) {
return shallow<ExecScannerProps>(
<ExecScanner
- host="host"
+ baseUrl="host"
isLocal={true}
os={OSs.Linux}
component={mockComponent({ key: 'projectKey' })}
it('renders correctly', () => {
expect(
shallow(
- <JavaGradle host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ <JavaGradle baseUrl="host" component={mockComponent({ key: 'projectKey' })} token="token" />
)
).toMatchSnapshot();
});
it('renders correctly', () => {
expect(
shallow(
- <JavaMaven host="host" component={mockComponent({ key: 'projectKey' })} token="token" />
+ <JavaMaven baseUrl="host" component={mockComponent({ key: 'projectKey' })} token="token" />
)
).toMatchSnapshot();
});
function shallowRender(props: Partial<OtherProps> = {}) {
return shallow<OtherProps>(
<Other
- host="host"
+ baseUrl="host"
isLocal={true}
os={OSs.Linux}
component={mockComponent({ key: 'projectKey' })}
exports[`renders correctly: .NET 1`] = `
<DotNet
+ baseUrl="http://example.com"
component={
Object {
"breadcrumbs": Array [],
"tags": Array [],
}
}
- host="HOST"
token="myToken"
/>
`;
"tags": Array [],
}
}
- host="HOST"
isLocal={true}
os="linux"
token="myToken"
exports[`renders correctly: gradle 1`] = `
<JavaGradle
+ baseUrl="http://example.com"
component={
Object {
"breadcrumbs": Array [],
"tags": Array [],
}
}
- host="HOST"
token="myToken"
/>
`;
exports[`renders correctly: maven 1`] = `
<JavaMaven
+ baseUrl="http://example.com"
component={
Object {
"breadcrumbs": Array [],
"tags": Array [],
}
}
- host="HOST"
token="myToken"
/>
`;
exports[`renders correctly: other 1`] = `
<Other
+ baseUrl="http://example.com"
component={
Object {
"breadcrumbs": Array [],
"tags": Array [],
}
}
- host="HOST"
isLocal={true}
os="win"
token="myToken"
/>
<CompilationInfo />
<ExecScanner
+ baseUrl="http://example.com"
cfamily={true}
component={
Object {
"tags": Array [],
}
}
- host="host"
isLocal={true}
os="linux"
token="token"
titleLabelKey="onboarding.build.dotnet.variant"
/>
<DotNetCore
+ baseUrl="host"
component={
Object {
"breadcrumbs": Array [],
"tags": Array [],
}
}
- host="host"
token="token"
/>
</Fragment>
token="token"
/>
<ExecScanner
+ baseUrl="host"
component={
Object {
"breadcrumbs": Array [],
"tags": Array [],
}
}
- host="host"
isLocal={true}
os="linux"
token="token"
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { GRADLE_SCANNER_VERSION } from '../../helpers/constants';
import { convertGithubApiUrlToLink, stripTrailingSlash } from '../../helpers/urls';
import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../types/alm-settings';
import { UserToken } from '../../types/token';
export function buildGradleSnippet(key: string) {
return `plugins {
- id "org.sonarqube" version "3.4.0.2513"
+ id "org.sonarqube" version "${GRADLE_SCANNER_VERSION}"
}
sonarqube {
export const IMPORT_COMPATIBLE_ALM_COUNT = IMPORT_COMPATIBLE_ALMS.filter(
a => a !== AlmKeys.BitbucketCloud
).length;
+
+export const GRADLE_SCANNER_VERSION = '3.4.0.2513';