fix issue

pull/410/head
vapao 2021-08-18 00:04:15 +08:00
parent 1897739512
commit 0dd2ef3df8
4 changed files with 194 additions and 39 deletions

View File

@ -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)

View File

@ -42,6 +42,7 @@ export default observer(function () {
setExtra2(commit)
} else {
setExtra1(lds.get(Object.keys(tags), 0))
setExtra2(null)
}
}

View File

@ -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 (
<Modal
visible
width={700}
width={800}
maskClosable={false}
title={`${store.record.id ? '编辑' : '新建'}发布申请`}
onCancel={() => store.ext1Visible = false}
confirmLoading={loading}
onOk={handleSubmit}>
<Form form={form} initialValues={store.record} labelCol={{span: 6}} wrapperCol={{span: 16}}>
<Form form={form} initialValues={store.record} labelCol={{span: 5}} wrapperCol={{span: 17}}>
<Form.Item required name="name" label="申请标题">
<Input placeholder="请输入申请标题"/>
</Form.Item>
<Form.Item required name="repository_id" label={type === '2' ? '回滚版本' : '发布版本'}>
<Select placeholder="请选择" notFoundContent={<NoVersions/>}>
{versions.map(item => (
<Select.Option key={item.id} value={item.id} disabled={type === '2' && item.id >= rb_id}>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<span>{item.remarks ? `${item.version} (${item.remarks})` : item.version}</span>
<span style={{color: '#999', fontSize: 12}}>构建于 {moment(item.created_at).fromNow()}</span>
</div>
</Select.Option>
))}
</Select>
<Form.Item required label="选择分支/标签/版本" style={{marginBottom: 12}} extra={<span>
根据网络情况首次刷新可能会很慢请耐心等待
<a target="_blank" rel="noopener noreferrer"
href="https://spug.cc/docs/install-error/#%E6%96%B0%E5%BB%BA%E5%B8%B8%E8%A7%84%E5%8F%91%E5%B8%83%E7%94%B3%E8%AF%B7-git-clone-%E9%94%99%E8%AF%AF">clone 失败</a>
</span>}>
<Form.Item style={{display: 'inline-block', marginBottom: 0, width: '450px'}}>
<Input.Group compact>
<Select value={git_type} onChange={switchType} style={{width: 100}}>
<Select.Option value="branch">Branch</Select.Option>
<Select.Option value="tag">Tag</Select.Option>
<Select.Option value="repository">构建仓库</Select.Option>
</Select>
<Select
showSearch
style={{width: 350}}
value={extra1}
placeholder="请稍等"
onChange={switchExtra1}
notFoundContent={git_type === 'repository' ? <NoVersions/> : undefined}
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}>
{git_type === 'branch' ? (
Object.keys(branches || {}).map(b => <Select.Option key={b} value={b}>{b}</Select.Option>)
) : git_type === 'tag' ? (
Object.entries(tags || {}).map(([tag, info]) => (
<Select.Option key={tag} value={tag}>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<span style={{
width: 200,
overflow: 'hidden',
textOverflow: 'ellipsis'
}}>{`${tag} ${info.author} ${info.message}`}</span>
<span style={{color: '#999', fontSize: 12}}>{info['date']} </span>
</div>
</Select.Option>
))
) : (
repositories.map(item => (
<Select.Option key={item.id} value={item.id} disabled={type === '2' && item.id >= rb_id}>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<span>{item.remarks ? `${item.version} (${item.remarks})` : item.version}</span>
<span style={{color: '#999', fontSize: 12}}>构建于 {moment(item.created_at).fromNow()}</span>
</div>
</Select.Option>
))
)}
</Select>
</Input.Group>
</Form.Item>
<Form.Item style={{display: 'inline-block', width: 82, textAlign: 'center', marginBottom: 0}}>
{fetching ? <LoadingOutlined style={{fontSize: 18, color: '#1890ff'}}/> :
<Button type="link" icon={<SyncOutlined/>} disabled={fetching} onClick={fetchVersions}>刷新</Button>
}
</Form.Item>
</Form.Item>
{git_type === 'branch' && (
<Form.Item required label="选择Commit ID">
<Select value={extra2} placeholder="请选择" onChange={v => setExtra2(v)}>
{extra1 && branches ? branches[extra1].map(item => (
<Select.Option key={item.id}>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<span style={{
width: 400,
overflow: 'hidden',
textOverflow: 'ellipsis'
}}>{item.id.substr(0, 6)} {item['author']} {item['message']}</span>
<span style={{color: '#999', fontSize: 12}}>{item['date']} </span>
</div>
</Select.Option>
)) : null}
</Select>
</Form.Item>
)}
<Form.Item required label="目标主机" tooltip="可以通过创建多个发布申请单,选择主机分批发布。">
{host_ids.length > 0 && `已选择 ${host_ids.length} 台(可选${app_host_ids.length}`}
<Button type="link" onClick={() => setVisible(true)}>选择主机</Button>

View File

@ -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 (
<React.Fragment>
{ext1 === 'branch' ? <BranchesOutlined/> : <TagOutlined/>} {info.version}
</React.Fragment>
)
const [ext1] = info.extra || info.rep_extra;
switch (ext1) {
case 'branch':
return <div><BranchesOutlined/> {info.version}</div>
case 'tag':
return <div><TagOutlined/> {info.version}</div>
default:
return <div><TagsOutlined/> {info.version}</div>
}
} else {
return (
<React.Fragment>
<BuildOutlined/> {info.version}
</React.Fragment>
<div><BuildOutlined/> {info.version}</div>
)
}
}