- {PIPELINE_TASKS[this.activeTab].map(task => (
-
-
-
-
-
-
-
{t(task)}
- {task === 'kubernetesDeploy' && (
-
-
-
- )}
+
+ {(allTask[this.activeTab] || []).map(task => (
+
+
+
+
+
+
+ {t(task.title)}
+
+
{t(task.desc) || '-'}
+
-
{this.taskDescs[task] || '-'}
-
+ ))}
- ))}
-
+ >
+ )}
)
}
diff --git a/src/pages/devops/components/Pipeline/StepsSelector/index.scss b/src/pages/devops/components/Pipeline/StepsSelector/index.scss
index e0049c60649..b45fd3a3b92 100644
--- a/src/pages/devops/components/Pipeline/StepsSelector/index.scss
+++ b/src/pages/devops/components/Pipeline/StepsSelector/index.scss
@@ -83,3 +83,10 @@
background-color: #242e42;
border: solid 1px #242e42;
}
+
+.loading {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
diff --git a/src/pages/devops/components/Pipeline/store.js b/src/pages/devops/components/Pipeline/store.js
index 7e1d4feff5a..a2a5b33178f 100644
--- a/src/pages/devops/components/Pipeline/store.js
+++ b/src/pages/devops/components/Pipeline/store.js
@@ -18,12 +18,15 @@
import { action, observable, computed, toJS } from 'mobx'
import { get, set, unset, isObject, isEmpty, isArray, cloneDeep } from 'lodash'
+import qs from 'qs'
+import cookie from 'utils/cookie'
import CredentialStore from 'stores/devops/credential'
import BaseStore from 'stores/devops'
+import PipelineStore from 'stores/devops/pipelines'
import CDStore from 'stores/cd'
-
-import { generateId } from 'utils'
+import { generateId, safeParseJSON } from 'utils'
+import { CREDENTIAL_DISPLAY_KEY } from 'utils/constants'
const formatPipeLineJson = json => {
if (!get(json, 'pipeline.stages')) return
@@ -67,11 +70,62 @@ const formatPipeLineJson = json => {
return json
}
+const formatStepTemplate = data => {
+ const lang = cookie('lang') === 'zh' ? 'ZH' : 'EN'
+ const template = {}
+ const annotations = get(data, 'metadata.annotations', {})
+
+ template.icon = annotations['step.devops.kubesphere.io/icon']
+ template.category = get(data, [
+ 'metadata',
+ 'labels',
+ 'step.devops.kubesphere.io/category',
+ ])
+ template.name = data.metadata.name
+ template.desc =
+ annotations[`devops.kubesphere.io/description${lang}`] ||
+ annotations['devops.kubesphere.io/descriptionEN']
+ template.title =
+ annotations[`devops.kubesphere.io/displayName${lang}`] ||
+ annotations['devops.kubesphere.io/displayNameEN'] ||
+ annotations.displayNameEN
+
+ template.parameters = get(data, 'spec.parameters', []).map(p => {
+ return {
+ ...p,
+ ...(p.options
+ ? {
+ options: safeParseJSON(p.options, []).map(opt => ({
+ label: t(opt.label),
+ value: opt.value,
+ })),
+ }
+ : {}),
+ }
+ })
+
+ if (!isEmpty(get(data, 'spec.secret', {}))) {
+ const secretType =
+ CREDENTIAL_DISPLAY_KEY[data.spec.secret.type?.split('/')[1]]
+ template.parameters.push({
+ name: 'secret',
+ type: 'secret',
+ display: 'Secret',
+ postByQuery: true,
+ required: true,
+ secretType,
+ })
+ }
+ return template
+}
+
export default class Store extends BaseStore {
credentialStore = new CredentialStore()
cdStore = new CDStore()
+ pipelineStore = new PipelineStore()
+
get newStage() {
return {
branches: [
@@ -132,6 +186,12 @@ export default class Store extends BaseStore {
@observable
cdList = { data: [] }
+ @observable
+ pipelineList = { data: [] }
+
+ @observable
+ pipelineSteps = []
+
handleAddBranch(lineIndex) {
if (this.jsonData.json.pipeline.stages[lineIndex].parallel) {
this.jsonData.json.pipeline.stages[lineIndex].parallel.push(this.newStage)
@@ -298,6 +358,17 @@ export default class Store extends BaseStore {
this.credentialsList = this.credentialStore.list
}
+ @action
+ getPipelines = async params => {
+ await this.pipelineStore.fetchList({
+ devops: this.params.devops,
+ cluster: this.params.cluster,
+ filter: 'no-folders',
+ ...params,
+ })
+ this.pipelineList = this.pipelineStore.list
+ }
+
@action
getCDListData = async params => {
await this.cdStore.fetchList({
@@ -331,4 +402,38 @@ export default class Store extends BaseStore {
}))
}
}
+
+ @action
+ async fetchPipelineStepTemplates() {
+ const data = await request.get(
+ `${this.getBaseUrl()}clustersteptemplates?limit=100`
+ )
+
+ const { items = [] } = data
+ const templateList = items.map(formatStepTemplate)
+
+ this.pipelineSteps = templateList
+ return templateList
+ }
+
+ @action
+ async fetchStepTemplate(clustersteptemplate) {
+ const data = await request.get(
+ `${this.getBaseUrl()}clustersteptemplates/${clustersteptemplate}`
+ )
+ return formatStepTemplate(data)
+ }
+
+ async getPipelineStepTempleJenkins(clustersteptemplate, params, query = {}) {
+ const data = await request.post(
+ `${this.getBaseUrl()}clustersteptemplates/${clustersteptemplate}/render?${qs.stringify(
+ query
+ )}`,
+ params
+ )
+
+ const jenkins = get(data, 'data', '')
+
+ return jenkins
+ }
}
diff --git a/src/utils/constants.js b/src/utils/constants.js
index b3bf8740241..94204ac5306 100644
--- a/src/utils/constants.js
+++ b/src/utils/constants.js
@@ -592,39 +592,6 @@ export const PATTERN_APPTEMPLATE_VERSION = /[a-zA-Z0-9](\.?-?[a-zA-Z0-9])+(\s?\[
export const PATTERN_UTC_TIME = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+Z/
export const PATTERN_ENV_NAME = /^[-._a-zA-Z][-._a-zA-Z0-9]*$/
-export const PIPELINE_TASKS = {
- All: [
- 'git',
- 'checkout',
- 'mail',
- 'echo',
- 'shell',
- 'withCredentials',
- 'container',
- 'archiveArtifacts',
- 'input',
- 'kubernetesDeploy',
- 'cd',
- 'timeout',
- 'withSonarQubeEnv',
- 'waitForQualityGate',
- 'script',
- ],
- SCM: ['git', 'checkout', 'cd'],
- Normal: [
- 'echo',
- 'shell',
- 'mail',
- 'withCredentials',
- 'container',
- 'archiveArtifacts',
- 'kubernetesDeploy',
- 'timeout',
- 'script',
- ],
- Review: ['input', 'withSonarQubeEnv', 'waitForQualityGate'],
-}
-
export const PIPELINE_CONDITIONS = [
'branch',
'environment',
diff --git a/src/utils/devops.js b/src/utils/devops.js
index 08614d1c32c..63b9986e5fc 100644
--- a/src/utils/devops.js
+++ b/src/utils/devops.js
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with KubeSphere Console. If not, see
.
*/
-import { set, cloneDeep } from 'lodash'
+import { get, set, cloneDeep } from 'lodash'
const deleteUnenableAttrs = data => {
/* eslint-disable no-unused-vars */
@@ -131,3 +131,59 @@ export const getLanguageIcon = (name, defaultIcon) => {
]
return LEGO_LANGUAGE_ICON.includes(name) ? name : defaultIcon
}
+
+const parsePhrase = phrase => {
+ const reg = /(.+)(>|>=|==|!=)(.+)/
+ const res = phrase.match(reg)
+ const [, key, operator, value] = res
+ return {
+ key: key.replace('.param.', ''),
+ operator,
+ value,
+ }
+}
+
+const compare = (cond, data) => {
+ const value = get(data, cond.key)
+ switch (cond.operator) {
+ case '==':
+ return value === cond.value
+ case '>=':
+ return value >= cond.value
+ case '<=':
+ return value <= cond.value
+ case '!=':
+ return value !== cond.value
+ default:
+ return false
+ }
+}
+
+export const parseCondition = (cond, data) => {
+ try {
+ const reg = /(.+?)(&&|\|\|)/g
+ const result = cond.match(reg)
+ if (!result) {
+ return compare(parsePhrase(cond), data)
+ }
+ const condList = [
+ ...result.map(match => match.slice(0, -2)),
+ cond.slice(result.reduce((pre, cur) => pre + cur.length, 0)),
+ ].map(parsePhrase)
+ const operator = result.map(match => match.slice(-2))
+ return operator.reduce((pre, cur, index) => {
+ const left = index === 0 ? compare(condList[0], data) : pre
+ const right = compare(condList[index + 1], data)
+ switch (cur) {
+ case '&&':
+ return left && right
+ case '||':
+ return left || right
+ default:
+ return false
+ }
+ }, false)
+ } catch (e) {
+ return false
+ }
+}