mirror of
https://github.com/opsre/LiteOps.git
synced 2026-03-16 02:50:49 +08:00
添加自定义构建参数功能
This commit is contained in:
@@ -225,6 +225,18 @@ class BuildTask(models.Model):
|
|||||||
# 构建阶段
|
# 构建阶段
|
||||||
stages = models.JSONField(default=list, verbose_name='构建阶段')
|
stages = models.JSONField(default=list, verbose_name='构建阶段')
|
||||||
|
|
||||||
|
# 构建参数配置
|
||||||
|
parameters = models.JSONField(default=list, verbose_name='构建参数配置', help_text='''
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "MY_SERVICES",
|
||||||
|
"description": "选择要部署的服务",
|
||||||
|
"choices": ["user-service", "order-service", "payment-service"],
|
||||||
|
"default_values": ["user-service"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
''')
|
||||||
|
|
||||||
# 外部脚本库配置
|
# 外部脚本库配置
|
||||||
use_external_script = models.BooleanField(default=False, verbose_name='使用外部脚本库')
|
use_external_script = models.BooleanField(default=False, verbose_name='使用外部脚本库')
|
||||||
external_script_config = models.JSONField(default=dict, verbose_name='外部脚本库配置', help_text='''
|
external_script_config = models.JSONField(default=dict, verbose_name='外部脚本库配置', help_text='''
|
||||||
@@ -287,6 +299,12 @@ class BuildHistory(models.Model):
|
|||||||
requirement = models.TextField(null=True, blank=True, verbose_name='构建需求描述')
|
requirement = models.TextField(null=True, blank=True, verbose_name='构建需求描述')
|
||||||
build_log = models.TextField(null=True, blank=True, verbose_name='构建日志')
|
build_log = models.TextField(null=True, blank=True, verbose_name='构建日志')
|
||||||
stages = models.JSONField(default=list, verbose_name='构建阶段')
|
stages = models.JSONField(default=list, verbose_name='构建阶段')
|
||||||
|
parameter_values = models.JSONField(default=dict, verbose_name='构建参数值', help_text='''
|
||||||
|
{
|
||||||
|
"MY_SERVICES": ["user-service", "order-service"],
|
||||||
|
"FEATURE_FLAGS": ["enable-cache"]
|
||||||
|
}
|
||||||
|
''')
|
||||||
build_time = models.JSONField(default=dict, verbose_name='构建时间信息', help_text='''
|
build_time = models.JSONField(default=dict, verbose_name='构建时间信息', help_text='''
|
||||||
{
|
{
|
||||||
"total_duration": "300", # 总耗时(秒)
|
"total_duration": "300", # 总耗时(秒)
|
||||||
|
|||||||
@@ -462,11 +462,19 @@ class Builder:
|
|||||||
'LANG': 'POSIX',
|
'LANG': 'POSIX',
|
||||||
}
|
}
|
||||||
|
|
||||||
combined_env = {**os.environ, **system_variables}
|
# 添加自定义参数变量
|
||||||
|
custom_parameters = {}
|
||||||
|
if self.history.parameter_values:
|
||||||
|
for param_name, selected_values in self.history.parameter_values.items():
|
||||||
|
custom_parameters[param_name] = ','.join(selected_values)
|
||||||
|
self.send_log(f"设置参数变量: {param_name}={custom_parameters[param_name]}", "Parameters")
|
||||||
|
|
||||||
|
combined_env = {**os.environ, **system_variables, **custom_parameters}
|
||||||
stage_executor.env = combined_env
|
stage_executor.env = combined_env
|
||||||
|
|
||||||
# 保存系统变量到文件
|
# 保存系统变量和自定义参数到文件
|
||||||
stage_executor._save_variables_to_file(system_variables)
|
all_variables = {**system_variables, **custom_parameters}
|
||||||
|
stage_executor._save_variables_to_file(all_variables)
|
||||||
|
|
||||||
# 执行构建阶段
|
# 执行构建阶段
|
||||||
success = self.execute_stages(stage_executor)
|
success = self.execute_stages(stage_executor)
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ class BuildTaskView(View):
|
|||||||
'name': task.git_token.name
|
'name': task.git_token.name
|
||||||
} if task.git_token else None,
|
} if task.git_token else None,
|
||||||
'stages': task.stages,
|
'stages': task.stages,
|
||||||
|
'parameters': task.parameters,
|
||||||
'notification_channels': task.notification_channels,
|
'notification_channels': task.notification_channels,
|
||||||
'notification_robots': notification_robots,
|
'notification_robots': notification_robots,
|
||||||
# 外部脚本库配置
|
# 外部脚本库配置
|
||||||
@@ -288,7 +289,8 @@ class BuildTaskView(View):
|
|||||||
'description': task.description,
|
'description': task.description,
|
||||||
'branch': task.branch,
|
'branch': task.branch,
|
||||||
'status': task.status,
|
'status': task.status,
|
||||||
'building_status': task.building_status, # 添加构建状态字段
|
'building_status': task.building_status,
|
||||||
|
'parameters': task.parameters,
|
||||||
'version': task.version,
|
'version': task.version,
|
||||||
'last_build_number': task.last_build_number,
|
'last_build_number': task.last_build_number,
|
||||||
'total_builds': task.total_builds,
|
'total_builds': task.total_builds,
|
||||||
@@ -334,6 +336,7 @@ class BuildTaskView(View):
|
|||||||
branch = data.get('branch', 'main')
|
branch = data.get('branch', 'main')
|
||||||
git_token_id = data.get('git_token_id')
|
git_token_id = data.get('git_token_id')
|
||||||
stages = data.get('stages', [])
|
stages = data.get('stages', [])
|
||||||
|
parameters = data.get('parameters', [])
|
||||||
notification_channels = data.get('notification_channels', [])
|
notification_channels = data.get('notification_channels', [])
|
||||||
|
|
||||||
# 外部脚本库配置
|
# 外部脚本库配置
|
||||||
@@ -379,6 +382,23 @@ class BuildTaskView(View):
|
|||||||
'message': '任务名称、项目和环境不能为空'
|
'message': '任务名称、项目和环境不能为空'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# 验证参数配置格式
|
||||||
|
if parameters:
|
||||||
|
import re
|
||||||
|
for param in parameters:
|
||||||
|
if not param.get('name') or not param.get('choices'):
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 400,
|
||||||
|
'message': '参数名称和可选值不能为空'
|
||||||
|
})
|
||||||
|
|
||||||
|
# 验证参数名格式(大写字母、数字、下划线)
|
||||||
|
if not re.match(r'^[A-Z_][A-Z0-9_]*$', param['name']):
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 400,
|
||||||
|
'message': f'参数名"{param["name"]}"格式不正确,只能包含大写字母、数字和下划线,且必须以字母或下划线开头'
|
||||||
|
})
|
||||||
|
|
||||||
# 验证通知机器人是否存在
|
# 验证通知机器人是否存在
|
||||||
if notification_channels:
|
if notification_channels:
|
||||||
existing_robots = set(NotificationRobot.objects.filter(
|
existing_robots = set(NotificationRobot.objects.filter(
|
||||||
@@ -431,6 +451,7 @@ class BuildTaskView(View):
|
|||||||
branch=branch,
|
branch=branch,
|
||||||
git_token=git_token,
|
git_token=git_token,
|
||||||
stages=stages,
|
stages=stages,
|
||||||
|
parameters=parameters,
|
||||||
notification_channels=notification_channels,
|
notification_channels=notification_channels,
|
||||||
use_external_script=use_external_script,
|
use_external_script=use_external_script,
|
||||||
external_script_config=external_script_config,
|
external_script_config=external_script_config,
|
||||||
@@ -473,6 +494,7 @@ class BuildTaskView(View):
|
|||||||
branch = data.get('branch')
|
branch = data.get('branch')
|
||||||
git_token_id = data.get('git_token_id')
|
git_token_id = data.get('git_token_id')
|
||||||
stages = data.get('stages')
|
stages = data.get('stages')
|
||||||
|
parameters = data.get('parameters')
|
||||||
notification_channels = data.get('notification_channels')
|
notification_channels = data.get('notification_channels')
|
||||||
status = data.get('status')
|
status = data.get('status')
|
||||||
|
|
||||||
@@ -512,6 +534,23 @@ class BuildTaskView(View):
|
|||||||
else:
|
else:
|
||||||
external_script_config = {}
|
external_script_config = {}
|
||||||
|
|
||||||
|
# 验证参数配置格式
|
||||||
|
if parameters:
|
||||||
|
import re
|
||||||
|
for param in parameters:
|
||||||
|
if not param.get('name') or not param.get('choices'):
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 400,
|
||||||
|
'message': '参数名称和可选值不能为空'
|
||||||
|
})
|
||||||
|
|
||||||
|
# 验证参数名格式(大写字母、数字、下划线)
|
||||||
|
if not re.match(r'^[A-Z_][A-Z0-9_]*$', param['name']):
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 400,
|
||||||
|
'message': f'参数名"{param["name"]}"格式不正确,只能包含大写字母、数字和下划线,且必须以字母或下划线开头'
|
||||||
|
})
|
||||||
|
|
||||||
if not task_id:
|
if not task_id:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'code': 400,
|
'code': 400,
|
||||||
@@ -617,6 +656,8 @@ class BuildTaskView(View):
|
|||||||
task.branch = branch
|
task.branch = branch
|
||||||
if 'stages' in data:
|
if 'stages' in data:
|
||||||
task.stages = stages
|
task.stages = stages
|
||||||
|
if 'parameters' in data:
|
||||||
|
task.parameters = parameters
|
||||||
if 'notification_channels' in data:
|
if 'notification_channels' in data:
|
||||||
# 验证通知机器人是否存在
|
# 验证通知机器人是否存在
|
||||||
existing_robots = set(NotificationRobot.objects.filter(
|
existing_robots = set(NotificationRobot.objects.filter(
|
||||||
@@ -710,6 +751,7 @@ class BuildExecuteView(View):
|
|||||||
commit_id = data.get('commit_id')
|
commit_id = data.get('commit_id')
|
||||||
version = data.get('version')
|
version = data.get('version')
|
||||||
requirement = data.get('requirement')
|
requirement = data.get('requirement')
|
||||||
|
parameter_values = data.get('parameter_values', {})
|
||||||
|
|
||||||
if not task_id:
|
if not task_id:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
@@ -785,6 +827,23 @@ class BuildExecuteView(View):
|
|||||||
'message': '构建需求描述不能为空'
|
'message': '构建需求描述不能为空'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# 验证参数值是否合法
|
||||||
|
if task.parameters and parameter_values:
|
||||||
|
task_parameters = {p['name']: p['choices'] for p in task.parameters}
|
||||||
|
for param_name, selected_values in parameter_values.items():
|
||||||
|
if param_name not in task_parameters:
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 400,
|
||||||
|
'message': f'未定义的参数: {param_name}'
|
||||||
|
})
|
||||||
|
|
||||||
|
for value in selected_values:
|
||||||
|
if value not in task_parameters[param_name]:
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 400,
|
||||||
|
'message': f'参数{param_name}的值"{value}"不在可选范围内'
|
||||||
|
})
|
||||||
|
|
||||||
# 检查任务的构建状态
|
# 检查任务的构建状态
|
||||||
if task.building_status == 'building':
|
if task.building_status == 'building':
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
@@ -824,6 +883,7 @@ class BuildExecuteView(View):
|
|||||||
version=version if version else None, # 对于预发布和生产环境,使用传入的版本号
|
version=version if version else None, # 对于预发布和生产环境,使用传入的版本号
|
||||||
status='pending', # 初始状态为等待中
|
status='pending', # 初始状态为等待中
|
||||||
requirement=requirement,
|
requirement=requirement,
|
||||||
|
parameter_values=parameter_values,
|
||||||
operator=User.objects.get(user_id=request.user_id) # 记录构建人
|
operator=User.objects.get(user_id=request.user_id) # 记录构建人
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,84 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 构建参数配置 -->
|
||||||
|
<a-divider>构建参数</a-divider>
|
||||||
|
<div class="parameters-list">
|
||||||
|
<div v-for="(param, index) in formState.parameters" :key="index" class="parameter-item">
|
||||||
|
<div class="parameter-header">
|
||||||
|
<span class="parameter-number">
|
||||||
|
<TagOutlined /> 参数 {{ index + 1 }}
|
||||||
|
</span>
|
||||||
|
<a-space>
|
||||||
|
<a-tooltip title="删除">
|
||||||
|
<a-button
|
||||||
|
v-if="formState.parameters.length > 0"
|
||||||
|
type="text"
|
||||||
|
danger
|
||||||
|
@click="removeParameter(index)"
|
||||||
|
>
|
||||||
|
<DeleteOutlined />
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item
|
||||||
|
label="参数名称"
|
||||||
|
:name="['parameters', index, 'name']"
|
||||||
|
:rules="[
|
||||||
|
{ required: true, message: '请输入参数名称' },
|
||||||
|
{ pattern: /^[A-Z_][A-Z0-9_]*$/, message: '参数名只能包含大写字母、数字和下划线,且必须以字母或下划线开头' }
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input v-model:value="param.name" placeholder="例如:MY_SERVICES">
|
||||||
|
<template #prefix>
|
||||||
|
<KeyOutlined />
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
<div class="form-item-help">参数名只能包含大写字母、数字和下划线</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item label="参数描述">
|
||||||
|
<a-input v-model:value="param.description" placeholder="参数用途说明" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item label="默认值">
|
||||||
|
<a-input v-model:value="param.defaultValuesText" placeholder="多个值用逗号分隔" @blur="updateDefaultValues(param, index)" />
|
||||||
|
<div class="form-item-help">多个默认值用英文逗号分隔</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-form-item
|
||||||
|
label="可选值"
|
||||||
|
:name="['parameters', index, 'choicesText']"
|
||||||
|
:rules="[{ required: true, message: '请输入可选值' }]"
|
||||||
|
>
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="param.choicesText"
|
||||||
|
placeholder="每行一个选项值,例如: user-service payment-service"
|
||||||
|
:rows="3"
|
||||||
|
@blur="updateChoices(param, index)"
|
||||||
|
/>
|
||||||
|
<div class="form-item-help">每行输入一个选项值</div>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="parameter-actions">
|
||||||
|
<a-button type="dashed" block @click="addParameter">
|
||||||
|
<PlusOutlined /> 添加构建参数
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-divider>构建阶段</a-divider>
|
||||||
<div class="stages-list">
|
<div class="stages-list">
|
||||||
<div v-for="(stage, index) in formState.stages" :key="index" class="stage-item">
|
<div v-for="(stage, index) in formState.stages" :key="index" class="stage-item">
|
||||||
<div class="stage-header">
|
<div class="stage-header">
|
||||||
@@ -404,6 +482,7 @@ const formState = reactive({
|
|||||||
script: '',
|
script: '',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
parameters: [],
|
||||||
notification_channels: [],
|
notification_channels: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -509,6 +588,51 @@ const removeStage = (index) => {
|
|||||||
formState.stages.splice(index, 1);
|
formState.stages.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 添加构建参数
|
||||||
|
const addParameter = () => {
|
||||||
|
formState.parameters.push({
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
choices: [],
|
||||||
|
choicesText: '',
|
||||||
|
choiceOptions: [],
|
||||||
|
default_values: [],
|
||||||
|
defaultValuesText: '',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeParameter = (index) => {
|
||||||
|
formState.parameters.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新选项
|
||||||
|
const updateChoices = (param, index) => {
|
||||||
|
if (param.choicesText) {
|
||||||
|
const choices = param.choicesText.split('\n').filter(line => line.trim()).map(line => line.trim());
|
||||||
|
param.choices = choices;
|
||||||
|
param.choiceOptions = choices.map(choice => ({
|
||||||
|
label: choice,
|
||||||
|
value: choice
|
||||||
|
}));
|
||||||
|
|
||||||
|
param.default_values = param.default_values.filter(value => choices.includes(value));
|
||||||
|
} else {
|
||||||
|
param.choices = [];
|
||||||
|
param.choiceOptions = [];
|
||||||
|
param.default_values = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新默认值
|
||||||
|
const updateDefaultValues = (param, index) => {
|
||||||
|
if (param.defaultValuesText) {
|
||||||
|
const values = param.defaultValuesText.split(',').filter(val => val.trim()).map(val => val.trim());
|
||||||
|
param.default_values = values;
|
||||||
|
} else {
|
||||||
|
param.default_values = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 处理返回
|
// 处理返回
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
router.back();
|
router.back();
|
||||||
@@ -526,6 +650,14 @@ const handleSubmit = async () => {
|
|||||||
// 构建提交数据
|
// 构建提交数据
|
||||||
const submitData = { ...formState };
|
const submitData = { ...formState };
|
||||||
|
|
||||||
|
// 处理参数数据
|
||||||
|
submitData.parameters = formState.parameters.map(param => ({
|
||||||
|
name: param.name,
|
||||||
|
description: param.description,
|
||||||
|
choices: param.choices,
|
||||||
|
default_values: param.default_values
|
||||||
|
}));
|
||||||
|
|
||||||
if (!submitData.use_external_script) {
|
if (!submitData.use_external_script) {
|
||||||
submitData.external_script_repo_url = '';
|
submitData.external_script_repo_url = '';
|
||||||
submitData.external_script_directory = '';
|
submitData.external_script_directory = '';
|
||||||
@@ -589,6 +721,25 @@ const loadTaskDetail = async (taskId) => {
|
|||||||
script: '',
|
script: '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载参数配置
|
||||||
|
const parameters = response.data.data.parameters || [];
|
||||||
|
formState.parameters = parameters.map(param => {
|
||||||
|
const choicesText = (param.choices || []).join('\n');
|
||||||
|
const defaultValuesText = (param.default_values || []).join(',');
|
||||||
|
return {
|
||||||
|
name: param.name || '',
|
||||||
|
description: param.description || '',
|
||||||
|
choices: param.choices || [],
|
||||||
|
choicesText: choicesText,
|
||||||
|
choiceOptions: (param.choices || []).map(choice => ({
|
||||||
|
label: choice,
|
||||||
|
value: choice
|
||||||
|
})),
|
||||||
|
default_values: param.default_values || [],
|
||||||
|
defaultValuesText: defaultValuesText,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
formState.notification_channels = response.data.data.notification_channels || [];
|
formState.notification_channels = response.data.data.notification_channels || [];
|
||||||
|
|
||||||
@@ -790,6 +941,38 @@ onMounted(async () => {
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.parameters-list {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameter-item {
|
||||||
|
padding: 16px;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameter-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameter-number {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameter-actions {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.form-footer {
|
.form-footer {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -362,6 +362,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 构建参数选择 -->
|
||||||
|
<div v-if="selectedTask?.parameters?.length > 0" class="build-parameters">
|
||||||
|
<a-divider>构建参数</a-divider>
|
||||||
|
|
||||||
|
<div v-for="param in selectedTask.parameters" :key="param.name" class="parameter-group">
|
||||||
|
<a-form-item :label="param.name">
|
||||||
|
<a-checkbox-group
|
||||||
|
v-model:value="buildForm.parameterValues[param.name]"
|
||||||
|
:options="param.choiceOptions"
|
||||||
|
/>
|
||||||
|
<div class="parameter-help" v-if="param.description">{{ param.description }}</div>
|
||||||
|
</a-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<a-form-item label="构建需求描述" required>
|
<a-form-item label="构建需求描述" required>
|
||||||
<a-textarea
|
<a-textarea
|
||||||
v-model:value="buildForm.requirement"
|
v-model:value="buildForm.requirement"
|
||||||
@@ -429,6 +444,7 @@ const buildForm = reactive({
|
|||||||
commit_id: '',
|
commit_id: '',
|
||||||
requirement: '',
|
requirement: '',
|
||||||
version: '',
|
version: '',
|
||||||
|
parameterValues: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
// SSE相关状态
|
// SSE相关状态
|
||||||
@@ -706,6 +722,21 @@ const handleBuild = async (record) => {
|
|||||||
buildForm.commit_id = '';
|
buildForm.commit_id = '';
|
||||||
buildForm.requirement = '';
|
buildForm.requirement = '';
|
||||||
buildForm.version = '';
|
buildForm.version = '';
|
||||||
|
buildForm.parameterValues = {};
|
||||||
|
|
||||||
|
// 初始化参数默认值
|
||||||
|
if (record.parameters && record.parameters.length > 0) {
|
||||||
|
record.parameters.forEach(param => {
|
||||||
|
// 处理参数选项
|
||||||
|
param.choiceOptions = (param.choices || []).map(choice => ({
|
||||||
|
label: choice,
|
||||||
|
value: choice
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
buildForm.parameterValues[param.name] = [...(param.default_values || [])];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 显示构建对话框
|
// 显示构建对话框
|
||||||
buildModalVisible.value = true;
|
buildModalVisible.value = true;
|
||||||
@@ -1213,7 +1244,8 @@ const confirmBuild = async () => {
|
|||||||
// 构建请求参数
|
// 构建请求参数
|
||||||
const requestData = {
|
const requestData = {
|
||||||
task_id: selectedTask.value.task_id,
|
task_id: selectedTask.value.task_id,
|
||||||
requirement: buildForm.requirement
|
requirement: buildForm.requirement,
|
||||||
|
parameter_values: buildForm.parameterValues
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isDevOrTestEnv.value) {
|
if (isDevOrTestEnv.value) {
|
||||||
@@ -1326,14 +1358,6 @@ const isStagingOrProdEnv = computed(() => {
|
|||||||
|
|
||||||
// 构建对话框标题
|
// 构建对话框标题
|
||||||
const buildModalTitle = computed(() => {
|
const buildModalTitle = computed(() => {
|
||||||
if (!selectedTask.value) return '构建配置';
|
|
||||||
|
|
||||||
const envType = selectedTask.value.environment?.type;
|
|
||||||
if (envType === 'development') return '开发环境构建配置';
|
|
||||||
if (envType === 'testing') return '测试环境构建配置';
|
|
||||||
if (envType === 'staging') return '预发布环境构建配置';
|
|
||||||
if (envType === 'production') return '生产环境构建配置';
|
|
||||||
|
|
||||||
return '构建配置';
|
return '构建配置';
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1698,4 +1722,18 @@ const handleViewBuildDetail = (record) => {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.build-parameters {
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameter-group {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameter-help {
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user