Files
naeeo d78c071818 构建状态增加平台终态只读核对,修复回调丢失后任务长期卡在构建中
工作流在脚本收尾前失败(拉取/编译/runner 异常)或 GENURL 不可达时,
结束回调会永久丢失,而等待页 30 秒轮询与列表页此前只读本地库,
任务只能等 6 小时本地超时,平台侧已失败也无法及时反映。

- GitHub/Gitea 后端新增只读 get_run(),仅在平台报告终态时返回结论,
  在途、非 200、网络异常、坏 JSON 一律返回 None;不取消、不写平台
- 等待页 30 秒轮询同步核对一次真实状态:20 秒节流、6 秒超时、异常静默
- 我的构建/后台仪表盘改为后台守护线程核对,页面渲染零等待
- 仅做非终态到终态的条件更新,回调抢先到达时不会被覆盖
- 停止/删除纯本地语义、6 小时本地超时兜底等现有逻辑保持不变
2026-09-30 12:46:05 +08:00

90 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""构建后端统一接口与共享逻辑。"""
from dataclasses import dataclass
class BackendError(Exception):
"""触发构建失败时抛出,message 为可直接展示给用户的中文提示。"""
def __init__(self, message, *, kind='error'):
super().__init__(message)
self.message = message
# rejected=平台明确拒绝(4xx/5xx);network=连不上平台
self.kind = kind
@dataclass
class DispatchResult:
run_id: object = None # 平台返回的运行编号(int 或 None)
html_url: str = '' # 平台上的运行详情页地址
@dataclass
class RunInfo:
"""平台单次运行的状态快照。"""
finished: bool = False # 是否已结束(拿到终态结论)
status: str = '' # finished=True 时为 rdgen 内部终态码
html_url: str = '' # 平台上的运行详情页地址
# rdgen 目标平台 -> 工作流文件名(两平台同名)
WORKFLOW_FILES = {
'windows': 'generator-windows.yml',
'windows-x86': 'generator-windows-x86.yml',
'linux': 'generator-linux.yml',
'android': 'generator-android.yml',
'macos': 'generator-macos.yml',
}
class BuildBackend:
"""各构建平台实现此接口。所有配置均通过 app_settings 实时读取。"""
name = ''
label = ''
# ---- 配置健康度(后台页 / 全局告警条使用) ----
def configured(self) -> bool:
raise NotImplementedError
def warnings(self) -> list:
"""配置隐患的中文提示列表;通用项(GENURL/ZIP_PASSWORD)各实现自行包含。"""
raise NotImplementedError
# ---- 构建任务 ----
def workflow_file_for(self, platform, selfhosted=False) -> str:
raise NotImplementedError
def dispatch(self, workflow_file, inputs, *, timeout=20) -> DispatchResult:
"""触发工作流。inputs 为完整输入字典(GitHub/Gitea 均为 {ref, inputs})。"""
raise NotImplementedError
def log_url(self, run_id) -> str:
raise NotImplementedError
def get_run(self, run_id, *, timeout=8):
"""只读查询单次运行:已结束返回 RunInfo(finished=True, status=内部终态码);
仍在途、查询失败或不支持时返回 None(调用方按「仍在进行」处理)。"""
return None
# ---- 后台连接测试 ----
def test_connection(self) -> dict:
"""返回 {'ok': bool, 'message': 中文说明},不抛异常。"""
raise NotImplementedError
# ---- 共享的配置检查 ----
def _shared_warnings(self, *, include_sh_secret=False):
"""两平台共用的回调/加密检查。"""
from .. import app_settings
warnings = []
if not app_settings.get_value('GENURL').strip():
warnings.append('平台外部访问地址(GENURL)未配置,构建机将无法回传构建产物。')
zip_password = app_settings.get_value('ZIP_PASSWORD')
if zip_password in ('', 'insecure'):
warnings.append(
'配置压缩包密码为空或仍为默认值 insecure,建议设置随机强密码,'
f'并同步更新{self.label}仓库 Secret。'
)
if include_sh_secret and app_settings.get_value('SH_SECRET') in ('', 'secret'):
warnings.append('自托管 Runner 密钥为空或仍为默认值 secret;如使用自托管 Runner,建议设置独立强密钥,避免被冒用触发。')
return warnings