apache / incubator-devlake

Apache DevLake is an open-source dev data platform to ingest, analyze, and visualize the fragmented data from DevOps tools, extracting insights for engineering excellence, developer experience, and community growth.
https://devlake.apache.org/
Apache License 2.0
2.56k stars 511 forks source link

[Feature][SonarQube Connection] Add support for SonarCloud #4838

Open alexvaccaro opened 1 year ago

alexvaccaro commented 1 year ago

Search before asking

Use case

Add support SonarCloud along with SonarCube

Hopefully this is not a big ask, SonarCloud is the cloud hosted version of SonarCube and most of the apis are the same.

I have tried setting up a connection but unfortunately the list of projects comes back empty, for what I can see that's becaus efor SonarCloud the organisation parameter is required, yet the SonarCube connection wizard does not capture this parameter.

Description

No response

Related issues

No response

Are you willing to submit a PR?

Code of Conduct

klesh commented 1 year ago

Thanks for your suggestion, @Startrekzky @yumengwang03 @hezyin please take a look at this.

Startrekzky commented 1 year ago

Collecting votes

alexvaccaro commented 1 year ago

I see the issue has been tagged with 'add-a-plugin', however this could be potentially handled with the existing SonarCube plugin and have an optional 'Organisation' parameter to inject in the URIs if supplied

Startrekzky commented 1 year ago

I see the issue has been tagged with 'add-a-plugin', however this could be potentially handled with the existing SonarCube plugin and have an optional 'Organisation' parameter to inject in the URIs if supplied

I agree and have removed the label. This issue is the improvements of #2305

BrookeKatalon commented 1 year ago

We're definitely interested as well - would be easier if the existing plugin could be adapted, or as second one that's sonarcloud-specific.

Startrekzky commented 1 year ago

@klesh It seems we've got 4 (3+1) votes now. I'll plan it in the next few versions.

klesh commented 1 year ago

LGTM

Ragavendira1 commented 1 year ago

Dear team, we are looking out sonarcloud integration. Therefore kindly provide us update when we will able to see sonarcloud data into devlake

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity for 30 days. It will be closed in next 7 days if no further activity occurs.

github-actions[bot] commented 1 year ago

This issue has been closed because it has not received response for too long time. You could reopen it if you encountered similar problems in the future.

lhart-intelycare commented 1 year ago

Another vote from me!

sztukamichal commented 1 year ago

Devlake looks great. I also vote on this functionality.

rhanton commented 11 months ago

I'm looking at how much devlake could help our org, but SonarCloud integration would make it quite amazing for us! Upvote from me!

github-actions[bot] commented 9 months ago

This issue has been automatically marked as stale because it has been inactive for 60 days. It will be closed in next 7 days if no further activity occurs.

rhanton commented 9 months ago

Ping! Is this still possible? Anyone with time to look at it? We might have time for someone on the team to investigate in 2024.

Startrekzky commented 9 months ago

@rhanton Excellent. It's still available. We didn't do it because we didn't have a SonarCloud instance. It'll be great if your team can take it. Do you mind if I assign it to you for now?

jillesmc commented 9 months ago

Devlake looks great. I also vote on this functionality.

madibaT commented 9 months ago

Upvote from me

wanisfahmyDE commented 8 months ago

+1

leandrofrs commented 8 months ago

+1

jhonjimenezmatrix commented 8 months ago

+1 we need it!

github-actions[bot] commented 6 months ago

This issue has been automatically marked as stale because it has been inactive for 60 days. It will be closed in next 7 days if no further activity occurs.

gdolfen commented 6 months ago

+1

Startrekzky commented 5 months ago

Any volunteers? We don't have the bandwidth to do this, and we don't have an account for SonarCloud either.

UncleLeoTheDad commented 5 months ago

I started to explore this as I am a SonarCloud user. If you have any shortcuts to get started, I'd appreciate it.

I see this is the current plugin: https://github.com/apache/incubator-devlake/tree/main/backend/plugins/sonarqube

And I followed the "Develop a plugin" link on the main page to start: https://github.com/apache/incubator-devlake

But I ended up at a dead link. :( https://github.com/apache/incubator-devlake/blob/main/backend/DevelopmentSetup

tonyjw commented 5 months ago

Hi @UncleLeoTheDad I believe the right link is this: https://github.com/apache/incubator-devlake/blob/main/backend/DevelopmentManual.md

rhanton commented 5 months ago

@Startrekzky I'll see if someone on our team can take a look. We "finally" got a devlake instance running for our teams, so should be easy-er to test whatever we put together.

tc-jason-gregory commented 5 months ago

+1

HumSeto commented 5 months ago

+1

Startrekzky commented 5 months ago

Hi @UncleLeoTheDad . I am sorry. I just saw your comment. Could you join the Slack community so that we can work more closely if you're still looking at it? Thank you. https://join.slack.com/t/devlake-io/shared_invite/zt-18uayb6ut-cHOjiYcBwERQ8VVPZ9cQQw

UncleLeoTheDad commented 5 months ago

Hi @Startrekzky : tried that link, but it looks like it expired: image

wanisfahmyDE commented 5 months ago

here you go https://join.slack.com/t/devlake-io/shared_invite/zt-20envwfbk-JUTZ4z9jSeRnrvNhBFLg9w

lezgin-bakircioglu-qred commented 3 months ago

Awesome to see some movement on this one, looking forward to the sonarcloud support :)

lhart-intelycare commented 3 months ago

I've started coding away on my end. Wanted to get some advice on which way to go...

The big difference ID'd so far between sonarcloud and sonarqube is that:

  1. Sonarcloud always has the same REST endpoint: https://sonarcloud.io/api/
  2. Sonarcloud APIs often needs an "organization" passed in when looking for things like projects: https://sonarcloud.io/api/projects/search?deprecated=false&organization=intelycare&ps=100&p=1

Given that, it seemed like I should probably start with enhancing:

  1. config-ui's sonarqube pluginconfig to have a multiconfig concept, similar to the jira plugin and then add an optional concept of "organization" when multiconfig is selected: https://github.com/apache/incubator-devlake/blob/0e7bf408afcb707a419c843a4a9839b054b1c7d4/config-ui/src/plugins/register/sonarqube/config.tsx:
    export const SonarQubeConfig: IPluginConfig = {
    plugin: 'sonarqube',
    name: 'SonarQube',
    icon: ({ color }) => <Icon fill={color} />,
    sort: 11,
    connection: {
    docLink: DOC_URL.PLUGIN.SONARQUBE.BASIS,
    fields: [
      'name',
      {
        key: 'endpoint',
        subLabel: 'Provide the SonarQube instance API endpoint. E.g. http://<host>:<port>/api/',
        multipleVersions: {
          cloud: 'http://sonarcloud.io/',
          server: ' '
        },
        organizationRequired: true,
      },
      'organization',
      'token',
      'proxy',
      {
        key: 'rateLimitPerHour',
        subLabel:
          'By default, DevLake uses 10,000 requests/hour for data collection for SonarQube. But you can adjust the collection speed by setting up your desirable rate limit.',
        learnMore: DOC_URL.PLUGIN.SONARQUBE.RATE_LIMIT,
        externalInfo: 'SonarQube does not specify a maximum value of rate limit.',
        defaultValue: 10000,
      },
    ],
    },
    dataScope: {
    title: 'Repositories',
    },
    };
  2. The endpoint connection config component, allowing a user to select cloud vs server and then if cloud, specify an organization : https://github.com/apache/incubator-devlake/blob/f27c31f3954bb4d5df8c6a4e829acfdedf36174a/config-ui/src/plugins/components/connection-form/fields/endpoint.tsx
import { useState, useEffect } from 'react';
import type { RadioChangeEvent } from 'antd';
import { Radio, Input } from 'antd';

import { Block } from '@/components';

type VersionType = 'cloud' | 'server';

interface Props {
  subLabel?: string;
  disabled?: boolean;
  name: string;
  multipleVersions?: Record<VersionType, string>;
  organizationRequired?: boolean;
  initialValue: string;
  value: string;
  error: string;
  setValue: (value: string) => void;
  setError: (error: string) => void;
}

export const ConnectionEndpoint = ({
  subLabel,
  disabled = false,
  name,
  multipleVersions,
  organizationRequired,
  initialValue,
  value,
  setValue,
  setError,
}: Props) => {
  const [version, setVersion] = useState<VersionType>('cloud');

  useEffect(() => {
    setValue(initialValue);
    setVersion(initialValue === multipleVersions?.cloud ? 'cloud' : 'server');
  }, [initialValue]);

  useEffect(() => {
    setError(value ? '' : 'endpoint is required');
  }, [value]);

  const handleChange = (e: RadioChangeEvent) => {
    const version = e.target.value;
    if (version === 'cloud') {
      setValue(multipleVersions?.cloud ?? '');
    }

    if (version === 'server') {
      setValue('');
    }

    setVersion(version);
  };

  const handleChangeValue = (e: React.ChangeEvent<HTMLInputElement>) => {
    setValue(e.target.value);
  };

  if (multipleVersions) {
    return (
      <>
        <Block title={name} required>
          <Radio.Group value={version} onChange={handleChange}>
            <Radio value="cloud">{name} Cloud</Radio>
            <Radio value="server" disabled={!multipleVersions.server}>
              {name} Server {multipleVersions.server ? multipleVersions.server : '(to be supported)'}
            </Radio>
          </Radio.Group>
        </Block>
        {version === 'cloud' && (
          <Block>
            <p>
              If you are using {name} Cloud, you do not need to enter the endpoint URL, which is{' '}
              {multipleVersions.cloud}.
            </p>
          </Block>
        )}
        {organizationRequired && (
          <Block>
            <p>
              Place some input here for "organization"
            </p>
          </Block>
        )}
        {version === 'server' && (
          <Block
            title="Endpoint URL"
            description={subLabel ?? `If you are using ${name} Server, please enter the endpoint URL.`}
            required
          >
            <Input style={{ width: 386 }} placeholder="Your Endpoint URL" value={value} onChange={handleChangeValue} />
          </Block>
        )}
      </>
    );
  }

  return (
    <Block title="Endpoint URL" description={subLabel ?? `Provide the ${name} instance API endpoint.`} required>
      <Input
        style={{ width: 386 }}
        disabled={disabled}
        placeholder="Your Endpoint URL"
        value={value}
        onChange={handleChangeValue}
      />
    </Block>
  );
};

DevLake devs (@Startrekzky?): does this sound directionally correct from a front-end perspective? Alternatively, I could create an entirely new field concept here, but it feels like org is tightly coupled to endpoint vs being its own entity: https://github.com/apache/incubator-devlake/blob/ac540080b73f313eb58b6a9659a392e1022beced/config-ui/src/plugins/components/connection-form/fields

Thanks!

jcorremo commented 2 months ago

Upvote from me

mintsweet commented 2 months ago

Hi @lhart-intelycare,

In response to your inquiry about how config-ui handles the implementation of two different SonarQube modes:

Modifying existing fields, such as "endpoint," is not advisable as it may impact other plugins. If a new field is introduced in SonarQube Cloud, the best approach is to create a new component specifically for this field, similar to the authentication component used in Jira.

Within the new component, you can retrieve the value of the "endpoint" to ascertain whether the "organization" field is required.

github-actions[bot] commented 3 weeks ago

This issue has been automatically marked as stale because it has been inactive for 60 days. It will be closed in next 7 days if no further activity occurs.

lezgin-bakircioglu-qred commented 3 weeks ago

adding a comment to keep this one alive as there is some progress :)