Semaphore UI Survey 变量完整实战指南:在 Task 模板中配置必填、枚举、默认值并验证运行链路

发布时间:2026/9/22 18:51:37
Semaphore UI Survey 变量完整实战指南:在 Task 模板中配置必填、枚举、默认值并验证运行链路 后端DevOps任务调度认证鉴权【免费下载链接】semaphoreModern UI and powerful API for Ansible, Terraform/OpenTofu/Terragrunt, PowerShell and other DevOps tools.项目地址https://gitcode.com/gh_mirrors/se/semaphore点击查看免费下载本指南以 Semaphore UI 仓库中的功能验收用例 TC-022 Survey variables: required, enum, default 为核心讲解如何在任务模板Task Template上定义 Survey 变量覆盖 String / Integer / Enum / Text / Select / Secret 六种类型、必填校验、枚举约束与默认值预填并结合后端模型、前端表单与 LocalExecutor 源码剖析从启动对话框提交到任务日志输出的完整运行链路。读完本文你将能独立完成 Survey 变量的配置、启动验证、命令行注入与结果核对并理解其底层实现原理。1. 背景什么是 Survey 变量为什么需要它Semaphore UI 的任务模板Template除了内置 playbook、仓库、库存等字段外还允许定义一组动态输入变量——即 Survey 变量。这些变量在用户点击模板的Run按钮时以表单控件的形式出现在启动对话框中用户填写或选择的值会被传入底层任务进程供 Ansible、Terraform/OpenTofu/Terragrunt、Bash、PowerShell、Python 等应用消费。它解决的核心问题是同一个模板在不同运行场景下需要不同的参数值但又不想为每种参数组合创建多个模板。例如一个部署服务的模板可以通过 Survey 变量让每次运行指定env环境、replicas副本数和feature_name特性开关运行前在 UI 中直接填写即可无需改动模板本身。TC-022 正是针对这一能力设计的端到端验收用例覆盖三个关键约束维度required必填变量未填写时表单应阻止提交并给出内联错误提示enum枚举变量只能从预定义候选中选择默认值必须属于枚举集合default默认值在打开启动对话框时自动预填减少重复输入。2. 测试用例全景TC-022 的目标、前置条件与测试数据2.1 用例元信息FieldValue用例 IDTC-022所属领域AreaTask Templates任务模板优先级PriorityHigh类型TypeFunctional Negative功能 负向可自动化AutomatableYes用例编号在 test/test-cases/README.md 的索引表中登记为第 22 项TC-022Templates 领域属于完整的 30 项手动 QA 用例集的一部分。2.2 Objective目标在模板上定义的 Survey 变量必须满足以下四点在启动对话框中以正确的控件呈现枚举 → 下拉选择整数 → 数字输入字符串 → 文本输入必填校验生效未填或类型错误时阻止提交枚举约束生效只能选择枚举集合内的值默认值正确预填用户填写后的值能传入底层任务。2.3 Preconditions前置条件项目中存在名为Infra QA的项目模板survey-demoBash app已创建并配置好playbook即脚本内容为echo env$env echo replicas$replicas echo feature_name$feature_name这是一个用 Bash 应用验证变量传递的最小脚本任务运行时Survey 变量会以namevalue的形式追加为 CLI 参数详见 第 5 节因此脚本通过$env、$replicas、$feature_name三个位置参数读取值。2.4 Test data — Survey variables测试数据NameTitleTypeRequiredValuesDefaultenvEnvironmentenumyesdev,stg,proddevreplicasReplica countintyes-1feature_nameFeaturestrno-empty三个变量恰好覆盖三种类型与两种必填状态env枚举 必填 默认值、replicas整数 必填 默认值、feature_name字符串 非必填 无默认值。3. 在模板上配置 Survey 变量字段模型与配置操作3.1 配置入口在模板编辑界面对应前端组件 web/src/components/TemplateForm.vue中找到Survey Variables区域fieldset的legend文案即surveyVariables。该区域以可拖拽的 chip 列表展示已配置变量点击 Add Variable当列表为空时显示addVariable或芯片打开编辑对话框每个已存在变量显示为一个可点击、可关闭的 chipchip 颜色根据类型区分int类型为青色#61e2ff其他为灰色见 SurveyVars.vue通过拖拽vuedraggable可以调整变量顺序顺序即启动对话框中控件的展示顺序。3.2 变量编辑对话框中的字段编辑对话框SurveyVars.vue包含以下输入项对应后端db.SurveyVar结构体字段表单字段后端字段JSON说明Namename变量名必填该名字将直接成为注入任务进程的变量名/CLI 参数名Titletitle展示标题必填显示在启动对话框的控件 label 上Descriptiondescription描述文本作为启动对话框控件的 hint 提示Typetype变量类型见下方类型表Targettarget变量传递方式CLI/extra-vars或env进程环境变量见 第 6 节Requiredrequired是否必填对话框底部 checkboxDefault valuedefault_value默认值控件随类型变化enum 为下拉、int 为数字框、text 为多行文本、select 为多选 chipsValuesvalues仅 enum/select 类型显示每行一个name展示名value实际值对3.3 六种变量类型源码级定义类型常量定义在 db/Template.gotype SurveyVarType string const ( SurveyVarStr SurveyVarType // String空字符串即字符串类型 SurveyVarInt SurveyVarType int // Integer 整数 SurveyVarEnum SurveyVarType enum // Enum 枚举 SurveyVarText SurveyVarType text // Text 多行文本 SurveyVarSelect SurveyVarType select// Select 多选 )前端编辑器中SurveyVars.vue提供的类型选项为String、Integerint、Secretsecret、Enumenum、Texttext、Selectselect。secret类型在启动对话框中使用掩码输入框masked-secret-input其值存入任务的secret字段而非普通环境字段运行日志中不会明文出现实现见 TaskForm.vue。枚举值结构体db/Template.gotype SurveyVarEnumValue struct { Name string json:name // 展示名如 Production Value string json:value // 实际值如 prod }TC-022 的env变量对应的values就是[{name:dev,value:dev},{name:stg,value:stg},{name:prod,value:prod}]形式前端启动对话框按name展示、按value提交见 TaskForm.vue 的item-textname/item-valuevalue。3.4 配置操作步骤对应 TC-022 Step 1进入项目Infra QA→ 模板列表 → 打开模板survey-demo的编辑页在 Survey Variables 区域点击添加变量envNameenvTitleEnvironmentType 选择Enum勾选 Required添加三条枚举值dev/stg/prodDefault value 选择dev添加变量replicasNamereplicasTitleReplica countType 选择Integer勾选 RequiredDefault value 填1添加变量feature_nameNamefeature_nameTitleFeatureType 保持String不勾选 RequiredDefault value 留空保存模板。模板的survey_vars字段以 JSON 数组形式持久化SQL 中位于project__template.survey_vars列后端通过Template.SurveyVarsJSON读取并反序列化见 db/Template.go 与FillTemplate的实现。4. 启动对话框控件渲染、默认值预填与校验规则4.1 控件渲染逻辑启动对话框表单由 web/src/components/TaskForm.vue 渲染模板的 type 为 build 等特殊场景复用 TaskParamsForm.vue。其渲染规则为变量类型控件对应模板代码secret掩码密码输入框masked-secret-inputTaskForm.vueenum/selectv-select下拉select为多选multiplechipsTaskForm.vuetext多行文本框v-textarea3 行TaskForm.vue其余/int单行v-text-fieldint额外附加整数正则校验TaskForm.vue控件的label为v.title必填时追加*hint为v.description。4.2 默认值预填打开启动对话框时afterLoadData()会从模板的survey_vars中取出所有带default_value的变量合并进editedEnvironmentTaskForm.vueconst defaultVars (this.template.survey_vars || []) .filter((s) s.default_value) .reduce((res, curr) ({ ...res, [curr.name]: curr.default_value, }), {}); this.editedEnvironment { ...defaultVars, ...this.editedEnvironment };因此在 TC-022 Step 2 中env下拉默认选中devreplicas数字框预填1feature_name留空。注意select类型的值会被规范化为数组normalizeSelectValues保证多选控件的 v-model 始终是数组。4.3 必填与类型校验前端第一道防线TC-022 Step 3 与 Step 4 验证的是负向场景表单必须阻止非法提交且不发出任何 API 调用no API call is made。前端校验规则TaskForm.vue 与 L132-L136必填校验v.required时规则为val !!val || v.title isRequired对enum/select则要求Array.isArray(val) ? val.length 0 : val ! null整数校验val !val || v.type ! int || /^\d$/.test(val) || v.title mustBeInteger即只接受纯数字/^\d$/。因此输入abc会立即被拒绝并显示内联错误信息表单整体在v-form上使用lazy-validation提交时调用validate()任一项失败则save()不会继续不会产生创建任务的网络请求。这就是 Step 3replicas留空 → 必填错误与 Step 4replicasabc→ 整数格式错误的机制来源。校验错误文案对应 i18n 键isRequired、mustBeInteger见 web/src/lang/en.js 等语言文件。5. 从启动对话框到任务日志Survey 变量的完整运行链路TC-022 的核心验证点是提交后的值确实被传入了任务进程Step 5/6并且能在Task → Arguments 选项卡中看到这些值。这条链路在仓库中分为四个环节。5.1 第一步值写入任务的 Environment / Secret用户提交启动表单后普通 Survey 变量的值序列化到任务对象的environmentJSON 字段secret类型变量写入secret字段见 TaskForm.vue 的beforeSave()this.item.environment JSON.stringify(this.editedEnvironment); this.item.secret JSON.stringify(this.editedSecretEnvironment);这两个字段正是 Task → Arguments 选项卡所展示的数据来源。5.2 第二步TaskPool 组装 LocalExecutor任务创建后TaskPool.AddTaskservices/tasks/TaskPool.go构建一个LocalExecutor携带Template、Environment、Secret三个关键输入。LocalExecutor结构体定义在 services/tasks/local_executor.go其中type LocalExecutor struct { Task db.Task Template db.Template Inventory db.Inventory Repository db.Repository Environment db.Environment Secret string // Secret contains secrets received from Survey variables ... }说明远程 Runner 场景下runner 会收到完整的db.TemplateJSON含survey_vars并运行同一个LocalExecutor因此本条链路同时覆盖服务端本地执行与远程 Runner 执行见 services/runners/types.go 中Template db.Template \json:template 的定义。5.3 第三步getEnvironmentExtraVars 合并环境与秘密变量getEnvironmentExtraVars 将Environment.JSON与Secret合并为一个 mapif t.Environment.JSON ! { err json.Unmarshal([]byte(t.Environment.JSON), extraVars) ... } if t.Secret ! { extraSecretVars : make(map[string]any) if err json.Unmarshal([]byte(t.Secret), extraSecretVars); err ! nil { return } maps.Copy(extraVars, extraSecretVars) }之后这个 map 会按应用类型转换为不同的 CLI 形态Ansible--extra-vars jsongetPlaybookArgsTerraform / Tofu / Terragrunt-var namevaluegetTerraformArgsShell 应用Bash 等namevalue形式的 CLI 参数getShellArgs。TC-022 的survey-demo是 Bash 应用所以最终命令行形如script.sh envdev replicas3 feature_namelogin-redesign即脚本内$1$env、$2$replicas、$3$feature_nameBash 位置参数因此echo env$env输出envdev以此类推——这正是 Expected results 中 Step 5/6 日志断言envdev replicas3 feature_name与envstg replicas2 feature_namelogin-redesign的来源。5.4 第四步Prepare 组装进程环境并执行LocalExecutor.Prepareservices/tasks/local_executor.go完成仓库检出、SSH key 安装、CLI 参数与进程环境组装最终由Run把CliArgs与EnvironmentVars交给底层 Appdb_lib.LocalApp执行。TaskRunnerservices/tasks/TaskRunner.go负责维护任务状态与日志流日志输出即 UI 任务详情页的内容。6. 进阶target字段——按应用方式传递变量除 TC-022 覆盖的默认行为外Survey 变量还支持target字段控制变量是走 CLI 参数还是进程环境变量该功能在 2.19 版本引入实施计划见 AGENTS/plans/2_19/survey-var-target.mdtype SurveyVarTarget string const ( // SurveyVarTargetDefault 按应用默认方式传递 // Ansible 走 --extra-varsTerraform 系走 -varShell 应用走 CLI 参数 SurveyVarTargetDefault SurveyVarTarget // SurveyVarTargetEnv 作为进程环境变量传递 SurveyVarTargetEnv SurveyVarTarget env )target默认变量进入 extra-vars map见 5.3 节按应用类型注入 CLItargetenv变量以NAMEvalue形式追加到进程环境getSurveyEnvVarslocal_executor.go同时从 extra-vars map 中删除L165-L171保证每个变量只传递一次。环境变量名即变量名本身如 Terraform 用户需要TF_VAR_foo时直接把变量命名为TF_VAR_foo。前端编辑器在对话框的 Type 旁提供 Pass variable assurvey_var_target下拉Extra variableCLI或Environment variableenv见 SurveyVars.vue 与varTargets数据。API 文档中对应定义见 api-docs.ymltarget枚举[, env]。7. 服务端校验与单元测试确保数据合法性的第二道防线前端校验之外后端在模板保存与任务执行前还有完整的校验逻辑这是 TC-022 中模板保留 Survey 配置Postconditions的保障。7.1 ValidateSurveyVar类型与默认值的兼容性校验db/Template.go 的ValidateSurveyVar实现了默认值与类型的兼容规则select 类型default_value必须是数组形态同时数组中每个值都必须出现在values列表里否则返回校验错误default_value ... is not in values listenum 类型default_value必须是标量单值且该值必须存在于values列表string / int / text / secretdefault_value必须是标量数组形态仅当恰好一个元素时才被接受。SurveyVarDefaultValue自定义 JSON 编解码db/Template.go会保留原始 JSON 是字符串还是数组的形状originalWasArray这正是校验能够区分单值默认与数组默认的基础。7.2 Template.Validatetarget 合法性校验Template.Validatedb/Template.go对每个 Survey 变量校验target只允许或env其他值返回invalid survey variable target: ...for _, v : range tpl.SurveyVars { switch v.Target { case SurveyVarTargetDefault, SurveyVarTargetEnv: default: return common_errors.ValidationError{Message: invalid survey variable target: string(v.Target)} } if err : ValidateSurveyVar(v); err ! nil { return err } }对应测试TestTemplateValidate_SurveyVarTarget与TestSurveyVarTarget_JSONRoundTrip记录在实施计划 AGENTS/plans/2_19/survey-var-target.md 中验证target字段的 JSON 往返与非法值拒绝。7.3 前端编辑器自身的校验saveVar配置 Survey 变量时前端编辑器也有自校验SurveyVars.vueenum/select 必须至少有一条 values否则报Enumeration/Select must have values.enum/select 的 values 的name必须唯一否则报must have unique names.value 的name不能为空字符串。这些规则由单元测试 web/tests/unit/survey-vars.spec.js 覆盖其中normalizeDefaultValue测试组验证了各类型默认值的规范化行为如 select 标量包装为数组、int 保留数字等saveVar测试组验证了enum 无值被拒绝重复 name 被拒绝表单非法时不 emit change等关键行为。8. 完整验收按 TC-022 执行 Steps 并核对 Expected results下面将 TC-022 的六个步骤与预期结果整理为可直接执行的验收清单8.1 Steps步骤在survey-demo模板上配置三个 Survey 变量见 3.4点击Run观察启动对话框不填写replicas直接点击Submit→ 期望出现校验错误填写replicas abc再提交 → 期望出现校验错误以envdev、replicas3提交feature_name留空再提交一次envstg、replicas2、feature_namelogin-redesign。8.2 Expected results预期结果步骤预期结果机制Step 2env是含三个候选值、默认dev的下拉框replicas是预填1的数字输入框feature_name是普通文本输入框控件渲染规则 默认值预填4.1、4.2Step 3-4表单阻止提交并显示内联错误不发任何 API 调用前端必填与整数校验4.3Step 5任务成功日志显示envdev replicas3 feature_nameBash 位置参数注入5.3Step 6任务成功日志显示envstg replicas2 feature_namelogin-redesign同上附加这些值同时显示在Task → Arguments选项卡值持久化于任务的environment字段5.18.3 Postconditions后置条件模板survey-demo的 Survey 配置保持完整所有变量定义不因运行任务而改变或丢失。9. 常见问题与排查建议启动对话框中没有出现 Survey 控件确认模板确实保存了survey_vars可调用模板 API 检查响应的survey_vars数组是否非空API 定义见 api-docs.yml 的TemplateSurveyVar。整数变量能输入负数/小数前端正则/^\d$/只接受非负整数如需其他范围可在模板arguments中另行约束。enum 默认值无法保存服务端ValidateSurveyVar要求 enum 的default_value必须存在于values列表检查默认值是否与某个枚举value完全一致区分大小写。Secret 变量在日志中不可见是正常现象secret 类型走Task.Secret字段与掩码输入不会以明文出现在任务日志或--extra-vars展示中。Bash 脚本中$env取不到值确认变量在启动对话框已正确填写非空空字符串变量不会生成 CLI 参数因此feature_name输出为空是符合预期的对应 Step 5 的期望日志。10. 相关资源索引用例原文test/test-cases/TC-022-survey-vars.md用例总览test/test-cases/README.md后端模型与校验db/Template.goSurveyVar、SurveyVarType、SurveyVarTarget、ValidateSurveyVar、Template.Validate执行器实现services/tasks/local_executor.gogetEnvironmentExtraVars、getSurveyEnvVars、getShellArgs、getTerraformArgs、getPlaybookArgs、Prepare任务池与执行器装配services/tasks/TaskPool.go前端变量编辑器web/src/components/SurveyVars.vue前端启动对话框web/src/components/TaskForm.vue、web/src/components/TaskParamsForm.vue前端单元测试web/tests/unit/survey-vars.spec.jsAPI 定义api-docs.ymlTemplateSurveyVar、TemplateSurveyVarValue功能实施计划AGENTS/plans/2_19/survey-var-target.md赞分享后端DevOps任务调度认证鉴权【免费下载链接】semaphoreModern UI and powerful API for Ansible, Terraform/OpenTofu/Terragrunt, PowerShell and other DevOps tools.项目地址https://gitcode.com/gh_mirrors/se/semaphore点击查看免费下载相关推荐nuclei-templates 用户枚举 OSINT 模板实战跨平台账号存在性批量验证指南nuclei templates 用户枚举 OSINT 模板实战跨平台账号存在性批量验证指南 导读 本指南以 nuclei templates 仓库 htt网络安全漏洞扫描应用安全渗透测试三条命令为 GTK 桌面部署 macOS 风格主题三条命令为 GTK 桌面部署 macOS 风格主题 开机时登录界面是一整面带模糊的彩色渐变进入桌面后标题栏、顶部面板、Nautilus 侧边栏全部是 maUI组件设计系统Rowy高级技巧如何配置自定义字段验证、默认值与必填字段的终极指南Rowy高级技巧如何配置自定义字段验证、默认值与必填字段的终极指南 Rowy作为开源的低代码后端平台让您能够在类似电子表格的界面中轻松管理数据库并通过Ja低代码上一篇终极指南5分钟免费解锁Axure中文界面让原型设计更高效下一篇如何从零开始掌握机器学习斯坦福CS229中文教程完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考