Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix modify story bug #11

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions config-ui/src/components/Sidebar/MenuConfiguration.jsx
Expand Up @@ -59,6 +59,14 @@ const MenuConfiguration = (activeRoute) => {
active: activeRoute.url.endsWith('/integrations/jenkins') || activeRoute.url.endsWith('/jenkins'),
icon: 'layers',
classNames: [],
},
{
id: 4,
label: ProviderLabels.TAPD,
route: '/integrations/tapd',
active: activeRoute.url.endsWith('/integrations/tapd') || activeRoute.url.endsWith('/tapd'),
icon: 'layers',
classNames: [],
}
]
},
Expand Down
6 changes: 6 additions & 0 deletions config-ui/src/components/blueprints/ConnectionDialog.jsx
Expand Up @@ -75,6 +75,12 @@ const DATA_SOURCES_LIST = [
title: ProviderLabels[Providers.JENKINS.toUpperCase()],
value: Providers.JENKINS,
},
{
id: 5,
name: Providers.TAPD,
title: ProviderLabels[Providers.TAPD.toUpperCase()],
value: Providers.TAPD,
},
]

const ConnectionDialog = (props) => {
Expand Down
1 change: 1 addition & 0 deletions config-ui/src/components/pipelines/StageTaskName.jsx
Expand Up @@ -92,6 +92,7 @@ const StageTaskName = (props) => {
{task.plugin === Providers.GITEXTRACTOR && (<>{ProviderLabels.GITEXTRACTOR}</>)}
{task.plugin === Providers.FEISHU && (<>{ProviderLabels.FEISHU}</>)}
{task.plugin === Providers.JENKINS && (<>{ProviderLabels.JENKINS}</>)}
{task.plugin === Providers.TAPD && (<>{ProviderLabels.TAPD}</>)}
{task.plugin === Providers.JIRA && (<>Board ID {task.options.boardId}</>)}
{task.plugin === Providers.GITLAB && (<>Project ID {task.options.projectId}</>)}
{task.plugin === Providers.GITHUB && task.plugin !== Providers.JENKINS && (<>@{task.options.owner}/{task.options.repo}</>)}
Expand Down
21 changes: 20 additions & 1 deletion config-ui/src/data/Providers.js
Expand Up @@ -21,6 +21,7 @@ import { ReactComponent as GitlabProviderIcon } from '@/images/integrations/gitl
import { ReactComponent as JenkinsProviderIcon } from '@/images/integrations/jenkins.svg'
import { ReactComponent as JiraProviderIcon } from '@/images/integrations/jira.svg'
import { ReactComponent as GitHubProviderIcon } from '@/images/integrations/github.svg'
import { ReactComponent as TapdProviderIcon } from '@/images/integrations/tapd.svg'
// import GitExtractorIcon from '@/images/git.png'
// import RefDiffIcon from '@/images/git-diff.png'
import FeishuIcon from '@/images/feishu.png'
Expand All @@ -39,6 +40,7 @@ const Providers = {
AE: 'ae',
DBT: 'dbt',
STARROCKS: 'starrocks',
TAPD: 'tapd',
}

const ProviderTypes = {
Expand All @@ -59,6 +61,7 @@ const ProviderLabels = {
AE: 'Analysis Engine (AE)',
DBT: 'Data Build Tool (DBT)',
STARROCKS: 'StarRocks',
TAPD: 'Tapd',
}

const ProviderConnectionLimits = {
Expand Down Expand Up @@ -96,11 +99,18 @@ const ProviderFormLabels = {
username: 'Username',
password: 'Password'
},
jira: {
tapd: {
name: 'Connection Name',
endpoint: 'Endpoint URL',
proxy: 'Proxy URL',
token: 'Basic Auth Token',
username: 'Username',
password: 'Password',
},
jira: {
name: 'Connection Name',
endpoint: 'Endpoint URL',
token: 'Basic Auth Token',
username: 'Username / E-mail',
// password; 'Password',
password: (
Expand Down Expand Up @@ -181,6 +191,14 @@ const ProviderFormPlaceholders = {
username: 'eg. admin',
password: 'eg. ************'
},
tapd: {
name: 'eg. Tapd',
endpoint: 'URL eg. https://api.tapd.cn/',
proxy: 'eg. http://proxy.localhost:8080',
token: 'eg. 6b057ffe68464c93a057',
username: 'eg. admin',
password: 'eg. ************'
},
jira: {
name: 'eg. JIRA',
endpoint: 'eg. https://your-domain.atlassian.net/rest/',
Expand All @@ -202,6 +220,7 @@ const ProviderFormPlaceholders = {
const ProviderIcons = {
[Providers.GITLAB]: (w, h) => <GitlabProviderIcon width={w || 24} height={h || 24} />,
[Providers.JENKINS]: (w, h) => <JenkinsProviderIcon width={w || 24} height={h || 24} />,
[Providers.TAPD]: (w, h) => <TapdProviderIcon width={w || 24} height={h || 24} />,
[Providers.JIRA]: (w, h) => <JiraProviderIcon width={w || 24} height={h || 24} />,
[Providers.GITHUB]: (w, h) => <GitHubProviderIcon width={w || 24} height={h || 24} />,
[Providers.REFDIFF]: (w, h) => <Icon icon='box' size={w || 24} />,
Expand Down
2 changes: 1 addition & 1 deletion config-ui/src/data/availablePlugins.js
Expand Up @@ -15,6 +15,6 @@
* limitations under the License.
*
*/
const AVAILABLE_PLUGINS = ['gitlab', 'jira', 'jenkins', 'github']
const AVAILABLE_PLUGINS = ['gitlab', 'jira', 'jenkins', 'github', 'tapd']

module.exports = AVAILABLE_PLUGINS
19 changes: 19 additions & 0 deletions config-ui/src/data/integrations.jsx
Expand Up @@ -28,6 +28,7 @@ import { ReactComponent as GitlabProvider } from '@/images/integrations/gitlab.s
import { ReactComponent as JenkinsProvider } from '@/images/integrations/jenkins.svg'
import { ReactComponent as JiraProvider } from '@/images/integrations/jira.svg'
import { ReactComponent as GitHubProvider } from '@/images/integrations/github.svg'
import { ReactComponent as TapdProvider } from '@/images/integrations/tapd.svg'
// import GitExtractorProvider from '@/images/git.png'
// import RefDiffProvider from '@/images/git-diff.png'
// import { ReactComponent as NullProvider } from '@/images/integrations/null.svg'
Expand Down Expand Up @@ -69,6 +70,24 @@ const integrationsData = [
/>
)
},
{
id: Providers.TAPD,
type: ProviderTypes.INTEGRATION,
enabled: true,
multiConnection: true,
name: ProviderLabels.TAPD,
icon: <TapdProvider className='providerIconSvg' width='30' height='30' style={{ float: 'left', marginTop: '5px' }} />,
iconDashboard: <TapdProvider className='providerIconSvg' width='40' height='40' />,
settings: ({ activeProvider, activeConnection, isSaving, isSavingConnection, setSettings }) => (
<JenkinsSettings
provider={activeProvider}
connection={activeConnection}
isSaving={isSaving}
isSavingConnection={isSavingConnection}
onSettingsChange={setSettings}
/>
)
},
{
id: Providers.JIRA,
type: ProviderTypes.INTEGRATION,
Expand Down
10 changes: 10 additions & 0 deletions config-ui/src/hooks/useConnectionManager.jsx
Expand Up @@ -149,6 +149,16 @@ function useConnectionManager (
...connectionPayload,
}
break
case Providers.TAPD:
connectionPayload = {
name: name,
endpoint: endpointUrl,
username: username,
password: password,
proxy: proxy,
...connectionPayload,
}
break
case Providers.GITHUB:
connectionPayload = {
name: name,
Expand Down
3 changes: 2 additions & 1 deletion config-ui/src/hooks/usePipelineManager.jsx
Expand Up @@ -53,7 +53,8 @@ function usePipelineManager (myPipelineName = `COLLECTION ${Date.now()}`, initia
Providers.GITEXTRACTOR,
Providers.FEISHU,
Providers.AE,
Providers.DBT
Providers.DBT,
Providers.TAPD
])

const PIPELINES_ENDPOINT = useMemo(() => `${DEVLAKE_ENDPOINT}/pipelines`, [DEVLAKE_ENDPOINT])
Expand Down
3 changes: 2 additions & 1 deletion config-ui/src/hooks/usePipelineValidation.jsx
Expand Up @@ -56,7 +56,8 @@ function usePipelineValidation ({
Providers.FEISHU,
Providers.AE,
Providers.DBT,
Providers.STARROCKS
Providers.STARROCKS,
Providers.TAPD
])

const clear = () => {
Expand Down
6 changes: 6 additions & 0 deletions config-ui/src/images/integrations/tapd.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions config-ui/src/pages/blueprints/create-blueprint.jsx
Expand Up @@ -494,6 +494,7 @@ const CreateBlueprint = (props) => {
switch (configuredConnection.provider) {
case Providers.GITLAB:
case Providers.JIRA:
case Providers.TAPD:
case Providers.GITHUB:
items = dataEntitiesList.filter((d) => d.name !== 'ci-cd')
break
Expand Down Expand Up @@ -550,6 +551,11 @@ const CreateBlueprint = (props) => {
...newScope,
}
break
case Providers.TAPD:
newScope = {
...newScope,
}
break
case Providers.GITHUB:
newScope = projects[connection.id]?.map((p) => ({
...newScope,
Expand Down Expand Up @@ -905,6 +911,9 @@ const CreateBlueprint = (props) => {
case Providers.JENKINS:
// No Transform Settings...
break
case Providers.TAPD:
// No Transform Settings...
break
case Providers.GITLAB:
// No Transform Settings...
break
Expand Down
3 changes: 2 additions & 1 deletion config-ui/src/pages/configure/connections/AddConnection.jsx
Expand Up @@ -112,6 +112,7 @@ export default function AddConnection () {
case Providers.GITHUB:
case Providers.GITLAB:
case Providers.JIRA:
case Providers.TAPD:
default:
setName('')
break
Expand Down Expand Up @@ -184,7 +185,7 @@ export default function AddConnection () {
allTestResponses={allTestResponses}
errors={errors}
showError={showError}
authType={[Providers.JENKINS, Providers.JIRA].includes(activeProvider.id) ? 'plain' : 'token'}
authType={[Providers.JENKINS, Providers.JIRA, Providers.TAPD].includes(activeProvider.id) ? 'plain' : 'token'}
sourceLimits={ProviderConnectionLimits}
labels={ProviderFormLabels[activeProvider.id]}
placeholders={ProviderFormPlaceholders[activeProvider.id]}
Expand Down
Expand Up @@ -216,7 +216,7 @@ export default function ConfigureConnection () {
</div>
{activeConnection && (
<>
{[Providers.GITLAB, Providers.JIRA].includes(activeProvider.id) &&
{[Providers.GITLAB, Providers.JIRA, Providers.TAPD].includes(activeProvider.id) &&
(<h2 style={{ margin: 0 }}>#{activeConnection.ID} {activeConnection.name}</h2>)}
<p className='page-description'>Manage settings and options for this connection.</p>
</>
Expand Down Expand Up @@ -255,7 +255,7 @@ export default function ConfigureConnection () {
username={username}
password={password}
// JIRA and GITLAB are multi-connection plugins, for now we intentially won't include additional settings during save...
onSave={() => saveConnection(![Providers.GITLAB, Providers.JIRA].includes(activeProvider.id) ? settings : {})}
onSave={() => saveConnection(![Providers.GITLAB, Providers.JIRA,Providers.TAPD].includes(activeProvider.id) ? settings : {})}
onTest={testConnection}
onCancel={cancel}
onValidate={validate}
Expand All @@ -272,7 +272,7 @@ export default function ConfigureConnection () {
allTestResponses={allTestResponses}
errors={errors}
showError={showConnectionError}
authType={[Providers.JENKINS, Providers.JIRA].includes(activeProvider.id) ? 'plain' : 'token'}
authType={[Providers.JENKINS, Providers.JIRA, Providers.TAPD].includes(activeProvider.id) ? 'plain' : 'token'}
showLimitWarning={false}
sourceLimits={ProviderConnectionLimits}
labels={ProviderFormLabels[activeProvider.id]}
Expand Down
Expand Up @@ -702,7 +702,7 @@ export default function ConnectionForm (props) {
</div>
</>
)}
{[Providers.GITHUB, Providers.GITLAB, Providers.JIRA].includes(
{[Providers.GITHUB, Providers.GITLAB, Providers.JIRA, Providers.TAPD].includes(
activeProvider.id
) && (
<div className='formContainer'>
Expand Down
3 changes: 2 additions & 1 deletion config-ui/src/pages/configure/connections/EditConnection.jsx
Expand Up @@ -76,6 +76,7 @@ export default function EditConnection () {
setEndpointUrl(activeConnection.endpoint)
switch (activeProvider.id) {
case Providers.JENKINS:
case Providers.TAPD:
case Providers.JIRA:
setUsername(activeConnection.username)
setPassword(activeConnection.password)
Expand Down Expand Up @@ -155,7 +156,7 @@ export default function EditConnection () {
testStatus={testStatus}
errors={errors}
showError={showError}
authType={[Providers.JENKINS, Providers.JIRA].includes(activeProvider.id) ? 'plain' : 'token'}
authType={[Providers.JENKINS, Providers.JIRA, Providers.TAPD].includes(activeProvider.id) ? 'plain' : 'token'}
sourceLimits={ProviderConnectionLimits}
labels={ProviderFormLabels[activeProvider.id]}
placeholders={ProviderFormPlaceholders[activeProvider.id]}
Expand Down
19 changes: 19 additions & 0 deletions config-ui/src/pages/pipelines/activity.jsx
Expand Up @@ -44,6 +44,7 @@ import TaskActivity from '@/components/pipelines/TaskActivity'
import CodeInspector from '@/components/pipelines/CodeInspector'
import { ReactComponent as GitlabProviderIcon } from '@/images/integrations/gitlab.svg'
import { ReactComponent as JenkinsProviderIcon } from '@/images/integrations/jenkins.svg'
import { ReactComponent as TapdProviderIcon } from '@/images/integrations/tapd.svg'
import { ReactComponent as JiraProviderIcon } from '@/images/integrations/jira.svg'
import { ReactComponent as GitHubProviderIcon } from '@/images/integrations/github.svg'
import { ReactComponent as HelpIcon } from '@/images/help.svg'
Expand Down Expand Up @@ -507,6 +508,24 @@ const PipelineActivity = (props) => {
</div>
</div>
)}
{pipelineHasProvider(Providers.TAPD) && (
<div className='jenkins-settings' style={{ display: 'flex' }}>
<div style={{ display: 'flex', padding: '2px 6px' }}>
<TapdProviderIcon width={24} height={24} />
</div>
<div>
<label style={{ lineHeight: '100%', display: 'block', fontSize: '10px', marginTop: '2px', marginBottom: '10px' }}>
<strong style={{
fontSize: '16px',
fontWeight: 800
}}
>{ProviderLabels.TAPD}
</strong><br />Auto-configured
</label>
<span style={{ color: Colors.GRAY3 }}>(No Settings)</span>
</div>
</div>
)}
{pipelineHasProvider(Providers.JIRA) && (
<div className='jira-settings' style={{ display: 'flex', paddingLeft: '20px' }}>
<div style={{ display: 'flex', padding: '2px 6px' }}>
Expand Down
2 changes: 2 additions & 0 deletions plugins/ae/tasks/api_client.go
Expand Up @@ -19,6 +19,7 @@ package tasks

import (
"fmt"
"github.com/apache/incubator-devlake/logger"
"net/http"
"time"

Expand All @@ -42,6 +43,7 @@ func CreateApiClient(taskCtx core.TaskContext, connection *models.AeConnection)
nonceStr := core.RandLetterBytes(8)
timestamp := fmt.Sprintf("%v", time.Now().Unix())
sign := models.GetSign(req.URL.Query(), appId, secretKey, nonceStr, timestamp)
logger.Global.Debug("appId: %s\ntimestamp: %s\nnonceStr:%s\nsign:%s\n", appId, timestamp, nonceStr, sign)
req.Header.Set("x-ae-app-id", appId)
req.Header.Set("x-ae-timestamp", timestamp)
req.Header.Set("x-ae-nonce-str", nonceStr)
Expand Down
17 changes: 8 additions & 9 deletions plugins/tapd/api/connection.go
Expand Up @@ -36,38 +36,37 @@ POST /plugins/tapd/test
*/
func TestConnection(input *core.ApiResourceInput) (*core.ApiResourceOutput, error) {
// process input
var params models.TestConnectionRequest
err := mapstructure.Decode(input.Body, &params)
var connection models.TestConnectionRequest
err := mapstructure.Decode(input.Body, &connection)
if err != nil {
return nil, err
}
err = vld.Struct(params)
err = vld.Struct(connection)
if err != nil {
return nil, err
}

// verify multiple token in parallel
// PLEASE NOTE: This works because GitHub API Client rotates tokens on each request
token := params.Auth
apiClient, err := helper.NewApiClient(
context.TODO(),
params.Endpoint,
connection.Endpoint,
map[string]string{
"Authorization": fmt.Sprintf("Basic %s", token),
"Authorization": fmt.Sprintf("Basic %s", connection.GetEncodedToken()),
},
3*time.Second,
params.Proxy,
connection.Proxy,
basicRes,
)
if err != nil {
return nil, fmt.Errorf("verify token failed for %s %w", token, err)
return nil, fmt.Errorf("verify token failed for %s %w", connection.Username, err)
}
res, err := apiClient.Get("/quickstart/testauth", nil, nil)
if err != nil {
return nil, err
}
if res.StatusCode == http.StatusUnauthorized {
return nil, fmt.Errorf("verify token failed for %s", token)
return nil, fmt.Errorf("verify token failed for %s", connection.Username)
}
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", res.StatusCode)
Expand Down
6 changes: 3 additions & 3 deletions plugins/tapd/models/connection.go
Expand Up @@ -25,9 +25,9 @@ import (
)

type TestConnectionRequest struct {
Endpoint string `json:"endpoint" validate:"required,url"`
Auth string `json:"auth" validate:"required"`
Proxy string `json:"proxy" gorm:"type:varchar(255)"`
Endpoint string `json:"endpoint"`
Proxy string `json:"proxy"`
helper.BasicAuth `mapstructure:",squash"`
}

type WorkspaceResponse struct {
Expand Down