From feff92d13ad03f2d1d5a2ac246a0b88c8d79de2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=A4=E6=9C=88?= Date: Mon, 23 Oct 2023 02:04:22 -0500 Subject: [PATCH 1/8] feat: Pipeline detail add code repo attr (#4215) feat: pipeline detail add code repo attr Signed-off-by: yazhou --- .../Pipelines/Detail/Layout/pipeline.jsx | 19 ++++++++++++++++++- src/utils/devOpsRepos.js | 12 +++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/pages/devops/containers/Pipelines/Detail/Layout/pipeline.jsx b/src/pages/devops/containers/Pipelines/Detail/Layout/pipeline.jsx index 8d8b8894b4f..ffd275d9a43 100644 --- a/src/pages/devops/containers/Pipelines/Detail/Layout/pipeline.jsx +++ b/src/pages/devops/containers/Pipelines/Detail/Layout/pipeline.jsx @@ -32,6 +32,7 @@ import { getPipelineStatus } from 'utils/status' import { trigger } from 'utils/action' +import { getCodeRepoTemplate } from 'utils/devOpsRepos' import './index.scss' @inject('rootStore', 'devopsStore', 'pipelineStore') @@ -256,6 +257,17 @@ export default class PipelineDetailLayout extends React.Component { getAttrs = () => { const { devopsName } = this.props.devopsStore + let repo = {} + if (this.store.detail.isMultiBranch) { + const config = toJS(this.store.pipelineConfig) + const provider = get(config, 'spec.multi_branch_pipeline.source_type') + const source = get( + config, + `spec.multi_branch_pipeline.${provider}_source`, + {} + ) + repo = getCodeRepoTemplate[provider]?.(source) ?? {} + } const syncStatus = get( this.store.pipelineConfig, @@ -275,6 +287,11 @@ export default class PipelineDetailLayout extends React.Component { name: t('KIND_TCAP'), value: kind, }, + { + hide: !this.store.detail.isMultiBranch, + name: t('CODE_REPO'), + value: repo.repo && repo.url ? `${repo.repo}(${repo.url})` : repo.url, + }, { name: t('TASK_STATUS'), value: , @@ -287,7 +304,7 @@ export default class PipelineDetailLayout extends React.Component { name: t('UPDATE_TIME_TCAP'), value: this.getUpTime(), }, - ] + ].filter(i => !i.hide) } handleScanRepository = async () => { diff --git a/src/utils/devOpsRepos.js b/src/utils/devOpsRepos.js index 55cf0f93528..6101c3a20bc 100644 --- a/src/utils/devOpsRepos.js +++ b/src/utils/devOpsRepos.js @@ -1,8 +1,9 @@ +// ------------- pipeline source to code repo obj ----------- + /** * type repo * { provider, url, server, owner, repo } */ - /** * github to repo * example: { @@ -74,6 +75,15 @@ export function getGitSource(data) { } } +export const getCodeRepoTemplate = { + github: getGithubSource, + gitlab: getGitlabSource, + bitbucket_server: getBitbucketSource, + git: getGitSource, +} + +// ------------ code repo obj to pipeline source ----------- + const gitRepositorySpec2BaseSource = (spec, name) => { return { scm_id: name, From bb10df04c556f7a317a621307bc47cbad256d88a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=A4=E6=9C=88?= Date: Mon, 23 Oct 2023 02:16:22 -0500 Subject: [PATCH 2/8] fix: Set disabled when cluster is not ready or not install devops (#4216) Signed-off-by: yazhou --- .../workspaces/containers/DevOps/index.jsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/pages/workspaces/containers/DevOps/index.jsx b/src/pages/workspaces/containers/DevOps/index.jsx index 6ef609a3bef..952884266f5 100644 --- a/src/pages/workspaces/containers/DevOps/index.jsx +++ b/src/pages/workspaces/containers/DevOps/index.jsx @@ -19,7 +19,7 @@ import { Avatar, Status } from 'components/Base' import Banner from 'components/Cards/Banner' import withList, { ListPage } from 'components/HOCs/withList' -import { computed } from 'mobx' +import { computed, toJS } from 'mobx' import React from 'react' import DevOpsStore from 'stores/devops' @@ -84,12 +84,18 @@ export default class DevOps extends React.Component { @computed get clusters() { - return this.workspaceStore.clusters.data.map(item => ({ - label: item.name, - value: item.name, - disabled: !item.isReady, - cluster: item, - })) + const list = this.workspaceStore.clusters.data + .map(item => ({ + label: item.name, + value: item.name, + disabled: !item.isReady || !item.configz?.devops, + cluster: toJS(item), + })) + .sort((a, b) => a.disabled - b.disabled) + if (list[0]) { + this.workspaceStore.cluster = list[0]?.value + } + return list } get clusterProps() { From ab1c1c9e729cccf96383c0ec3545292e1305080a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=A4=E6=9C=88?= Date: Mon, 23 Oct 2023 02:16:29 -0500 Subject: [PATCH 3/8] fix: Fix parameters defined in pipeline not passed to jenkins (#4217) fix: fix parameters defined in pipeline not passed to jenkins Signed-off-by: yazhou --- src/components/Forms/Pipelines/ParamsFormModal/index.jsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/Forms/Pipelines/ParamsFormModal/index.jsx b/src/components/Forms/Pipelines/ParamsFormModal/index.jsx index cb58aa8c6b3..cb9a4a30e30 100644 --- a/src/components/Forms/Pipelines/ParamsFormModal/index.jsx +++ b/src/components/Forms/Pipelines/ParamsFormModal/index.jsx @@ -142,6 +142,10 @@ export default class ParamsFormModal extends React.Component { const { parameters, currentBranch } = this.state this.formRef.current.validate(() => { + if (!isEmpty(formParameters) && formParameters.__branch) { + formParameters.branch = formParameters.__branch + delete formParameters.__branch + } const params = isEmpty(formParameters) ? !isEmpty(parameters) && Array.isArray(parameters) ? parameters.map(item => ({ @@ -171,7 +175,10 @@ export default class ParamsFormModal extends React.Component { label={param.name} desc={param.description} > - + ) case 'text': From af7067dc5a4bb3911e41655ac87b3bcedc23804b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=A4=E6=9C=88?= Date: Mon, 23 Oct 2023 02:16:37 -0500 Subject: [PATCH 4/8] fix: [devops 3.4.1] fix devops pipeline run log (#1772) (#4218) fix: [devops 3.5] fix devops pipeline run log (#1772) * fix: fix devops pipeline run log * fix: update pipeline run log refresh icon * fix: fix devops pipeline run log refresh action * fix: fix devops history card name --------- Signed-off-by: yazhou --- server/proxy.js | 44 +++++++ .../PipelineLogDialog/FullLogs/index.jsx | 7 +- .../Detail/PipelineLogDialog/index.scss | 12 +- .../Pipelines/Detail/TaskStatus/index.jsx | 2 +- src/pages/devops/containers/layout.jsx | 3 +- src/stores/devops/run.js | 122 ++++++++++++++---- src/utils/request.js | 7 +- 7 files changed, 162 insertions(+), 35 deletions(-) diff --git a/server/proxy.js b/server/proxy.js index fa276162dae..edd89af33cb 100644 --- a/server/proxy.js +++ b/server/proxy.js @@ -36,6 +36,50 @@ const k8sResourceProxy = { NEED_OMIT_HEADERS.forEach(key => proxyReq.removeHeader(key)) }, + proxyRes(proxyRes, req, client_res) { + let maxBufferSize = req.headers['x-file-size-limit'] + if (maxBufferSize) { + maxBufferSize = Number(maxBufferSize) + let body = Buffer.alloc(maxBufferSize) + let offset = 0 + let end = false + proxyRes.on('data', chunk => { + if (end) { + return + } + if (offset >= maxBufferSize) { + if (!client_res.getHeader('x-file-size-limit-out')) { + client_res.setHeader('x-file-size-limit-out', 'true') + } + proxyRes.emit('end') + end = true + return + } + chunk.copy(body, offset) + + offset += chunk.length + }) + proxyRes.pipe = function(res) { + proxyRes.on('end', () => { + end = true + const offset1 = Math.min(offset, maxBufferSize) + body = body.slice(0, offset1) + res.writeHead(proxyRes.statusCode, { + ...proxyRes.headers, + 'x-file-size': offset1, + }) + res.end(body) + }) + } + } + let addHeaders = req.headers['x-add-res-header'] + if (addHeaders) { + addHeaders = JSON.parse(addHeaders) + Object.keys(addHeaders).forEach(key => { + proxyRes.headers[key] = addHeaders[key] + }) + } + }, }, } diff --git a/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/FullLogs/index.jsx b/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/FullLogs/index.jsx index 2af9c0d8824..dbd4cc04408 100644 --- a/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/FullLogs/index.jsx +++ b/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/FullLogs/index.jsx @@ -36,9 +36,9 @@ export default class FullLogs extends React.Component { } @action - getPipelineIndexLog() { + getPipelineIndexLog(refresh = false) { const { params } = this.props - this.store.getRunStatusLogs(params) + this.store.getRunStatusLogs(params, refresh) } @computed @@ -84,7 +84,8 @@ export default class FullLogs extends React.Component { } handleRefreshLogs = async () => { - await this.getPipelineIndexLog() + await this.getPipelineIndexLog(true) + await this.handleRealtime() this.scrollToBottom() } diff --git a/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/index.scss b/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/index.scss index ea7bd9695ba..96a231b888c 100644 --- a/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/index.scss +++ b/src/pages/devops/containers/Pipelines/Detail/PipelineLogDialog/index.scss @@ -2,7 +2,8 @@ @import '~scss/mixins'; .container { - display: flex; + display: grid; + grid-template-columns: 215px 1fr; height: 100%; } @@ -17,13 +18,16 @@ } .left { - flex-basis: 215px; height: 500px; overflow: auto; } .right { - flex-grow: 1; + // max-height: calc(100vh - 200px); + overflow-y: auto; + display: grid; + grid-template-rows: auto 1fr; + gap: 12px; } .cutTitle { @@ -71,7 +75,6 @@ .header { height: 32px; - margin-bottom: 12px; display: grid; grid-template-columns: 1fr auto; align-items: center; @@ -93,7 +96,6 @@ .logContainer { width: 100%; - height: 100%; padding: 12px; border-radius: 4px; background-color: #242e42; diff --git a/src/pages/devops/containers/Pipelines/Detail/TaskStatus/index.jsx b/src/pages/devops/containers/Pipelines/Detail/TaskStatus/index.jsx index 290437c276f..80df6baeec1 100644 --- a/src/pages/devops/containers/Pipelines/Detail/TaskStatus/index.jsx +++ b/src/pages/devops/containers/Pipelines/Detail/TaskStatus/index.jsx @@ -256,7 +256,7 @@ export default class TaskStatus extends React.Component { /> -