diff --git a/spug_api/apps/deploy/views.py b/spug_api/apps/deploy/views.py index c4af72d..de163ad 100644 --- a/spug_api/apps/deploy/views.py +++ b/spug_api/apps/deploy/views.py @@ -202,30 +202,45 @@ class RequestDetailView(View): def post_request_ext1(request): form, error = JsonParser( Argument('id', type=int, required=False), + Argument('deploy_id', type=int, help='参数错误'), Argument('name', help='请输入申请标题'), - Argument('repository_id', type=int, help='请选择发布版本'), + Argument('extra', type=list, help='请选择发布版本'), Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'), Argument('type', default='1'), Argument('plan', required=False), Argument('desc', required=False), ).parse(request.body) if error is None: - repository = Repository.objects.filter(pk=form.repository_id).first() - if not repository: - return json_response(error='未找到指定构建版本记录') - form.name = form.name.replace("'", '') - form.status = '0' if repository.deploy.is_audit else '1' - form.version = repository.version - form.spug_version = repository.spug_version - form.deploy_id = repository.deploy_id + deploy = Deploy.objects.get(pk=form.deploy_id) + form.spug_version = Repository.make_spug_version(deploy.id) + if form.extra[0] == 'tag': + if not form.extra[1]: + return json_response(error='请选择要发布的版本') + form.version = form.extra[1] + elif form.extra[0] == 'branch': + if not form.extra[2]: + return json_response(error='请选择要发布的分支及Commit ID') + form.version = f'{form.extra[1]}#{form.extra[2][:6]}' + elif form.extra[0] == 'repository': + if not form.extra[1]: + return json_response(error='请选择要发布的版本') + repository = Repository.objects.get(pk=form.extra[1]) + form.repository_id = repository.id + form.version = repository.version + form.spug_version = repository.spug_version + else: + return json_response(error='参数错误') + + form.extra = json.dumps(form.extra) + form.status = '0' if deploy.is_audit else '1' form.host_ids = json.dumps(sorted(form.host_ids)) if form.id: req = DeployRequest.objects.get(pk=form.id) - is_required_notify = repository.deploy.is_audit and req.status == '-1' + is_required_notify = deploy.is_audit and req.status == '-1' DeployRequest.objects.filter(pk=form.id).update(created_by=request.user, reason=None, **form) else: req = DeployRequest.objects.create(created_by=request.user, **form) - is_required_notify = repository.deploy.is_audit + is_required_notify = deploy.is_audit if is_required_notify: Thread(target=Helper.send_deploy_notify, args=(req, 'approve_req')).start() return json_response(error=error) diff --git a/spug_web/src/pages/deploy/repository/Form.js b/spug_web/src/pages/deploy/repository/Form.js index 0671d0e..bf34e36 100644 --- a/spug_web/src/pages/deploy/repository/Form.js +++ b/spug_web/src/pages/deploy/repository/Form.js @@ -42,6 +42,7 @@ export default observer(function () { setExtra2(commit) } else { setExtra1(lds.get(Object.keys(tags), 0)) + setExtra2(null) } } diff --git a/spug_web/src/pages/deploy/request/Ext1Form.js b/spug_web/src/pages/deploy/request/Ext1Form.js index 8c2eab4..740ab10 100644 --- a/spug_web/src/pages/deploy/request/Ext1Form.js +++ b/spug_web/src/pages/deploy/request/Ext1Form.js @@ -6,6 +6,7 @@ import React, { useState, useEffect } from 'react'; import { observer } from 'mobx-react'; import { Modal, Form, Input, Select, DatePicker, Button, message } from 'antd'; +import { LoadingOutlined, SyncOutlined } from '@ant-design/icons'; import HostSelector from './HostSelector'; import hostStore from 'pages/host/store'; import { http, history } from 'libs'; @@ -30,18 +31,38 @@ export default observer(function () { const [form] = Form.useForm(); const [visible, setVisible] = useState(false); const [loading, setLoading] = useState(false); - const [versions, setVersions] = useState([]); + const [repositories, setRepositories] = useState([]); const [host_ids, setHostIds] = useState([]); const [plan, setPlan] = useState(store.record.plan); + const [fetching, setFetching] = useState(false); + const [git_type, setGitType] = useState(); + const [extra, setExtra] = useState([]); + const [extra1, setExtra1] = useState(); + const [extra2, setExtra2] = useState(); + const [versions, setVersions] = useState({}); useEffect(() => { - const {deploy_id, app_host_ids, host_ids} = store.record; + const {app_host_ids, host_ids} = store.record; setHostIds(lds.clone(host_ids || app_host_ids)); - http.get('/api/repository/', {params: {deploy_id}}) - .then(res => setVersions(res)) if (!hostStore.records || hostStore.records.length === 0) hostStore.fetchRecords() + fetchVersions() + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) + function fetchVersions() { + setFetching(true); + const deploy_id = store.record.deploy_id + const p1 = http.get(`/api/app/deploy/${deploy_id}/versions/`, {timeout: 120000}) + const p2 = http.get('/api/repository/', {params: {deploy_id}}) + Promise.all([p1, p2]) + .then(([res1, res2]) => { + if (!versions.branches) _initial(res1, res2) + setVersions(res1) + setRepositories(res2) + }) + .finally(() => setFetching(false)) + } + function handleSubmit() { if (host_ids.length === 0) { return message.error('请至少选择一个要发布的主机') @@ -49,9 +70,10 @@ export default observer(function () { setLoading(true); const formData = form.getFieldsValue(); formData['id'] = store.record.id; + formData['deploy_id'] = store.record.deploy_id; formData['host_ids'] = host_ids; formData['type'] = store.record.type; - formData['deploy_id'] = store.record.deploy_id; + formData['extra'] = [git_type, extra1, extra2]; if (plan) formData.plan = plan.format('YYYY-MM-DD HH:mm:00'); http.post('/api/deploy/request/ext1/', formData) .then(res => { @@ -61,32 +83,148 @@ export default observer(function () { }, () => setLoading(false)) } + function _setDefault(type, new_extra, new_versions, new_repositories) { + const now_extra = new_extra || extra; + const now_versions = new_versions || versions; + const now_repositories = new_repositories || repositories; + const {branches, tags} = now_versions; + if (type === 'branch') { + let [branch, commit] = [now_extra[1], null]; + if (branches[branch]) { + commit = lds.get(branches[branch], '0.id') + } else { + branch = lds.get(Object.keys(branches), 0) + commit = lds.get(branches, [branch, 0, 'id']) + } + setExtra1(branch) + setExtra2(commit) + } else if (type === 'tag') { + setExtra1(lds.get(Object.keys(tags), 0)) + setExtra2(null) + } else { + setExtra1(lds.get(now_repositories, '0.id')) + setExtra2(null) + } + } + + function _initial(versions, repositories) { + const {branches, tags} = versions; + if (branches && tags) { + for (let item of store.records) { + if (item.extra && item.deploy_id === store.record.deploy_id) { + const type = item.extra[0]; + setExtra(item.extra); + setGitType(type); + return _setDefault(type, item.extra, versions, repositories); + } + } + setGitType('branch'); + const branch = lds.get(Object.keys(branches), 0); + const commit = lds.get(branches, [branch, 0, 'id']) + setExtra1(branch); + setExtra2(commit) + } + } + + function switchType(v) { + setGitType(v); + _setDefault(v) + } + + function switchExtra1(v) { + setExtra1(v) + if (git_type === 'branch') { + setExtra2(lds.get(versions.branches[v], '0.id')) + } + } + const {app_host_ids, type, rb_id} = store.record; + const {branches, tags} = versions; return ( store.ext1Visible = false} confirmLoading={loading} onOk={handleSubmit}> -
+ - - + + 根据网络情况,首次刷新可能会很慢,请耐心等待。 + clone 失败? + }> + + + + + + + + {fetching ? : + + } + + {git_type === 'branch' && ( + + + + )} {host_ids.length > 0 && `已选择 ${host_ids.length} 台(可选${app_host_ids.length})`} diff --git a/spug_web/src/pages/deploy/request/Table.js b/spug_web/src/pages/deploy/request/Table.js index d33c3c6..1b6d1c5 100644 --- a/spug_web/src/pages/deploy/request/Table.js +++ b/spug_web/src/pages/deploy/request/Table.js @@ -5,7 +5,7 @@ */ import React from 'react'; import { observer } from 'mobx-react'; -import { BranchesOutlined, BuildOutlined, TagOutlined, PlusOutlined } from '@ant-design/icons'; +import { BranchesOutlined, BuildOutlined, TagOutlined, PlusOutlined, TagsOutlined } from '@ant-design/icons'; import { Radio, Modal, Popover, Tag, Popconfirm, Tooltip, message } from 'antd'; import { http, hasPermission } from 'libs'; import { Action, AuthButton, TableCard } from 'components'; @@ -33,17 +33,18 @@ function ComTable() { title: '版本', render: info => { if (info['app_extend'] === '1') { - const [ext1] = info.rep_extra; - return ( - - {ext1 === 'branch' ? : } {info.version} - - ) + const [ext1] = info.extra || info.rep_extra; + switch (ext1) { + case 'branch': + return
{info.version}
+ case 'tag': + return
{info.version}
+ default: + return
{info.version}
+ } } else { return ( - - {info.version} - +
{info.version}
) } }