alkaid_release_platform/core/release_flow.py
ekko.bao 0a0f6a6054 初次创建仓库提交代码
1. 已经构建好了架子了。
2. 添加了示例的插件
2025-04-21 06:37:06 +00:00

158 lines
6.1 KiB
Python
Raw 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.

import functools
import os,sys
import threading
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
import thirdparty.py_trees as py_trees
from thirdparty.py_trees.trees import BehaviourTree
from core.behavior_tree import ReleaseFlowBuilder
from core.plugin import PluginManager
from core.defines import ReleasePhase, ProcessStep, ReleaseErr, Dict
from database import *
import core.logger as logger
log = logger.get_logger()
def draw_release_flow_status(snapshot_visitor, behaviour_tree):
"""保存行为树状态为HTML文件"""
mutex = threading.Lock()
with mutex:
# timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"alkaid_release_flow_status.html"
with open(filename, 'w') as f:
f.write('<html><head><title>SStar Alkaid Release Flow Status</title><body>')
f.write(py_trees.display.xhtml_tree(
behaviour_tree.root,
show_status=True,
visited=snapshot_visitor.visited,
previously_visited=snapshot_visitor.visited
))
f.write("</body></html>")
filename = f"alkaid_release_flow_status.dot"
with open(filename, 'w') as f:
f.write(str(py_trees.display.dot_tree(behaviour_tree.root, with_blackboard_variables=True)))
# log.info(f"Behavior tree saved to {filename}")
# 构建环境阶段 (验证配置、拉取code等基础环境的准备)
def _construct_env_phase(builder: ReleaseFlowBuilder, plugins: PluginManager):
with builder.sequence(ReleasePhase.ENV):
with builder.sequence(ProcessStep.PRE):
pass
with builder.sequence(ProcessStep.PROCESS):
if not ReleaseOptions.SkipSyncCode:
builder.action(plugins.BaseLine.PhaseEnv.Process())
with builder.sequence(ProcessStep.POST):
pass
# 配置编译文件阶段 defconfig mkfile 等编译控制文件的配置)
def _construct_config_phase(builder: ReleaseFlowBuilder, plugins: PluginManager):
with builder.sequence(ReleasePhase.CONFIG):
with builder.sequence(ProcessStep.PRE):
pass
with builder.sequence(ProcessStep.PROCESS):
pass
with builder.sequence(ProcessStep.POST):
pass
# 构建阶段(编译构建sdk根据上一步的配置执行编译构建)
def _construct_build_phase(builder: ReleaseFlowBuilder, plugins: PluginManager):
with builder.sequence(ReleasePhase.BUILD):
with builder.sequence(ProcessStep.PRE):
pass
with builder.sequence(ProcessStep.PROCESS):
pass
with builder.sequence(ProcessStep.POST):
pass
# 检查阶段检查SDK编译结果是否符合预期
def _construct_check_phase(builder: ReleaseFlowBuilder, plugins: PluginManager):
with builder.sequence(ReleasePhase.CHECK):
with builder.sequence(ProcessStep.PRE):
pass
with builder.sequence(ProcessStep.PROCESS):
pass
with builder.sequence(ProcessStep.POST):
pass
# 打包阶段 (将SDK其他文件诸如doctool等打包)
def _construct_package_phase(builder: ReleaseFlowBuilder, plugins: PluginManager):
with builder.sequence(ReleasePhase.PACKAGE):
with builder.sequence(ProcessStep.PRE):
pass
with builder.sequence(ProcessStep.PROCESS):
pass
with builder.sequence(ProcessStep.POST):
pass
# 验证阶段 (验证Release的SDK是否可以正常工作)
def _construct_verify_phase(builder: ReleaseFlowBuilder, plugins: PluginManager):
with builder.sequence(ReleasePhase.VERIFY):
with builder.sequence(ProcessStep.PRE):
pass
with builder.sequence(ProcessStep.PROCESS):
pass
with builder.sequence(ProcessStep.POST):
pass
class ReleaseFlow():
def __init__(self):
# 我们的Flow默认是一个串行的流程所以根节点用Sequence
self.builder = ReleaseFlowBuilder()
self.tree = None
self.flow = None
self.timer = None
self.status_update_interval = 1 # 定时器间隔时间,单位秒
self.running = False
# 构建 Alkaid Release流程
def construct(self, plugins: PluginManager):
with self.builder.sequence("AlkaidReleaseFlow") as builder:
_construct_env_phase(builder, plugins)
_construct_config_phase(builder, plugins)
_construct_build_phase(builder, plugins)
_construct_check_phase(builder, plugins)
_construct_package_phase(builder, plugins)
_construct_verify_phase(builder, plugins)
self.flow = self.builder.build()
def _start_update_status(self, snapshot_visitor):
"""启动定时器"""
if self.timer is not None:
return
def timer_callback():
if self.tree is not None:
draw_release_flow_status(snapshot_visitor, self.tree)
# 重新设置定时器
self.timer = threading.Timer(self.status_update_interval, timer_callback)
self.timer.start()
# 启动第一个定时器
self.timer = threading.Timer(self.status_update_interval, timer_callback)
self.tree.add_post_tick_handler(functools.partial(draw_release_flow_status, snapshot_visitor))
self.timer.start()
# 运行Release 流程
def run(self):
if self.flow is None:
raise ReleaseErr("Flow is not built")
# 使用封装好的BehaviourTree去管理流程
self.tree = BehaviourTree(root=self.flow)
snapshot_visitor = py_trees.visitors.SnapshotVisitor()
self.tree.visitors.append(snapshot_visitor)
self.tree.setup() # 初始化树
# 启动定时器
self._start_update_status(snapshot_visitor)
# print(
# py_trees.display.dot_tree(
# self.tree.root
# )
# )
self.tree.tick() # 触发tick进行执行
return self.tree.root.status
def shutdown(self):
if self.timer is not None:
self.timer.cancel()
self.timer = None
if self.tree is not None:
self.tree.shutdown()