带审批、延迟节点和运行变量的工作流运行

Semaphore UI 2.20 新增了带 SIEM 导出的审计日志,把工作流发展为真正的流水线引擎 —— 支持延迟节点、修订版本、在任务间传递的输出以及工作流变量;重构了角色,使一位成员可以持有多个角色,管理员也获得了实例级角色和 IdP 组映射;引入了用于逐主机配置 SSH 和 Git 凭据的主机配置;把每一个 Ansible 额外变量都移入Vault 加密的文件;并对外暴露了 Prometheus 指标。

本系列从 v2.20.0 开始。补丁版本会在发布时列于本页末尾。

亮点

  • 审计日志 — 谁、从哪里、做了什么、结果如何;提供管理员界面、保留策略,以及面向 SIEM 的 Syslog / Splunk HEC 导出(导出和过滤为 Pro 功能)。
  • 工作流 — 延迟节点、与运行绑定的不可变修订版本、作为下一个任务输入交付的输出、在运行对话框中询问的工作流变量、带快捷键和撤销的重新设计编辑器,以及可启动工作流的 webhook。
  • 每位成员可拥有多个角色,角色带有 id 和 slug,全局角色可授予实例级权限 (Pro),并支持在登录时应用的 IdP 组 → 角色映射 (Enterprise)。
  • 外部身份 — LDAP 和 OIDC 登录通过提供者的稳定 id 绑定到账户,而不再通过电子邮件;同一登录页可以展示多个 LDAP 目录。
  • 主机配置 — 把 SSH 主机和 Git URL 映射到项目凭据,并应用于克隆、Galaxy、Terraform 模块和 Ansible。
  • Ansible 额外变量不再出现在命令行上;密钥通过 Ansible Vault 加密的文件传递,值中的 Jinja2 也不再被求值。
  • 模板:Ansible 工作目录、唯一名称以及任务 API 中的 template_name、可抑制的错误通知、可隐藏的 Dry Run / Diff、Galaxy 安装选项、多选调查变量、可传达到远程 runner 的调查密钥。
  • Monorepo 仓库在多个模板之间共享同一份检出;Git 重试、并行子模块拉取、SSH 主机密钥校验。
  • 位于 /api/metrics 的 Prometheus 指标。
  • 在服务端生成 SSH 密钥对,并可从密钥库复制公钥。

审计日志

审计日志界面

Semaphore 现在会把与安全相关的事件记录到一个专用的仅追加日志中。通过以下配置启用:

"audit": {
  "enabled": true,
  "instance_id": "semaphore-prod"
}

(SEMAPHORE_AUDIT_ENABLED、SEMAPHORE_AUDIT_INSTANCE_ID;instance_id 为必填项,用于在每个事件中标识该安装实例。)

记录的内容。 八个类别中的 116 种事件类型:auth(登录、登出、MFA、API 令牌拒绝、被拒请求、CSRF 拦截)、iam(用户、密码、API 令牌、身份、成员关系、角色、模板权限)、resource(项目、备份、清单、仓库、模板、计划任务、集成、主机配置、工作流、变量组)、secret(凭据和密钥存储)、task(带触发来源的启动、带结果和耗时的完成、审批、停止、历史删除)、runner(注册、变更、被拒报告)、system(设置、许可证),以及 audit 自身(启动、保留、导出)。密码、令牌、密钥值、任务输出和变量永不写入。

事件信封。 每个事件都携带一个 UUID、一个无间断的序列号、一个微秒级 UTC 时间戳、操作者(用户 / 匿名 / 系统 / runner / 集成,附带会话或 API 令牌认证方式以及令牌指纹)、来源 IP 和 User‑Agent、目标、项目、请求 id(同时在 X-Request-ID 响应头中返回)、实例 id 和 HA 节点 id。结果为 success 或 failure,失败原因取自一个封闭列表;对象已保存但后续步骤失败的操作记为成功并带 partial = true。在反向代理之后,只有来自 audit.trusted_proxy_cidrs 的 X-Forwarded-For 才被信任。

审计事件卡片

管理员界面。 用户菜单中的 Audit log(/audit-log)按时间从新到旧列出事件,每页 50 条,提供 Older / Newer 翻页;点击一行会打开一张卡片,包含 Who、Object、Where、When、Details 和 Technical 等区块,以及一个把事件按发送给 SIEM 的 JSON 格式复制出来的按钮。访问需要新增的 Read the audit log 全局权限。

保留策略。 audit.retention_days 会分批删除更早的事件,每小时执行一次并带抖动,以免 HA 节点互相冲突;每一次删除了内容的清理本身也会被记录。

Pro:过滤与导出。 按时间段、用户、项目、事件类型、结果和 IP 过滤;从任意卡片值快速下钻;把当前选择导出为 CSV 或 JSON Lines。

Pro:SIEM 导出。 两种目标,各有自己的游标,因此接收端故障时不会跳过任何内容:通过 audit.syslog 的 TLS 上的 Syslog(RFC 5424,事件 JSON 作为消息体),以及通过 audit.splunk_hec 的 Splunk HTTP Event Collector(url、token、index、source、sourcetype、ca_file,……)。投递至少一次,并按序列号排序;在 HA 中每个目标只有一个节点负责导出,通过 Redis 租约协调。三个 Prometheus 指标序列描述该导出器:semaphore_audit_export_pending_events、semaphore_audit_export_oldest_pending_seconds 和 semaphore_audit_export_errors_total。

存储:audit_event、audit_event_sequence、audit_export_state 表(迁移 v2.20.9 到 v2.20.11)。API:GET /api/audit/events 和 GET /api/audit/events/export。


工作流

工作流是 Pro 功能;Beta 标记已移除。

延迟节点

继任务、审批和注释之后的第四种节点类型:延迟节点会把运行暂停若干秒,然后释放其出边。运行视图会在卡片上显示实时倒计时;停止运行会取消延迟。字段 delay_seconds,迁移 v2.20.2。

修订版本

每次保存工作流都会创建图的一个新修订版本;一次运行会固定它启动时所用的修订版本,因此编辑工作流永远不会改变正在进行的运行,也不会让过往运行的节点失去归属。编辑器会显示一个 rev. N 标签以及仍在执行较旧修订版本的运行数量;运行视图会显示它所执行的修订版本。保存更新的修订版本时,没有任何运行引用的修订版本会被删除。API:GET …/workflows/{id}/revisions 和 …/revisions/{revision_id}。

输出与输入

带输出徽标的运行视图

一个任务可以把结构化数据交给其后的节点。由工作流启动的每个任务都会获得 SEMAPHORE_OUTPUTS_FILE;它写入其中的任何 JSON 对象都会成为该任务的输出:

cat > "$SEMAPHORE_OUTPUTS_FILE" <<EOF
{"image_tag": "1.4.2", "replicas": 3, "subnet_ids": ["subnet-1", "subnet-2"]}
EOF

Ansible 通过内置的回调插件以 ansible.builtin.set_stats 产生输出;Terraform、OpenTofu 和 Terragrunt 的输出会自动从 output -json 中捕获(sensitive 值会被跳过,并标记为 Not captured)。只有任务成功时才会读取输出;限制为 100 个输出、每个 32 KB、每个文件 256 KB。

一条进入任务节点的连接会交付输入 —— 它用源节点的输出填充目标模板的调查变量:

  • 按名称(默认):名称与某个调查变量相同的每个输出都会填充该变量。
  • 显式映射输入:列出要交付的 variable ← output key 对;一旦工作流有过一次完成的运行,面板就会提示该次运行产生的键。

带显式输入映射的连接面板

值会被强制转换为变量类型,审批节点和延迟节点会把输出透传,显式映射优先于按名称交付,而一个必填变量若没有取到值,会在节点的任务启动前就使其失败,从而让运行沿着 失败时 的边继续。运行视图会为每个节点显示一个 N outputs 徽标,任务对话框中有一个输出表格,任务日志开头会为每个已交付的值打印一行 Input "x" <- output "y" of node N。输出以明文存储,永不填充 secret 变量;secret 不能通过输出传递。远程 runner 上的任务既能产生也能接收输出;Docker 和 Kubernetes 执行器尚不捕获输出。

带输出表格的任务对话框

工作流变量与运行对话框

询问工作流变量的运行对话框

工作流拥有自己的调查变量,在运行启动时通过一个 Run “…” 对话框一次性询问(没有变量的工作流会像以前一样立即启动)。答案存储在该次运行上,以标签形式显示在运行画布上方的变量条中,并且只能通过节点面板中的显式绑定到达任务 —— 工作流变量永远不会按名称泄漏进模板。不允许把密钥用作工作流变量。POST …/workflows/{id}/runs 接受 {"environment": {"image_tag": "1.4.3"}};与类型不符的答案或缺失的必填值会导致启动被拒绝。

工作流任务的环境

由工作流启动的每个任务都会收到 SEMAPHORE_WORKFLOW_ID、SEMAPHORE_WORKFLOW_RUN_ID、SEMAPHORE_WORKFLOW_URL(需要 web_host)和 SEMAPHORE_OUTPUTS_FILE,对所有应用以及远程 runner 均适用。

重新设计的编辑器

工作流编辑器

  • 新的节点卡片带有类型图块、状态、耗时、输出徽标以及内联的 Approve / Reject;边标签带有就地条件下拉框和删除按钮;画布采用点阵网格。
  • 快速添加菜单,可从节点的 + 把手、画布上的右键菜单或空状态按钮打开:可搜索的节点类型与任务模板列表,新节点会以 成功时 连接。
  • 撤销 / 重做(Ctrl/⌘+Z、Ctrl/⌘+Shift+Z)、工作流的内联重命名、可定位到出错节点的 Problems 菜单、提示未保存更改的 Save 徽标,以及离开页面的保护提示。
  • 画布上的快捷键:方向键平移(按 Shift 为大步长)、+ / - 缩放、0 适应图形、1 重置缩放、Esc 清除选择;节点卡片支持键盘聚焦。
  • 浮动控件:放大 / 缩小、适应视图、Tidy up 自动布局、缩放百分比。
  • 一个折叠箭头可同时折叠面板和主导航;该状态会被记住。
  • 触控板的过度滚动不再在 macOS 上触发浏览器的返回手势。

快速添加菜单

Webhook 启动工作流

集成现在可以运行工作流而不是模板(集成表单中的 Runs: Template / Workflow)。每个提取出的值都会成为工作流调查的一个答案。管理这类集成需要 Pro 的 workflow_integrations_management 功能。对于模板集成,若提取出的 Task Params 值名为 git_branch,则在模板允许覆盖时会设置所启动任务的分支。

API 变更

POST …/workflows/{id}/run 已重命名为 POST …/workflows/{id}/runs,并接受 environment 请求体。运行详情会携带 revision_id、revision、每个节点的 delay 对象以及 task.artifacts。任务上由客户端提供的 workflow_run_id、workflow_node_id 和 artifacts 会被忽略,因此一个任务无法冒充他人运行中的节点。


角色与访问控制

每位成员可拥有多个角色

每位成员拥有多个角色的团队页面

项目成员持有一组角色,在团队页面上以标签形式编辑。API 在旧的 role 之外还接受 roles: ["manager", "release_approver"];响应只对单角色成员保留标量 role。非管理员无法从最后一位所有者手中拿走内置的 Owner 角色。

带 id、slug 和作用域的角色

角色现在是带整数 id 和 slug(^[A-Za-z0-9_-]{1,100}$,由表单中的名称派生)的数据行;四个内置角色也是数据行,不再能被自定义角色遮蔽。角色具有作用域:内置、共享(可在任意项目中使用)或项目级。删除正在使用的角色会返回 409 并附带其影响范围(成员、项目、模板权限、映射),可以带 ?force=true 重试 —— 即 UI 中的 Delete with assignments。迁移 v2.20.12 和 v2.20.13 会重建角色表;参见升级说明。

全局角色与权限 (Pro)

用户页面的全局角色标签页

实例级权限不再只有管理员标志。一个全局角色授予由四项权限组成的掩码 —— Manage users、Manage global roles、Manage system settings、Read the audit log —— 并在用户页面的 Roles 标签页(/users/roles)以及用户对话框的 Global roles 标签页中分配给用户,后者还会显示生效的权限以及各项权限由哪个角色授予。每个管理路由都由这四个位之一守护;GET /api/user 会返回 global_permissions。实例始终至少保留一位管理员,这通过一个在 HA 节点间也安全的行锁来强制保证。拥有 Manage users 的用户无法编辑管理员,也无法编辑任何持有其所不具备权限的人。API:/api/global-roles、/api/users/{id}/global-roles、/api/users/{id}/global-permissions,权限目录位于 /api/global-roles/permissions。

某个用户的全局角色

组角色映射 (Enterprise)

组映射页面

在新的组映射页面(/role-mappings)把身份提供者的组映射到项目角色:提供者、组、项目、角色。每次 OIDC 登录时,用户的映射角色都会与令牌中的组(提供者的 groups_claim)保持一致。映射得到的角色在团队页面上显示为带 provider: group 提示的锁定标签,无法作为成员角色移除;映射角色不计入项目的最后一位所有者。密码或 LDAP 登录会清除映射角色,因为它们不带组信息。API:/api/role_mappings。


认证与身份

带多个 LDAP 目录的登录页面

  • 外部身份。 LDAP 和 OIDC 登录通过提供者的稳定 id(OIDC 的 sub、LDAP 的 DN)绑定到 Semaphore 账户,记录在新的 user__external_identity 表中,而不再通过电子邮件。这就消除了这一类缺陷:接受任意输入地址的 IdP 会接管别人的账户。external_auth_email_matching(默认 auto,另有 always、never)控制一个尚无身份的既有外部用户是否仍可按电子邮件匹配一次;本地密码账户永不会被接管。只有当 email_verified 为真且提供者设置了 require_verified_email 时,OIDC 电子邮件才会被采纳。用户可以自行在账户对话框中关联和解除关联身份(/api/users/{id}/identities、POST /api/user/identities/ldap、/api/auth/oidc/{provider}/login?link=1)。
  • 多个 LDAP 目录。 ldap_providers 是一个按名称索引的目录映射,每个目录都有自己的服务器、绑定、搜索、映射、颜色和顺序;旧的扁平 ldap_* 配置块继续作为名为 ldap 的提供者生效。登录页在标签页多于一个时会显示切换器,而内部标签页永远不会把密码发送给某个目录。GET /api/auth/login 会返回 ldap_providers 和 login_with_password。
  • LDAPS 证书默认会被校验。 对于自签名证书,请设置 ldap_tls_skip_verify(扁平配置块)或 tls_skip_verify(按提供者)。
  • 会话绝对生命周期。 auth.max_session_life_hours(SEMAPHORE_AUTH_MAX_SESSION_LIFE_HOURS)会在登录后固定时间使会话过期,无论其活跃情况;0 表示只保留不活跃超时。
  • 没有项目且无权创建项目的用户会看到 No projects yet 页面,而不是一个他无法提交的表单;此时 POST /api/projects 会返回 403。
  • 在用户菜单中选择的语言会存储在服务端,并随用户跨浏览器生效(/api/user/options 中的 lang)。

主机配置

主机配置页面

新的项目页面主机配置把 SSH 主机和 Git URL 映射到项目凭据:

  • Host 映射(bastion.example.com)关联一个 SSH 密钥,表现为生成的 ssh_config 中的一个 Host 块;
  • URL 映射(https://github.com/acme/,以 / 结尾的前缀可覆盖整个组)关联一个 SSH 密钥或一组登录名/密码(仅限 HTTPS),表现为 Git 的 insteadOf 重写;最具体的 URL 优先。
主机映射表单

映射会应用于模板仓库及其子模块、requirements.yml 中的角色和集合、terraform init 的模块、由 playbook 运行的 git 命令、清单仓库和清单主机,以及分支与 playbook 浏览;它们也会下发到远程 runner。私钥永不落盘 —— 每个映射一个 SSH agent,通过 IdentityAgent 绑定;密码通过 GIT_CONFIG_PARAMETERS 传递,仓库 URL 在任务日志中会被脱敏。被映射引用的密钥无法删除。映射也是项目备份的一部分。需要 git_client: cmd_git。表 project__host_config,迁移 v2.20.7;API /api/project/{id}/host_configs。


模板与任务

带工作目录和通知选项的模板表单

  • Ansible 工作目录。 Different working directory 会从仓库的某个子目录运行 ansible-playbook;该路径必须位于检出目录内(working_directory,迁移 v2.20.3)。

  • 模板名称在项目内唯一(迁移 v2.20.4),并且 POST /api/project/{id}/tasks 可以接受 template_name 代替 template_id。

  • 按模板抑制错误通知,与既有的成功通知抑制并列;电子邮件告警首次同时遵循这两项设置(suppress_error_alerts,迁移 v2.20.5)。

  • 按模板从任务对话框中隐藏 Dry Run / Diff;服务端也会停止为该模板附加 --check / --diff(task_params.hide_dry_run、hide_diff)。

  • Galaxy 安装选项 —— 一个可折叠的区块,包含 Skip Galaxy install、分别用于 ansible-galaxy role install 和 collection install 的 CLI 参数(采用标志白名单;--token、--api-key 和路径类标志会被拒绝),以及按任务覆盖的提示。

  • Playbook 选择器会在输入时列出子目录,并按应用过滤(Ansible 为 .yml,Terraform / OpenTofu / Terragrunt / Pulumi 为顶层目录,另有 .sh、.py、.ps1),跳过 Ansible 布局目录和点目录,最多 30 条,并且只在限定于仓库根目录的浅克隆中浏览。

  • 多选调查变量 —— 新的 select 类型接受多个值,在任务对话框中以标签形式渲染;default_value 可以是数组。

    带多选调查变量的新建任务对话框
  • 调查密钥可传达到远程 runner。 过去 secret 类型的调查答案到达 runner 时是空的。现在它会作为与任务绑定的访问密钥加密存储(access_key.task_id、expire_at,迁移 v2.20.1),由为该 runner 提供服务的任一 HA 节点解密,任务结束时删除,并每小时清扫一次;它对密钥库、备份和密钥 API 均不可见。

  • YAML 额外变量。 变量组编辑器新增了 Table | JSON | YAML 切换和全屏编辑器;转换是严格的(日期保持为字符串,非对象根和非有限数值会被拒绝)。存储方式未变。

    YAML 模式下的变量组编辑器

  • 任务页面会显示并链接到启动该任务的计划任务或集成,并把已删除的来源标记为 #id (deleted)。复制日志时不再选中日志时间戳。

  • 计划任务会在保存前由服务端校验表达式,因此 @hourly 也被接受,并且时区提示条可以关闭。

    计划任务表单
  • 停止本地任务会终止其整个进程组:先 SIGTERM,15 秒宽限期后再 SIGKILL;被遗弃的 ssh 或提供者进程不再比任务活得更久。被停止的 Terraform plan 不再继续执行;在 SIGTERM 下以 0 退出的 plan 不会被当作成功。

  • 清单的 repository_id 只对 file 类型保留,并且必须属于该项目。

  • 服务器日志会在 Task added to queue / Task started 条目中标明用户。


密钥与 Ansible Vault

  • 额外变量通过文件传递,而不是命令行。 变量组、调查答案、工作流输入和任务详情会被写入一个权限为 0600 的 YAML 文件,并以 --extra-vars @file 传入。密钥 —— secret 类型的调查答案和变量组密钥 —— 会进入第二个文件,由原生 Go 实现以 Ansible Vault 1.1 / AES‑256 格式加密(无需 ansible-vault 二进制文件),并通过回答 ansible-playbook 的 --vault-id <uuid>@prompt 使用一次性密码解锁。无论是这些值还是该密码都不会出现在 ps 中,任务结束时两个文件都会被删除。

  • 值中的 Jinja2 是数据,不是代码。 每个包含 {{、{%、{# 或 #jinja2: 头的字符串都会被递归地标记为 !unsafe,因此像 {{ lookup('pipe', 'id') }} 这样的调查答案会按字面量传递。不含分隔符的字符串是有意不加标记的:ansible‑core ≥ 2.19 会重新解析 !unsafe 标量,那会把 "2026.08" 变成浮点数。

  • 新的 extra_vars 调试命名空间(SEMAPHORE_DEBUG_FILTER=extra_vars)会记录变量是如何拆分和写入的 —— 只记录名称、文件和大小,永不记录值。

  • 在服务端生成 SSH 密钥对。 密钥库中的 Generate SSH Key 会创建一个 RSA 密钥;公钥与该密钥一起保存,可通过 Show / Hide 查看并有复制按钮,创建后还会立即在对话框中提供(generate_ssh_key)。

    带已生成 SSH 密钥对的密钥
  • 更新密钥时,只有设置了 Override 才会写入 type、secret 和公钥部分,因此客户端无法在不替换密钥值的情况下改变密钥的载荷。

  • 从服务器环境变量或 dirs.secrets 下的文件读取凭据的方式现在已有文档说明(密钥库表单的 Env / File 标签页)。


仓库与 Git

带单次检出选项的仓库表单
  • Monorepo:所有模板共用一次检出。 一个仓库选项会只克隆仓库一次并在多个模板之间共享,而不是为每个模板各复制一份;检出目录在 fetch 和 pull 期间加锁,之后任务便可并行运行。这类仓库的模板不能拥有自己的分支,其任务也不能覆盖分支或提交(monorepo,迁移 v2.20.11)。
  • Git 重试。 clone 和 pull 会以指数延迟重试,上限为一分钟;git_attempts(SEMAPHORE_GIT_ATTEMPTS,默认 4)。
  • 并行子模块。 git_submodule_jobs(SEMAPHORE_GIT_SUBMODULE_JOBS,默认 4)会作为 --jobs 传入。
  • SSH 主机密钥校验。 新增 ssh 配置区块:config_path、known_hosts_file(SEMAPHORE_SSH_KNOWN_HOSTS_FILE)和 strict_host_key_checking —— 取值 no(默认)、yes 或 accept-new —— 应用于 SSH 上的 Git。
  • 浏览仓库使用按分支作键的浅克隆;裸机克隆的凭据会进行百分号编码,并在日志和事件流中脱敏。

Runner 与集成

  • runner.check_interval_seconds(SEMAPHORE_RUNNER_CHECK_INTERVAL_SECONDS,默认 5)设置 runner 的轮询频率;Runner 页面上的 Advanced options 开关会把它写入生成的环境变量、配置和 Docker 代码片段(随 v2.19.17 发布)。

  • runner.connection.timeout_seconds(SEMAPHORE_RUNNER_CONNECTION_TIMEOUT_SECONDS,默认 3)分别限制连接、TLS 握手和响应头的耗时;日志上传不会被中断。

  • runners.default_global_runners_mode(SEMAPHORE_DEFAULT_GLOBAL_RUNNERS_MODE:disable、prefer、require)取代了已弃用的 use_remote_runner;runners.registration_token 取代了顶层的 runner_registration_token。

  • SEMAPHORE_DEBUG_FILTER=runner 下的服务端 runner 诊断:令牌拒绝原因、重启与上线检测、被拒的进度报告、派发追踪。

  • Runner 的 unregister 请求会被认证;runner 客户端拒绝 HTTP 重定向。

  • 在既有的 HMAC‑SHA256 之外新增 HMAC‑SHA512 webhook 认证(hmac-sha512);签名头可配置。

    带 HMAC-SHA512 的集成表单
  • 集成属于其他项目的 webhook 会被拒绝。


可观测性

  • Prometheus 指标。 GET /api/metrics,受 HTTP Basic Auth 和一组静态服务凭据保护:

    "metrics": { "enabled": true, "username": "prometheus", "password": "…" }
    

    (SEMAPHORE_METRICS_ENABLED、SEMAPHORE_METRICS_USERNAME、SEMAPHORE_METRICS_PASSWORD。)指标序列:semaphore_tasks_running、semaphore_tasks_total{status}、标准的 go_* 和 process_* 采集器,以及 Pro 中的审计导出计量值。

  • 新增调试命名空间 extra_vars 和 runner;浏览仓库会在 DEBUG 级别记录 Git 输出。

  • 项目备份的导出和恢复都会被记录。


安全

  • 按提供者 id 而非电子邮件关联身份;LDAPS 证书校验默认开启。
  • 额外变量不再出现在命令行上;密钥经 Vault 加密;值中的 Jinja2 不再被求值。
  • 从客户端任务中剥离伪造的 workflow_run_id、workflow_node_id 和 artifacts。
  • 管理路由由显式的全局权限守护,而不是管理员标志;未知的权限位会被拒绝;用户管理上增加了权限提升防护。
  • Playbook 选择器被限制在仓库根目录内(OpenRoot),并有数量上限和过滤。
  • 额外变量的根和 YAML 数值会被校验;Galaxy CLI 参数采用白名单。
  • 仓库凭据在日志和事件流中脱敏;Git 配置参数中的 = 会被转义。
  • 审计端点拒绝跨站读取和格式错误的游标;受信任代理网段会被校验。
  • Runner 的 unregister 会被认证;runner 客户端拒绝重定向。
  • 校验 webhook 的项目和集成 id。
  • 本地任务会连同整个进程组一起停止。

升级说明

破坏性变更与行为变更

  1. 模板名称在项目内必须唯一。 迁移 v2.20.4 会添加唯一索引;请在升级前重命名重复项。
  2. 角色表会被重建(v2.20.12 / v2.20.13)。请先备份。slug 与内置角色或其他角色不区分大小写冲突的自定义角色会被重命名(并记录日志);指向无法解析的角色的模板权限会被丢弃(并记录日志)。成员关系已迁移到 project__user_role;project__user.role 列已移除。
  3. GET /api/project/{id}/users 只对单角色成员返回 role —— 请读取 roles。
  4. /roles* 已从管理员标志改为由 Manage global roles 权限控制;管理员不受影响。
  5. LDAPS 证书默认会被校验。 对于自签名证书,请设置 ldap_tls_skip_verify 或某个提供者的 tls_skip_verify。
  6. ansible-playbook 的调用方式已改变:使用 --extra-vars @file;当任务含有密钥时,还会追加第二个文件和 --vault-id <uuid>@prompt,即使模板没有 vault 也是如此。任何解析该命令行的程序,或禁止 vault 提示的 ansible.cfg,都会受到影响。
  7. 额外变量值中的 Jinja2 不再被求值。 依赖对 webhook 或调查值做模板渲染的 playbook 将不再生效。
  8. 工作流运行端点已重命名:POST …/workflows/{id}/run → …/runs。
  9. Monorepo 仓库会覆盖模板设置:没有按模板的分支,任务中也不能覆盖分支或提交。
  10. 清单的 repository_id 对除 file 以外的所有类型都会被丢弃。
  11. 停止本地任务会杀死其进程组(Windows 上暂无对应实现)。
  12. Docker 和 Kubernetes 执行器尚不捕获工作流输出;调查密钥也尚未传达到这些执行器。

新增配置

audit、metrics、auth.max_session_life_hours、ssh.{config_path,known_hosts_file,strict_host_key_checking}、git_attempts、git_submodule_jobs、ldap_providers、ldap_tls_skip_verify、external_auth_email_matching、按 OIDC 提供者的 groups_claim 和 require_verified_email、runner.check_interval_seconds、runner.connection.timeout_seconds、runners.{default_global_runners_mode,registration_token}。全部为可选。指针类型的配置字段现在也可以通过环境变量设置。配置和 CLI 参考文档页面由源码生成。

数据库迁移

v2.20.0 外部身份 · v2.20.1 与任务绑定的调查密钥 · v2.20.2 延迟节点 · v2.20.3 工作目录 · v2.20.4 唯一模板名称 · v2.20.5 错误告警抑制 · v2.20.7 主机配置 · v2.20.8 工作流修订版本 · v2.20.9–v2.20.11 审计日志与索引、边输入映射、monorepo 标志 · v2.20.12–v2.20.13 角色表、工作流变量 · v2.20.14 工作流集成与组映射 · v2.20.16 全局角色。

依赖项

Go 1.26;Docker 镜像基于 Alpine 3.24;新增 prometheus/client_golang 1.23;go-oidc 3.21、go-ldap 3.4.14、golang.org/x/crypto 0.57、modernc.org/sqlite 1.59、logrus 1.10;前端 js-yaml 5 和 cron-parser 5.10。新增一键部署:Cloudzy、RepoCloud 和 Pethost。