You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by li...@apache.org on 2022/10/11 07:03:23 UTC
[incubator-devlake] branch main updated: feat: add jenkins job select in create-blueprint page (#3356)
This is an automated email from the ASF dual-hosted git repository.
likyh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 24b674a6 feat: add jenkins job select in create-blueprint page (#3356)
24b674a6 is described below
commit 24b674a65d662256e19e638d68d38931a2056ae7
Author: Likyh <l...@likyh.com>
AuthorDate: Tue Oct 11 15:03:19 2022 +0800
feat: add jenkins job select in create-blueprint page (#3356)
* feat: add jenkins job select in create-blueprint page
* feat: add jenkins selector in edit page
* feat: add jobName in backend for jenkins scope
* feat: save jenkins models in different scope by jobName
* fix: fix for review
* fix: fix for lint
* fix: fix for review
Co-authored-by: linyh <ya...@meri.co>
---
.../blueprints/BlueprintDataScopesDialog.jsx | 20 ++-
.../components/blueprints/JenkinsJobsSelector.jsx | 151 ++++++++++++++++++++
.../blueprints/ProviderTransformationSettings.jsx | 3 +-
.../blueprints/create-workflow/DataScopes.jsx | 25 ++++
.../create-workflow/DataTransformations.jsx | 33 ++---
config-ui/src/config/jenkinsApiProxy.js | 23 +++
config-ui/src/hooks/useBlueprintValidation.jsx | 16 +--
config-ui/src/hooks/useDataScopesManager.jsx | 154 +++++++++------------
config-ui/src/hooks/useJenkins.jsx | 91 ++++++++++++
config-ui/src/models/JenkinsJob.js | 56 ++++++++
.../src/pages/blueprints/blueprint-settings.jsx | 28 +++-
.../src/pages/blueprints/create-blueprint.jsx | 23 +++
.../src/pages/configure/integration/manage.jsx | 4 +-
config-ui/src/pages/configure/settings/gitlab.jsx | 1 -
config-ui/src/pages/configure/settings/jenkins.jsx | 9 +-
config-ui/src/store/UIContext.jsx | 34 ++---
config-ui/src/styles/libraries/blueprint.scss | 7 +
plugins/gitlab/api/proxy.go | 2 +-
plugins/{gitlab => jenkins}/api/proxy.go | 10 +-
plugins/jenkins/e2e/builds_test.go | 1 +
plugins/jenkins/e2e/jobs_test.go | 1 +
plugins/jenkins/e2e/stages_test.go | 1 +
plugins/jenkins/impl/impl.go | 3 +
plugins/jenkins/jenkins.go | 2 +
plugins/jenkins/tasks/build_cicd_convertor.go | 1 +
plugins/jenkins/tasks/build_collector.go | 3 +-
plugins/jenkins/tasks/build_commit_convertor.go | 1 +
plugins/jenkins/tasks/build_extractor.go | 10 +-
plugins/jenkins/tasks/job_collector.go | 9 +-
plugins/jenkins/tasks/job_extractor.go | 9 +-
plugins/jenkins/tasks/stage_collector.go | 5 +-
plugins/jenkins/tasks/stage_convertor.go | 1 +
plugins/jenkins/tasks/stage_extractor.go | 1 +
plugins/jenkins/tasks/task_data.go | 2 +
34 files changed, 551 insertions(+), 189 deletions(-)
diff --git a/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx b/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx
index 941e8e6f..44e5e733 100644
--- a/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx
+++ b/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx
@@ -77,6 +77,8 @@ const BlueprintDataScopesDialog = (props) => {
setBoardSearch = () => {},
gitlabProjects = [],
fetchGitlabProjects = () => [],
+ fetchJenkinsJobs = () => [],
+ jenkinsJobs = [],
entities = {},
projects = {},
mode = Modes.EDIT,
@@ -112,6 +114,8 @@ const BlueprintDataScopesDialog = (props) => {
jiraProxyError,
isFetchingGitlab,
gitlabProxyError,
+ isFetchingJenkins,
+ jenkinsProxyError,
errors = [],
content = null,
backButtonProps = {
@@ -119,28 +123,32 @@ const BlueprintDataScopesDialog = (props) => {
intent: Intent.PRIMARY,
text: 'Previous Step',
outlined: true,
- loading: isFetchingJIRA || isFetchingGitlab || isSaving
+ loading:
+ isFetchingJIRA || isFetchingGitlab || isFetchingJenkins || isSaving
},
nextButtonProps = {
disabled: !isValid,
intent: Intent.PRIMARY,
text: 'Next Step',
outlined: true,
- loading: isFetchingJIRA || isFetchingGitlab || isSaving
+ loading:
+ isFetchingJIRA || isFetchingGitlab || isFetchingJenkins || isSaving
},
finalButtonProps = {
disabled: !isValid,
intent: Intent.PRIMARY,
onClick: onSave,
text: 'Save Changes',
- loading: isFetchingJIRA || isFetchingGitlab || isSaving
+ loading:
+ isFetchingJIRA || isFetchingGitlab || isFetchingJenkins || isSaving
},
closeButtonProps = {
// disabled:
intent: Intent.PRIMARY,
text: 'Cancel',
outlined: true,
- loading: isFetchingJIRA || isFetchingGitlab || isSaving
+ loading:
+ isFetchingJIRA || isFetchingGitlab || isFetchingJenkins || isSaving
}
} = props
@@ -184,6 +192,10 @@ const BlueprintDataScopesDialog = (props) => {
gitlabProjects={gitlabProjects}
isFetchingGitlab={isFetchingGitlab}
gitlabProxyError={gitlabProxyError}
+ fetchJenkinsJobs={fetchJenkinsJobs}
+ jenkinsJobs={jenkinsJobs}
+ isFetchingJenkins={isFetchingJenkins}
+ jenkinsProxyError={jenkinsProxyError}
dataEntities={entities}
projects={projects}
configuredConnection={configuredConnection}
diff --git a/config-ui/src/components/blueprints/JenkinsJobsSelector.jsx b/config-ui/src/components/blueprints/JenkinsJobsSelector.jsx
new file mode 100644
index 00000000..00dfe675
--- /dev/null
+++ b/config-ui/src/components/blueprints/JenkinsJobsSelector.jsx
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import React, { useEffect, useState } from 'react'
+import { Intent, MenuItem, Position, Tooltip } from '@blueprintjs/core'
+import { MultiSelect } from '@blueprintjs/select'
+import JenkinsJob from '@/models/JenkinsJob'
+
+const JenkinsJobsSelector = (props) => {
+ const {
+ onFetch = () => [],
+ isFetching = false,
+ configuredConnection,
+ placeholder = 'Select Jobs',
+ items = [],
+ selectedItems = [],
+ activeItem = null,
+ disabled = false,
+ isLoading = false,
+ isSaving = false,
+ onItemSelect = () => {},
+ onRemove = () => {},
+ onClear = () => {},
+ itemRenderer = (item, { handleClick, modifiers }) => (
+ <MenuItem
+ active={modifiers.active}
+ disabled={selectedItems.find((i) => i?.id === item?.id)}
+ key={item.value}
+ onClick={handleClick}
+ text={
+ selectedItems.find((i) => i?.id === item?.id) ? (
+ <>
+ <input type='checkbox' checked readOnly /> {item?.title}
+ </>
+ ) : (
+ <span style={{ fontWeight: 700 }}>
+ <input type='checkbox' readOnly /> {item?.title}
+ </span>
+ )
+ }
+ style={{
+ marginBottom: '2px',
+ fontWeight: items.includes(item) ? 700 : 'normal'
+ }}
+ />
+ ),
+ // eslint-disable-next-line max-len
+ tagRenderer = (item) => (
+ <Tooltip
+ intent={Intent.PRIMARY}
+ content={item?.title}
+ position={Position.TOP}
+ >
+ {item.title}
+ </Tooltip>
+ )
+ } = props
+
+ const [query, setQuery] = useState('')
+ const [filtedItems, setFiltedItems] = useState([])
+
+ useEffect(() => {
+ onFetch()
+ }, [onFetch, configuredConnection?.id])
+
+ useEffect(() => {
+ setFiltedItems(items.filter((v) => v.title.includes(query)))
+ }, [items, query])
+
+ return (
+ <div
+ className='jenkins-jobs-multiselect'
+ style={{ display: 'flex', marginBottom: '10px' }}
+ >
+ <div
+ className='jenkins-jobs-multiselect-selector'
+ style={{ minWidth: '200px', width: '100%' }}
+ >
+ <MultiSelect
+ disabled={disabled || isSaving || isLoading}
+ // openOnKeyDown={true}
+ resetOnSelect={true}
+ placeholder={placeholder}
+ popoverProps={{ usePortal: false, minimal: true }}
+ className='multiselector-jobs'
+ inline={true}
+ fill={true}
+ items={filtedItems}
+ selectedItems={selectedItems}
+ activeItem={activeItem}
+ onQueryChange={(query) => setQuery(query)}
+ itemRenderer={itemRenderer}
+ tagRenderer={tagRenderer}
+ tagInputProps={{
+ tagProps: {
+ intent: Intent.PRIMARY,
+ minimal: true
+ }
+ }}
+ noResults={
+ isFetching ? (
+ <MenuItem disabled={true} text='Fetching...' />
+ ) : (
+ <MenuItem disabled={true} text='No Jobs Available.' />
+ )
+ }
+ onRemove={(item) => {
+ onRemove((rT) => {
+ return {
+ ...rT,
+ [configuredConnection.id]: rT[configuredConnection.id].filter(
+ (t) => t?.id !== item.id
+ )
+ }
+ })
+ }}
+ onItemSelect={(item) => {
+ onItemSelect((rT) => {
+ return !rT[configuredConnection.id].includes(item)
+ ? {
+ ...rT,
+ [configuredConnection.id]: [
+ ...rT[configuredConnection.id],
+ new JenkinsJob(item)
+ ]
+ }
+ : { ...rT }
+ })
+ }}
+ style={{ borderRight: 0 }}
+ />
+ </div>
+ </div>
+ )
+}
+
+export default JenkinsJobsSelector
diff --git a/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx b/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx
index 5ecf56be..a211e2c9 100644
--- a/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx
+++ b/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx
@@ -65,7 +65,6 @@ const ProviderTransformationSettings = (props) => {
provider={provider}
connection={connection}
configuredProject={configuredProject}
- projects={projects}
transformation={transformation}
entityIdKey={entityIdKey}
onSettingsChange={onSettingsChange}
@@ -80,7 +79,6 @@ const ProviderTransformationSettings = (props) => {
provider={provider}
connection={connection}
configuredProject={configuredProject}
- projects={projects}
transformation={transformation}
entityIdKey={entityIdKey}
onSettingsChange={onSettingsChange}
@@ -115,6 +113,7 @@ const ProviderTransformationSettings = (props) => {
<JenkinsSettings
provider={provider}
connection={connection}
+ configuredProject={configuredProject}
transformation={transformation}
entityIdKey={entityIdKey}
onSettingsChange={onSettingsChange}
diff --git a/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx b/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
index 2091dfab..65cb5be4 100644
--- a/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
+++ b/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
@@ -31,6 +31,7 @@ import DataEntitiesSelector from '@/components/blueprints/DataEntitiesSelector'
import NoData from '@/components/NoData'
import GitlabProjectsSelector from '@/components/blueprints/GitlabProjectsSelector'
import GitHubProject from '@/models/GithubProject'
+import JenkinsJobsSelector from '@/components/blueprints/JenkinsJobsSelector'
const DataScopes = (props) => {
const {
@@ -42,6 +43,9 @@ const DataScopes = (props) => {
fetchGitlabProjects = () => [],
isFetchingGitlab = false,
gitlabProjects = [],
+ fetchJenkinsJobs = () => [],
+ isFetchingJenkins = false,
+ jenkinsJobs = [],
dataEntities = [],
projects = [],
boards = [],
@@ -232,6 +236,27 @@ const DataScopes = (props) => {
</>
)}
+ {[Providers.JENKINS].includes(
+ configuredConnection.provider
+ ) && (
+ <>
+ <h4>Jobs *</h4>
+ <p>Select the job you would like to sync.</p>
+ <JenkinsJobsSelector
+ onFetch={fetchJenkinsJobs}
+ isFetching={isFetchingJenkins}
+ items={jenkinsJobs}
+ selectedItems={selectedProjects}
+ onItemSelect={setProjects}
+ onClear={setProjects}
+ onRemove={setProjects}
+ disabled={isSaving}
+ configuredConnection={configuredConnection}
+ isLoading={isFetching}
+ />
+ </>
+ )}
+
<h4>Data Entities</h4>
<p>
Select the data entities you wish to collect for the
diff --git a/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx b/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx
index 14581368..f929cb3c 100644
--- a/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx
+++ b/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx
@@ -53,7 +53,6 @@ import ConnectionTabs from '@/components/blueprints/ConnectionTabs'
import NoData from '@/components/NoData'
import StandardStackedList from '@/components/blueprints/StandardStackedList'
import ProviderTransformationSettings from '@/components/blueprints/ProviderTransformationSettings'
-import GithubSettings from '@/pages/configure/settings/github'
const DataTransformations = (props) => {
const {
@@ -104,15 +103,6 @@ const DataTransformations = (props) => {
setInitializeTransformations(transformations)
}, [])
- const isTransformationSupported = useMemo(
- () =>
- configuredProject ||
- configuredBoard ||
- (configuredConnection?.provider === Providers.JENKINS &&
- configuredConnection),
- [configuredProject, configuredBoard, configuredConnection]
- )
-
const noTransformationsAvailable = useMemo(
() =>
[Providers.TAPD].includes(configuredConnection?.provider) ||
@@ -150,9 +140,6 @@ const DataTransformations = (props) => {
(item) => {
const initializeTransform = initializeTransformations[item?.id]
const storedTransform = transformations[item?.id]
-
- console.log(initializeTransform)
- console.log(storedTransform)
return (
initializeTransform &&
storedTransform &&
@@ -265,7 +252,8 @@ const DataTransformations = (props) => {
[
Providers.JIRA,
Providers.GITHUB,
- Providers.GITLAB
+ Providers.GITLAB,
+ Providers.JENKINS
].includes(configuredConnection.provider) && (
<div
className='project-or-board-select'
@@ -277,9 +265,6 @@ const DataTransformations = (props) => {
: 'Project'}
</h4>
<Select
- disabled={
- configuredConnection.provider === Providers.JENKINS
- }
popoverProps={{ usePortal: false }}
className='selector-entity'
id='selector-entity'
@@ -313,10 +298,6 @@ const DataTransformations = (props) => {
}}
>
<Button
- disabled={
- configuredConnection.provider ===
- Providers.JENKINS
- }
className='btn-select-entity'
intent={Intent.PRIMARY}
outlined
@@ -339,9 +320,11 @@ const DataTransformations = (props) => {
</div>
)}
- {[Providers.GITLAB, Providers.GITHUB].includes(
- configuredConnection.provider
- ) &&
+ {[
+ Providers.GITLAB,
+ Providers.GITHUB,
+ Providers.JENKINS
+ ].includes(configuredConnection.provider) &&
!useDropdownSelector &&
!configuredProject && (
<>
@@ -391,7 +374,7 @@ const DataTransformations = (props) => {
</>
)}
- {isTransformationSupported && (
+ {(configuredProject || configuredBoard) && (
<div>
{!useDropdownSelector &&
(configuredProject || configuredBoard) && (
diff --git a/config-ui/src/config/jenkinsApiProxy.js b/config-ui/src/config/jenkinsApiProxy.js
new file mode 100644
index 00000000..4497a081
--- /dev/null
+++ b/config-ui/src/config/jenkinsApiProxy.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+// @todo: add string replacer for [:connectionId] or refactor this const
+const JENKINS_API_PROXY_ENDPOINT =
+ '/api/plugins/jenkins/connections/[:connectionId:]/proxy/rest'
+const JENKINS_JOBS_ENDPOINT = `${JENKINS_API_PROXY_ENDPOINT}/api/json?tree=jobs[name]{0,10000}`
+
+export { JENKINS_API_PROXY_ENDPOINT, JENKINS_JOBS_ENDPOINT }
diff --git a/config-ui/src/hooks/useBlueprintValidation.jsx b/config-ui/src/hooks/useBlueprintValidation.jsx
index 9bcb9a69..a409e7d1 100644
--- a/config-ui/src/hooks/useBlueprintValidation.jsx
+++ b/config-ui/src/hooks/useBlueprintValidation.jsx
@@ -161,10 +161,16 @@ function useBlueprintValidation({
errs.push('Boards: No Boards selected.')
}
if (
- activeProvider?.id === Providers.GITHUB &&
+ [Providers.GITHUB, Providers.GITLAB, Providers.JENKINS].includes(
+ activeProvider?.id
+ ) &&
projects[activeConnection?.id]?.length === 0
) {
- errs.push('Projects: No Project Repsitories entered.')
+ if (activeProvider?.id === Providers.JENKINS) {
+ errs.push('Jobs: No Job entered.')
+ } else {
+ errs.push('Projects: No Project Repsitories entered.')
+ }
}
if (
activeProvider?.id === Providers.GITHUB &&
@@ -191,12 +197,6 @@ function useBlueprintValidation({
if (entities[activeConnection?.id]?.length === 0) {
errs.push('Data Entities: No Data Entities selected.')
}
- if (
- activeProvider?.id === Providers.GITLAB &&
- projects[activeConnection?.id]?.length === 0
- ) {
- errs.push('Projects: No Project IDs entered.')
- }
if (
activeProvider?.id === Providers.GITLAB &&
!validateUniqueObjectSet(projects[activeConnection?.id])
diff --git a/config-ui/src/hooks/useDataScopesManager.jsx b/config-ui/src/hooks/useDataScopesManager.jsx
index f100f8d3..71577c51 100644
--- a/config-ui/src/hooks/useDataScopesManager.jsx
+++ b/config-ui/src/hooks/useDataScopesManager.jsx
@@ -15,19 +15,17 @@
* limitations under the License.
*
*/
-import { useCallback, useEffect, useState, useMemo } from 'react'
-import { ToastNotification } from '@/components/Toast'
-import { DEVLAKE_ENDPOINT } from '@/utils/config'
-import request from '@/utils/request'
-import { NullBlueprint, BlueprintMode } from '@/data/NullBlueprint'
+import { useCallback, useEffect, useMemo, useState } from 'react'
+import { BlueprintMode } from '@/data/NullBlueprint'
import { DEFAULT_DATA_ENTITIES } from '@/data/BlueprintWorkflow'
import { integrationsData } from '@/data/integrations'
import TransformationSettings from '@/models/TransformationSettings'
import JiraBoard from '@/models/JiraBoard'
import GitHubProject from '@/models/GithubProject'
import GitlabProject from '@/models/GitlabProject'
-import { Providers, ProviderLabels, ProviderIcons } from '@/data/Providers'
+import { ProviderIcons, ProviderLabels, Providers } from '@/data/Providers'
import { DataScopeModes } from '@/data/DataScopes'
+import JenkinsJob from '@/models/JenkinsJob'
function useDataScopesManager({
mode = DataScopeModes.CREATE,
@@ -62,12 +60,12 @@ function useDataScopesManager({
switch (connection?.providerId) {
case Providers.GITHUB:
case Providers.GITLAB:
+ case Providers.JENKINS:
key = configuredProject?.id
break
case Providers.JIRA:
key = configuredBoard?.id
break
- case Providers.JENKINS:
case 'default':
key = `C#${connection?.id}`
break
@@ -254,13 +252,13 @@ function useDataScopesManager({
}))
break
case Providers.JENKINS:
- newScope = {
+ newScope = projects[connection.id]?.map((p) => ({
...newScope,
- // options: {
- // },
- // NOTE: Jenkins has no concept of projects/boards. Transformations Key'ed by Conn *INDEX* ID!
- transformation: { ...transformations[`C#${connection?.id}`] }
- }
+ options: {
+ jobName: p.value
+ },
+ transformation: { ...transformations[p?.id] }
+ }))
break
case Providers.GITHUB:
newScope = projects[connection.id]?.map((p) => ({
@@ -365,38 +363,64 @@ function useDataScopesManager({
const getGithubProjects = useCallback(
(c) =>
- [Providers.GITHUB].includes(c.plugin)
- ? c.scope.map(
- (s) =>
- new GitHubProject({
- id: `${s.options?.owner}/${s.options?.repo}`,
- key: `${s.options?.owner}/${s.options?.repo}`,
- owner: s.options?.owner,
- repo: s.options?.repo,
- value: `${s.options?.owner}/${s.options?.repo}`,
- title: `${s.options?.owner}/${s.options?.repo}`
- })
- )
- : [],
+ c.scope.map(
+ (s) =>
+ new GitHubProject({
+ id: `${s.options?.owner}/${s.options?.repo}`,
+ key: `${s.options?.owner}/${s.options?.repo}`,
+ owner: s.options?.owner,
+ repo: s.options?.repo,
+ value: `${s.options?.owner}/${s.options?.repo}`,
+ title: `${s.options?.owner}/${s.options?.repo}`
+ })
+ ),
[]
)
const getGitlabProjects = useCallback(
(c) =>
- [Providers.GITLAB].includes(c.plugin)
- ? c.scope.map(
- (s) =>
- new GitlabProject({
- id: s.options?.projectId,
- key: s.options?.projectId,
- value: s.options?.projectId,
- title: s.options?.title || `Project ${s.options?.projectId}`
- })
- )
- : [],
+ c.scope.map(
+ (s) =>
+ new GitlabProject({
+ id: s.options?.projectId,
+ key: s.options?.projectId,
+ value: s.options?.projectId,
+ title: s.options?.title || `Project ${s.options?.projectId}`
+ })
+ ),
+ []
+ )
+
+ const getJenkinsProjects = useCallback(
+ (c) =>
+ c.scope.map(
+ (s) =>
+ new JenkinsJob({
+ id: s.options?.jobName,
+ key: s.options?.jobName,
+ value: s.options?.jobName,
+ title: s.options?.jobName
+ })
+ ),
[]
)
+ const getProjects = useCallback(
+ (c) => {
+ switch (c.plugin) {
+ case Providers.GITHUB:
+ return getGithubProjects(c)
+ case Providers.GITLAB:
+ return getGitlabProjects(c)
+ case Providers.JENKINS:
+ return getJenkinsProjects(c)
+ default:
+ return []
+ }
+ },
+ [getGithubProjects, getGitlabProjects, getJenkinsProjects]
+ )
+
const getAdvancedGithubProjects = useCallback(
(t, providerId) =>
[Providers.GITHUB].includes(providerId)
@@ -531,9 +555,7 @@ function useDataScopesManager({
entityList: c.scope[0]?.entities?.map((e) =>
DEFAULT_DATA_ENTITIES.find((de) => de.value === e)
),
- projects: [Providers.GITLAB].includes(c.plugin)
- ? getGitlabProjects(c)
- : getGithubProjects(c),
+ projects: getProjects(c),
boards: [Providers.JIRA].includes(c.plugin)
? c.scope.map((s) => `Board ${s.options?.boardId}`)
: [],
@@ -562,7 +584,7 @@ function useDataScopesManager({
stage: 1,
totalStages: 1
}),
- [getGithubProjects, getGitlabProjects]
+ [getProjects]
)
const createAdvancedConnection = useCallback(
@@ -655,6 +677,7 @@ function useDataScopesManager({
switch (connection?.provider?.id) {
case Providers.GITHUB:
case Providers.GITLAB:
+ case Providers.JENKINS:
setProjects((p) => ({
...p,
[connection?.id]: connection?.projects || []
@@ -683,16 +706,6 @@ function useDataScopesManager({
setTransformationSettings(connection.transformations[bIdx], bId)
)
break
- case Providers.JENKINS:
- setEntities((e) => ({
- ...e,
- [connection?.id]: connection?.entityList || []
- }))
- setTransformationSettings(
- connection.transformations[0],
- `C#${connection?.id}`
- )
- break
}
}, [connection, setTransformationSettings])
@@ -708,45 +721,6 @@ function useDataScopesManager({
modifyConnectionSettings
])
- useEffect(() => {
- console.log('>>>>> DATA SCOPES MANAGER: PROVIDER...', provider)
- switch (provider?.id) {
- case Providers.GITHUB:
- break
- case Providers.GITLAB:
- break
- case Providers.JIRA:
- break
- case Providers.JENKINS:
- break
- case Providers.TAPD:
- break
- }
- }, [provider])
-
- useEffect(() => {
- console.log(
- '>>>>> DATA SCOPES MANAGER: INITIALIZE NEW CONNECTION TRANSFORMATIONS...',
- newConnections
- )
- // @note: jenkins has no "project/board" entity associated!
- // transformations are based on the main connection scope...
- const jenkinsTransformations = newConnections
- .filter((c) => c.plugin === Providers.JENKINS)
- .map((c) => `C#${c?.id}`)
- console.log(
- '>>>>> DATA SCOPES MANAGER: JENKINS TRANSFORMATIONS SCOPES...',
- jenkinsTransformations
- )
- if (Array.isArray(jenkinsTransformations)) {
- setTransformations((cT) => ({
- ...jenkinsTransformations.reduce(initializeTransformations, {}),
- // Spread Current/Existing Transformations Settings
- ...cT
- }))
- }
- }, [newConnections, initializeTransformations])
-
useEffect(() => {
console.log('>>>>> DATA SCOPES MANAGER: INITIALIZE BOARDS...', boards)
const boardTransformations = boards[connection?.id]
diff --git a/config-ui/src/hooks/useJenkins.jsx b/config-ui/src/hooks/useJenkins.jsx
new file mode 100644
index 00000000..81ec872b
--- /dev/null
+++ b/config-ui/src/hooks/useJenkins.jsx
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import { useEffect, useState, useCallback } from 'react'
+import request from '@/utils/request'
+import { ToastNotification } from '@/components/Toast'
+
+const useJenkins = (
+ { apiProxyPath, jobsEndpoint },
+ activeConnection = null
+) => {
+ const [isFetching, setIsFetching] = useState(false)
+ const [jobs, setJobs] = useState([])
+ const [error, setError] = useState()
+
+ const fetchJobs = useCallback(async () => {
+ try {
+ if (apiProxyPath.includes('null')) {
+ throw new Error('Connection ID is Null')
+ }
+ setError(null)
+ setIsFetching(true)
+ // only search when type more than 2 chars
+ const endpoint = jobsEndpoint.replace(
+ '[:connectionId:]',
+ activeConnection?.connectionId
+ )
+ const jobsResponse = await request.get(endpoint)
+ if (
+ jobsResponse &&
+ jobsResponse.status === 200 &&
+ jobsResponse.data &&
+ jobsResponse.data.jobs
+ ) {
+ setJobs(createListData(jobsResponse.data?.jobs))
+ } else {
+ throw new Error('request jobs fail')
+ }
+ } catch (e) {
+ setError(e)
+ ToastNotification.show({
+ message: e.message,
+ intent: 'danger',
+ icon: 'error'
+ })
+ } finally {
+ setIsFetching(false)
+ }
+ }, [jobsEndpoint, activeConnection, apiProxyPath])
+
+ const createListData = (
+ data = [],
+ titleProperty = 'name',
+ valueProperty = 'name'
+ ) => {
+ return data.map((d, dIdx) => ({
+ id: d[valueProperty],
+ key: d[valueProperty],
+ title: d[titleProperty],
+ value: d[valueProperty],
+ type: 'string'
+ }))
+ }
+
+ useEffect(() => {
+ console.log('>>> Jenkins API PROXY: FIELD SELECTOR JOBS DATA', jobs)
+ }, [jobs])
+
+ return {
+ isFetching,
+ fetchJobs,
+ jobs,
+ error
+ }
+}
+
+export default useJenkins
diff --git a/config-ui/src/models/JenkinsJob.js b/config-ui/src/models/JenkinsJob.js
new file mode 100644
index 00000000..f43d29bf
--- /dev/null
+++ b/config-ui/src/models/JenkinsJob.js
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @typedef {object} JenkinsJob
+ * @property {number?} id
+ * @property {number?} key
+ * @property {number?} projectId
+ * @property {string|number?} name
+ * @property {string|number?} value
+ * @property {string|number?} title
+ * @property {boolean?} useApi
+ * @property {project|board|job?} variant
+ */
+class JenkinsJob {
+ constructor(data = {}) {
+ this.id = data?.id || null
+ this.key = data?.key || this.id || null
+ this.name = data?.name || null
+ this.value = data?.value || this.name || this.id || null
+ this.title = data?.title || this.name || this.id || null
+
+ this.useApi = data?.useApi || true
+ this.variant = data?.variant || 'job'
+ }
+
+ get(property) {
+ return this[property]
+ }
+
+ set(property, value) {
+ this[property] = value
+ return this.property
+ }
+
+ getConfiguredEntityId() {
+ return this.name.toString() || this.id
+ }
+}
+
+export default JenkinsJob
diff --git a/config-ui/src/pages/blueprints/blueprint-settings.jsx b/config-ui/src/pages/blueprints/blueprint-settings.jsx
index cb1c9355..5095047a 100644
--- a/config-ui/src/pages/blueprints/blueprint-settings.jsx
+++ b/config-ui/src/pages/blueprints/blueprint-settings.jsx
@@ -78,6 +78,11 @@ import {
GITLAB_API_PROXY_ENDPOINT,
PROJECTS_ENDPOINT
} from '@/config/gitlabApiProxy'
+import useJenkins from '@/hooks/useJenkins'
+import {
+ JENKINS_API_PROXY_ENDPOINT,
+ JENKINS_JOBS_ENDPOINT
+} from '@/config/jenkinsApiProxy'
const BlueprintSettings = (props) => {
// eslint-disable-next-line no-unused-vars
@@ -326,6 +331,19 @@ const BlueprintSettings = (props) => {
configuredConnection
)
+ const {
+ fetchJobs: fetchJenkinsJobs,
+ jobs: jenkinsJobs,
+ isFetching: isFetchingJenkins,
+ error: jenkinsProxyError
+ } = useJenkins(
+ {
+ apiProxyPath: JENKINS_API_PROXY_ENDPOINT,
+ jobsEndpoint: JENKINS_JOBS_ENDPOINT
+ },
+ configuredConnection
+ )
+
const handleBlueprintActivation = useCallback(
(blueprint) => {
if (blueprint.enable) {
@@ -1281,7 +1299,8 @@ const BlueprintSettings = (props) => {
loading={
isFetchingBlueprint ||
isFetchingJIRA ||
- isFetchingGitlab
+ isFetchingGitlab ||
+ isFetchingJenkins
}
/>
</div>
@@ -1322,7 +1341,8 @@ const BlueprintSettings = (props) => {
loading={
isFetchingBlueprint ||
isFetchingJIRA ||
- isFetchingGitlab
+ isFetchingGitlab ||
+ isFetchingJenkins
}
/>
</div>
@@ -1455,6 +1475,10 @@ const BlueprintSettings = (props) => {
gitlabProjects={gitlabProjects}
isFetchingGitlab={isFetchingGitlab}
gitlabProxyError={gitlabProxyError}
+ fetchJenkinsJobs={fetchJenkinsJobs}
+ jenkinsJobs={jenkinsJobs}
+ isFetchingJenkins={isFetchingJenkins}
+ jenkinsProxyError={jenkinsProxyError}
setConfiguredProject={setConfiguredProject}
setConfiguredBoard={setConfiguredBoard}
setBoards={setBoards}
diff --git a/config-ui/src/pages/blueprints/create-blueprint.jsx b/config-ui/src/pages/blueprints/create-blueprint.jsx
index 2c2bd83c..3aa214f7 100644
--- a/config-ui/src/pages/blueprints/create-blueprint.jsx
+++ b/config-ui/src/pages/blueprints/create-blueprint.jsx
@@ -79,6 +79,11 @@ import {
GITLAB_API_PROXY_ENDPOINT,
PROJECTS_ENDPOINT
} from '@/config/gitlabApiProxy'
+import useJenkins from '@/hooks/useJenkins'
+import {
+ JENKINS_API_PROXY_ENDPOINT,
+ JENKINS_JOBS_ENDPOINT
+} from '@/config/jenkinsApiProxy'
// import ConnectionTabs from '@/components/blueprints/ConnectionTabs'
@@ -287,6 +292,19 @@ const CreateBlueprint = (props) => {
configuredConnection
)
+ const {
+ fetchJobs: fetchJenkinsJobs,
+ jobs: jenkinsJobs,
+ isFetching: isFetchingJenkins,
+ error: jenkinsProxyError
+ } = useJenkins(
+ {
+ apiProxyPath: JENKINS_API_PROXY_ENDPOINT,
+ jobsEndpoint: JENKINS_JOBS_ENDPOINT
+ },
+ configuredConnection
+ )
+
const {
testConnection,
// eslint-disable-next-line no-unused-vars
@@ -1137,6 +1155,9 @@ const CreateBlueprint = (props) => {
fetchGitlabProjects={fetchGitlabProjects}
isFetchingGitlab={isFetchingGitlab}
gitlabProjects={gitlabProjects}
+ fetchJenkinsJobs={fetchJenkinsJobs}
+ isFetchingJenkins={isFetchingJenkins}
+ jenkinsJobs={jenkinsJobs}
boards={boards}
dataEntities={dataEntities}
projects={projects}
@@ -1156,6 +1177,7 @@ const CreateBlueprint = (props) => {
isFetching={
isFetchingJIRA ||
isFetchingGitlab ||
+ isFetchingJenkins ||
isFetchingConnection
}
/>
@@ -1234,6 +1256,7 @@ const CreateBlueprint = (props) => {
isSaving ||
isFetchingJIRA ||
isFetchingGitlab ||
+ isFetchingJenkins ||
isFetchingConnection ||
isTestingConnection
}
diff --git a/config-ui/src/pages/configure/integration/manage.jsx b/config-ui/src/pages/configure/integration/manage.jsx
index 1f964fb4..aca63b6d 100644
--- a/config-ui/src/pages/configure/integration/manage.jsx
+++ b/config-ui/src/pages/configure/integration/manage.jsx
@@ -208,9 +208,7 @@ export default function ManageIntegration() {
</>
)}
</h1>
- <p className='page-description'>
- Manage connections.
- </p>
+ <p className='page-description'>Manage connections.</p>
</div>
</div>
</div>
diff --git a/config-ui/src/pages/configure/settings/gitlab.jsx b/config-ui/src/pages/configure/settings/gitlab.jsx
index fa0c8d02..1af832fc 100644
--- a/config-ui/src/pages/configure/settings/gitlab.jsx
+++ b/config-ui/src/pages/configure/settings/gitlab.jsx
@@ -30,7 +30,6 @@ export default function GitlabSettings(props) {
transformation = {},
entityIdKey,
provider,
- projects,
configuredProject,
isSaving = false,
isSavingConnection = false,
diff --git a/config-ui/src/pages/configure/settings/jenkins.jsx b/config-ui/src/pages/configure/settings/jenkins.jsx
index ceb983ac..9d937571 100644
--- a/config-ui/src/pages/configure/settings/jenkins.jsx
+++ b/config-ui/src/pages/configure/settings/jenkins.jsx
@@ -40,13 +40,14 @@ import '@/styles/connections.scss'
export default function JenkinsSettings(props) {
const {
provider,
- transformation,
- entityIdKey,
connection,
entities = [],
- onSettingsChange = () => {},
+ transformation = {},
+ entityIdKey,
isSaving = false,
- isSavingConnection = false
+ isSavingConnection = false,
+ onSettingsChange = () => {},
+ configuredProject
} = props
const history = useHistory()
const { providerId, connectionId } = useParams()
diff --git a/config-ui/src/store/UIContext.jsx b/config-ui/src/store/UIContext.jsx
index 6e1e22fb..d4774c48 100644
--- a/config-ui/src/store/UIContext.jsx
+++ b/config-ui/src/store/UIContext.jsx
@@ -1,20 +1,20 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
import React, { useState } from 'react'
const UIContext = React.createContext({
@@ -39,4 +39,4 @@ export const UIContextProvider = (props) => {
)
}
-export default UIContext
\ No newline at end of file
+export default UIContext
diff --git a/config-ui/src/styles/libraries/blueprint.scss b/config-ui/src/styles/libraries/blueprint.scss
index 993de363..f00d85bf 100644
--- a/config-ui/src/styles/libraries/blueprint.scss
+++ b/config-ui/src/styles/libraries/blueprint.scss
@@ -155,6 +155,13 @@ button, .bp3-button {
}
}
+.bp3-multi-select-popover {
+ .bp3-menu {
+ max-height: calc(10 * 32px);
+ overflow: auto;
+ }
+}
+
.bp3-multi-select-popover {
max-width: 600px;
overflow: auto;
diff --git a/plugins/gitlab/api/proxy.go b/plugins/gitlab/api/proxy.go
index 39717f45..999cb9bf 100644
--- a/plugins/gitlab/api/proxy.go
+++ b/plugins/gitlab/api/proxy.go
@@ -46,7 +46,7 @@ func Proxy(input *core.ApiResourceInput) (*core.ApiResourceOutput, errors.Error)
map[string]string{
"Authorization": fmt.Sprintf("Bearer %v", connection.Token),
},
- 30*time.Second,
+ TimeOut,
connection.Proxy,
BasicRes,
)
diff --git a/plugins/gitlab/api/proxy.go b/plugins/jenkins/api/proxy.go
similarity index 90%
copy from plugins/gitlab/api/proxy.go
copy to plugins/jenkins/api/proxy.go
index 39717f45..cc56a1db 100644
--- a/plugins/gitlab/api/proxy.go
+++ b/plugins/jenkins/api/proxy.go
@@ -21,13 +21,13 @@ import (
"context"
"encoding/json"
"fmt"
- "github.com/apache/incubator-devlake/errors"
"io"
"time"
+ "github.com/apache/incubator-devlake/errors"
"github.com/apache/incubator-devlake/plugins/core"
- "github.com/apache/incubator-devlake/plugins/gitlab/models"
"github.com/apache/incubator-devlake/plugins/helper"
+ "github.com/apache/incubator-devlake/plugins/jenkins/models"
)
const (
@@ -35,7 +35,7 @@ const (
)
func Proxy(input *core.ApiResourceInput) (*core.ApiResourceOutput, errors.Error) {
- connection := &models.GitlabConnection{}
+ connection := &models.JenkinsConnection{}
err := connectionHelper.First(connection, input.Params)
if err != nil {
return nil, err
@@ -44,9 +44,9 @@ func Proxy(input *core.ApiResourceInput) (*core.ApiResourceOutput, errors.Error)
context.TODO(),
connection.Endpoint,
map[string]string{
- "Authorization": fmt.Sprintf("Bearer %v", connection.Token),
+ "Authorization": fmt.Sprintf("Basic %v", connection.GetEncodedToken()),
},
- 30*time.Second,
+ TimeOut,
connection.Proxy,
BasicRes,
)
diff --git a/plugins/jenkins/e2e/builds_test.go b/plugins/jenkins/e2e/builds_test.go
index bd6fb662..e5d5b8e3 100644
--- a/plugins/jenkins/e2e/builds_test.go
+++ b/plugins/jenkins/e2e/builds_test.go
@@ -35,6 +35,7 @@ func TestJenkinsBuildsDataFlow(t *testing.T) {
taskData := &tasks.JenkinsTaskData{
Options: &tasks.JenkinsOptions{
ConnectionId: 1,
+ JobName: `devlake`,
},
}
diff --git a/plugins/jenkins/e2e/jobs_test.go b/plugins/jenkins/e2e/jobs_test.go
index 85da78d4..b55ad3ea 100644
--- a/plugins/jenkins/e2e/jobs_test.go
+++ b/plugins/jenkins/e2e/jobs_test.go
@@ -34,6 +34,7 @@ func TestJenkinsJobsDataFlow(t *testing.T) {
taskData := &tasks.JenkinsTaskData{
Options: &tasks.JenkinsOptions{
ConnectionId: 1,
+ JobName: `devlake`,
},
}
diff --git a/plugins/jenkins/e2e/stages_test.go b/plugins/jenkins/e2e/stages_test.go
index 61eb87a0..eff00a6e 100644
--- a/plugins/jenkins/e2e/stages_test.go
+++ b/plugins/jenkins/e2e/stages_test.go
@@ -34,6 +34,7 @@ func TestJenkinsStagesDataFlow(t *testing.T) {
taskData := &tasks.JenkinsTaskData{
Options: &tasks.JenkinsOptions{
ConnectionId: 1,
+ JobName: `devlake`,
},
}
diff --git a/plugins/jenkins/impl/impl.go b/plugins/jenkins/impl/impl.go
index 9a94dbe2..11b281a9 100644
--- a/plugins/jenkins/impl/impl.go
+++ b/plugins/jenkins/impl/impl.go
@@ -137,6 +137,9 @@ func (plugin Jenkins) ApiResources() map[string]map[string]core.ApiResourceHandl
"DELETE": api.DeleteConnection,
"GET": api.GetConnection,
},
+ "connections/:connectionId/proxy/rest/*path": {
+ "GET": api.Proxy,
+ },
}
}
diff --git a/plugins/jenkins/jenkins.go b/plugins/jenkins/jenkins.go
index f5c1c12e..941d7798 100644
--- a/plugins/jenkins/jenkins.go
+++ b/plugins/jenkins/jenkins.go
@@ -28,11 +28,13 @@ var PluginEntry impl.Jenkins
func main() {
jenkinsCmd := &cobra.Command{Use: "jenkins"}
connectionId := jenkinsCmd.Flags().Uint64P("connection", "c", 1, "jenkins connection id")
+ jobName := jenkinsCmd.Flags().StringP("jobName", "j", "", "jenkins job name")
deployTagPattern := jenkinsCmd.Flags().String("deployTagPattern", "(?i)deploy", "deploy tag name")
jenkinsCmd.Run = func(cmd *cobra.Command, args []string) {
runner.DirectRun(cmd, args, PluginEntry, map[string]interface{}{
"connectionId": *connectionId,
+ "jobName": jobName,
"deployTagPattern": *deployTagPattern,
})
}
diff --git a/plugins/jenkins/tasks/build_cicd_convertor.go b/plugins/jenkins/tasks/build_cicd_convertor.go
index 5719dbd4..92772030 100644
--- a/plugins/jenkins/tasks/build_cicd_convertor.go
+++ b/plugins/jenkins/tasks/build_cicd_convertor.go
@@ -69,6 +69,7 @@ func ConvertBuildsToCICD(taskCtx core.SubTaskContext) (err errors.Error) {
RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
+ JobName: data.Options.JobName,
},
Ctx: taskCtx,
Table: RAW_BUILD_TABLE,
diff --git a/plugins/jenkins/tasks/build_collector.go b/plugins/jenkins/tasks/build_collector.go
index 1d19f1ae..5f9546c1 100644
--- a/plugins/jenkins/tasks/build_collector.go
+++ b/plugins/jenkins/tasks/build_collector.go
@@ -51,7 +51,7 @@ func CollectApiBuilds(taskCtx core.SubTaskContext) errors.Error {
clauses := []dal.Clause{
dal.Select("tjj.name,tjj.path"),
dal.From("_tool_jenkins_jobs tjj"),
- dal.Where(`tjj.connection_id = ?`, data.Options.ConnectionId),
+ dal.Where(`tjj.connection_id = ? and tjj.name = ?`, data.Options.ConnectionId, data.Options.JobName),
}
cursor, err := db.Cursor(clauses...)
@@ -69,6 +69,7 @@ func CollectApiBuilds(taskCtx core.SubTaskContext) errors.Error {
RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
+ JobName: data.Options.JobName,
},
Ctx: taskCtx,
Table: RAW_BUILD_TABLE,
diff --git a/plugins/jenkins/tasks/build_commit_convertor.go b/plugins/jenkins/tasks/build_commit_convertor.go
index 8af205d3..95589ca8 100644
--- a/plugins/jenkins/tasks/build_commit_convertor.go
+++ b/plugins/jenkins/tasks/build_commit_convertor.go
@@ -59,6 +59,7 @@ func ConvertBuildRepos(taskCtx core.SubTaskContext) errors.Error {
RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
+ JobName: data.Options.JobName,
},
Ctx: taskCtx,
Table: RAW_BUILD_TABLE,
diff --git a/plugins/jenkins/tasks/build_extractor.go b/plugins/jenkins/tasks/build_extractor.go
index ee3e517c..0a01de9a 100644
--- a/plugins/jenkins/tasks/build_extractor.go
+++ b/plugins/jenkins/tasks/build_extractor.go
@@ -45,15 +45,9 @@ func ExtractApiBuilds(taskCtx core.SubTaskContext) errors.Error {
RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
+ JobName: data.Options.JobName,
},
- Ctx: taskCtx,
- /*
- This struct will be JSONEncoded and stored into database along with raw data itself, to identity minimal
- set of data to be process, for example, we process JiraIssues by Board
- */
- /*
- Table store raw data
- */
+ Ctx: taskCtx,
Table: RAW_BUILD_TABLE,
},
Extract: func(row *helper.RawData) ([]interface{}, errors.Error) {
diff --git a/plugins/jenkins/tasks/job_collector.go b/plugins/jenkins/tasks/job_collector.go
index db4325a2..e94db4bd 100644
--- a/plugins/jenkins/tasks/job_collector.go
+++ b/plugins/jenkins/tasks/job_collector.go
@@ -49,14 +49,7 @@ func CollectApiJobs(taskCtx core.SubTaskContext) errors.Error {
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
},
- Ctx: taskCtx,
- /*
- This struct will be JSONEncoded and stored into database along with raw data itself, to identity minimal
- set of data to be process, for example, we process JiraIssues by Board
- */
- /*
- Table store raw data
- */
+ Ctx: taskCtx,
Table: RAW_JOB_TABLE,
},
ApiClient: data.ApiClient,
diff --git a/plugins/jenkins/tasks/job_extractor.go b/plugins/jenkins/tasks/job_extractor.go
index fd93354b..63a553cb 100644
--- a/plugins/jenkins/tasks/job_extractor.go
+++ b/plugins/jenkins/tasks/job_extractor.go
@@ -42,14 +42,7 @@ func ExtractApiJobs(taskCtx core.SubTaskContext) errors.Error {
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
},
- Ctx: taskCtx,
- /*
- This struct will be JSONEncoded and stored into database along with raw data itself, to identity minimal
- set of data to be process, for example, we process JiraIssues by Board
- */
- /*
- Table store raw data
- */
+ Ctx: taskCtx,
Table: RAW_JOB_TABLE,
},
Extract: func(row *helper.RawData) ([]interface{}, errors.Error) {
diff --git a/plugins/jenkins/tasks/stage_collector.go b/plugins/jenkins/tasks/stage_collector.go
index 8411ac01..7ffc1250 100644
--- a/plugins/jenkins/tasks/stage_collector.go
+++ b/plugins/jenkins/tasks/stage_collector.go
@@ -53,8 +53,8 @@ func CollectApiStages(taskCtx core.SubTaskContext) errors.Error {
clauses := []dal.Clause{
dal.Select("tjj.path,tjb.job_name,tjb.number,tjb.full_display_name"),
dal.From("_tool_jenkins_builds as tjb,_tool_jenkins_jobs as tjj"),
- dal.Where(`tjb.connection_id = ? and tjb.class = ? and tjb.job_name = tjj.name`,
- data.Options.ConnectionId, "WorkflowRun"),
+ dal.Where(`tjb.connection_id = ? and tjj.name = ? and tjb.class = ? and tjb.job_name = tjj.name`,
+ data.Options.ConnectionId, data.Options.JobName, "WorkflowRun"),
}
cursor, err := db.Cursor(clauses...)
@@ -72,6 +72,7 @@ func CollectApiStages(taskCtx core.SubTaskContext) errors.Error {
RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
+ JobName: data.Options.JobName,
},
Ctx: taskCtx,
Table: RAW_STAGE_TABLE,
diff --git a/plugins/jenkins/tasks/stage_convertor.go b/plugins/jenkins/tasks/stage_convertor.go
index 75461f49..42dbd670 100644
--- a/plugins/jenkins/tasks/stage_convertor.go
+++ b/plugins/jenkins/tasks/stage_convertor.go
@@ -97,6 +97,7 @@ func ConvertStages(taskCtx core.SubTaskContext) (err errors.Error) {
RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
+ JobName: data.Options.JobName,
},
Ctx: taskCtx,
Table: RAW_STAGE_TABLE,
diff --git a/plugins/jenkins/tasks/stage_extractor.go b/plugins/jenkins/tasks/stage_extractor.go
index d010c792..e4158c6f 100644
--- a/plugins/jenkins/tasks/stage_extractor.go
+++ b/plugins/jenkins/tasks/stage_extractor.go
@@ -42,6 +42,7 @@ func ExtractApiStages(taskCtx core.SubTaskContext) errors.Error {
RawDataSubTaskArgs: helper.RawDataSubTaskArgs{
Params: JenkinsApiParams{
ConnectionId: data.Options.ConnectionId,
+ JobName: data.Options.JobName,
},
Ctx: taskCtx,
Table: RAW_STAGE_TABLE,
diff --git a/plugins/jenkins/tasks/task_data.go b/plugins/jenkins/tasks/task_data.go
index 1a775706..0fa4a298 100644
--- a/plugins/jenkins/tasks/task_data.go
+++ b/plugins/jenkins/tasks/task_data.go
@@ -27,10 +27,12 @@ import (
type JenkinsApiParams struct {
ConnectionId uint64
+ JobName string
}
type JenkinsOptions struct {
ConnectionId uint64 `json:"connectionId"`
+ JobName string `json:"JobName"`
Since string
Tasks []string `json:"tasks,omitempty"`
models.TransformationRules `mapstructure:"transformationRules" json:"transformationRules"`