OneUptime × GitHub 集成:用 Workflow 让每个 Incident 自动创建 GitHub Issue
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
本文基于 OneUptime 官方文档《GitHub-integration》(丹麦语原文、英文版)编写,完整讲解如何借助 OneUptime 的 Workflow 引擎(Incident On Create 触发器 + API 组件)把每一次事件自动落成一个 GitHub Issue,使工程跟进发生在拥有该服务的代码仓库中。读完本文,你可以独立配置 token 与全局变量、搭建并验证这条工作流、排障常见 HTTP 错误码,并理解 API 组件底层的返回值、脱敏与执行机制。
集成总览:一条出站链路,明确边界
该集成是**出站(outgoing)**集成:OneUptime 主动调用 GitHub REST API 的 创建 Issue 端点,不需要 GitHub 侧向 OneUptime 回调任何内容。整体链路为:
OneUptime Incident → On Create ──► API component (POST /repos/{owner}/{repo}/issues) ──► GitHub issue实现方式是 OneUptime 的一个Workflow,由两部分组成:
- 一个Incident → On Create触发器:事件被创建时触发工作流;
- 一个API 组件:以
POST请求把事件字段写入 GitHub Issues API。
注意区分另一种 GitHub 连接:OneUptime 还提供一个原生GitHub App集成,用于把代码仓库与平台绑定(被 AI Agent 和代码相关功能使用)。在那个集成下,你可以在 Issue 或 Pull Request 中 @ 该 App,让它实现、审查或走查代码,参见 Arbejd med OneUptime fra GitHub 中指向的 GitHub App 使用文档 与 自托管安装文档。本文只讲从事件创建 Issue这一条链路。
前置条件
按文档列出,你需要准备三样东西:
一个 GitHub 仓库:你希望在其中自动创建 Issue 的仓库。
一个有权限创建 Issue 的 token,二选一:
- 细粒度 PAT(Fine-grained PAT):scope 到目标仓库,并授予Issues: Read and write权限;
- 经典 PAT(Classic PAT):带
reposcope。
在 github.com 的 settings/tokens 页面创建。
一个 OneUptime 项目:你需要在其中有权创建工作流。
步骤 1 — 保存 token 为全局变量
- 进入工作流(Workflows)→ 全局变量(Global variables)→ 创建;
- 变量命名
GITHUB_TOKEN,值填入 token,并开启Is Secret开关。
开启 Is Secret 不是可有可无的选项。从源码看,工作流的执行日志(WorkflowLog)对任何有项目读取权限的人是可见的;在 API 组件定义 中,request-headers参数被显式标记为isSensitive: true,源码注释解释了原因:
Headers 是填写 Authorization bearer token 的地方。若不标记,解析后的值会被原样写入 WorkflowLog,对任何有项目读取权限的人可见。只有来自标记为 secret 的变量的值才会被清除。
因此,把 token 存成 Secret 全局变量并通过{{variable.GITHUB_TOKEN}}引用,是保证 token 不泄漏到工作流日志中的正确做法。
步骤 2 — 搭建工作流
打开工作流 → 创建工作流,命名为
Incidents → GitHub Issues,进入Builder(构建器);添加一个Incident触发器并设为On Create,将其重命名为
Incident;添加一个API块并连接到触发器:
Method:
POSTURL:
https://api.github.com/repos/din-org/dit-repo/issues(替换为你的组织/仓库)Headers:
Authorization: Bearer {{variable.GITHUB_TOKEN}} Accept: application/vnd.github+json X-GitHub-Api-Version: 2022-11-28 User-Agent: OneUptimeBody:
{ "title": "OneUptime incident: {{Incident.title}}", "body": "{{Incident.description}}\n\nFiled automatically from OneUptime.", "labels": ["incident", "oneuptime"] }
保存并启用工作流,然后创建一个测试事件。工作流日志中出现
201 Created即表示 Issue 已创建;响应体(response-body)中会包含该 Issue 的number与html_url。
源码级深潜:这条工作流在 OneUptime 里是如何跑起来的
Incident On Create 触发器
Incident 的触发器不是手写组件,而是由模型元数据自动派生的。从 BaseModel.ts 可以看到,每个数据库模型都会生成形如incident-on-create的触发器元数据(On Create ${model.singularName},id 为${tableName}-on-create)。仓库内置的工作流模板(Templates.ts)也大量引用了incident-on-create组件,例如内置的事件通知模板就通过{{local.components.incident-on-create-1.returnValues.model.title}}这类表达式读取触发器上下文中的事件标题、严重级别与状态——这正是本文 Body 中{{Incident.title}}/{{Incident.description}}可用的底层依据。
API 组件的入参与返回值
文档中 API 块的全部配置项,对应 API 组件注册表 中ApiPost组件的元数据。该组件提供ApiGet/ApiPost/ApiPut/ApiPatch/ApiDelete五个变体,全部收录在 组件注册表 的API分类下。关键参数与文档配置的对应关系:
| 文档配置 | 组件参数(id) | 类型 | 说明 |
|---|---|---|---|
| URL | url | URL,必填 | 请求地址 |
| Body | request-body | JSON,选填 | 请求体 |
| Headers | request-headers | StringDictionary,选填、高级项、isSensitive | 请求头 |
执行完成后,组件向下游暴露四个返回值,这解释了文档中两处说法的来源:
response-status(数字)——工作流日志里的201 Created就是它;response-body(JSON)——文档提示从中读取number和html_url;response-headers(StringDictionary);error(文本)。
同时该组件有Success和Error两个输出端口,意味着你可以把失败分支接到告警(如 Slack/邮件组件)上,Issue 创建失败时及时获知。
执行与审计模型
工作流组件不是在 API 进程内同步执行的。从 RunStep.ts(Builder 中“运行单步”端点)的注释可以看到执行模型:
- 即使是 Builder 里的单步调试,也是真实执行,没有“安全/只读组件”的概念;
- 它并不直接执行组件,而是入队一次普通的、被收窄到单步的工作流运行,因此完整继承既有约束:工作流必须启用、订阅有效、项目计划的运行次数限额被遵守;
- 每次运行都会写WorkflowLog行,留下与其他运行一致的审计痕迹;
- 组件在 worker 上执行而非 API 进程内,且日志与返回值按运行器既有规则脱敏,不会原样回传到 HTTP 响应里。
触发器注册与入队同样经由 ComponentCode.ts:所有TriggerCode类型组件在初始化时被统一挂载scheduleWorkflow/executeWorkflow钩子,触发事件最终通过QueueWorkflow.addWorkflowToQueue进入队列,由 worker 异步消费——所以事件创建后 Issue 的出现是准实时的,排障时应以工作流日志为准,而不是盯着 GitHub 刷新。
验证与进阶技巧
文档给出的三条 Tips,均可直接落地:
- GitHub Enterprise Server:把 URL 换成
https://<你的企业主机>/api/v3/repos/{owner}/{repo}/issues,其余配置不变。 - 负责人 / 里程碑:在 Body 中加入
"assignees": ["octocat"]或"milestone": 3(assignees为登录名数组,milestone为数字编号)。 - 回链到事件:从 API 组件的
response-body中读取html_url,再用一个Update Incident块把链接写回事件。注意文档示例写的是{{CreateIssue.response-body.html_url}}(CreateIssue为 API 块的重命名);从内置模板的写法看(Templates.ts),完整模板表达式形如{{local.components.<组件id>.returnValues.response-body.html_url}},在 Builder 中引用时以提示面板给出的实际路径为准。
此外,结合组件元数据还可以:
- 用
response-status配合Condition组件做分支(非 201/202 走 Error 口告警); - 在 Body 中引用更多触发器字段(如事件编号、严重级别),构造信息更完整的 Issue 标题与描述。
故障排查
按文档整理四种典型错误码与处置:
| 错误码 | 原因与处置 |
|---|---|
| 401 | token 错误或已过期。细粒度 token 必须显式授予目标仓库及Issues权限。 |
| 403 / 速率限制 | 确保携带User-Agent头(GitHub 会拒绝没有它的请求),并确认未被速率限制。 |
| 404 | owner/repo路径错误,或 token 无法访问该私有仓库。 |
| 422 | Body 中引用不存在的 label 是可以的(GitHub 会自动创建被引用的 label);但畸形的 JSON 不行——检查你的 Body。 |
排障入口就是工作流日志:确认response-status与error返回值,日志中的敏感值已按前述脱敏规则处理,不会回显 token 明文。
自托管部署的网络要求
若为自托管 OneUptime,本页面这条创建 Issue 的工作流只需要:
- 对
api.github.com的DNS 解析; - OneUptime →
api.github.com的出站 HTTPS(TCP 443); - 无需任何来自 GitHub 的入站回调。
更完整的出站/入站与私有网络(private installation)场景说明,见 自托管 GitHub 集成文档。
延伸阅读
- 集成总览 — 各集成模式与鉴权方式一览;
- GitLab 集成 — 同样思路在 GitLab 上的实现;
- 自托管 GitHub 集成 — 原生 GitHub App 连接的部署;
- 从 GitHub 操作 OneUptime — 在 Issue 或 Pull Request 中指挥 GitHub App。
核心参考文件:本文档(da)、API 组件定义、组件注册表、触发器元数据生成、内置工作流模板、单步执行 API。
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考