[{"data":1,"prerenderedAt":425},["ShallowReactive",2],{"content-doc-\u002Fzh\u002Fblogs\u002F20250726":3,"surround-\u002Fzh\u002Fblogs\u002F20250726":423},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"category":11,"author":12,"body":16,"_type":415,"_id":416,"_source":417,"_file":418,"_stem":419,"_extension":420,"coverImage":59,"plainText":421,"authorNames":422},"\u002Fzh\u002Fblogs\u002F20250726","blogs",false,"","商业实践 | openUBMC社区开发流水线使能长江计算高质量交付","在软件开发流程中，构建环节至关重要，它直接影响着开发效率与软件质量。为保证openUBMC的本地化部署并提升开发效率，长江计算提出了一套面向企业开发者的构建方案与流水线构建方案。这一套基于离线部署的方案，涵盖了基础设施配置、构建方案设计等方面，有助于深入理解openUBMC构建体系的搭建与优化。","2025\u002F07\u002F26","case",[13],{"name":14,"description":15},"易重辉","武汉长江计算科技有限公司BMC软件开发工程师，专注openUBMC软件开发领域，在BMC构建方面有较深入的研究与丰富的实践经验，对开发流程优化有独到见解",{"type":17,"children":18,"toc":396},"root",[19,27,34,39,45,52,62,67,72,78,85,90,96,104,109,114,119,124,130,136,143,148,174,179,192,198,205,210,217,222,228,235,240,247,252,258,263,270,275,318,323,329,334,341,349,354,362,367,375,380,385,391],{"type":20,"tag":21,"props":22,"children":24},"element","h1",{"id":23},"商业实践-openubmc社区开发流水线使能长江计算高质量交付",[25],{"type":26,"value":8},"text",{"type":20,"tag":28,"props":29,"children":31},"h2",{"id":30},"一引言",[32],{"type":26,"value":33},"一、引言",{"type":20,"tag":35,"props":36,"children":37},"p",{},[38],{"type":26,"value":9},{"type":20,"tag":28,"props":40,"children":42},{"id":41},"二基础设施配置",[43],{"type":26,"value":44},"二、基础设施配置",{"type":20,"tag":46,"props":47,"children":49},"h3",{"id":48},"一-基础设施与资源更新总览",[50],{"type":26,"value":51},"（一） 基础设施与资源更新总览",{"type":20,"tag":35,"props":53,"children":54},{},[55],{"type":20,"tag":56,"props":57,"children":61},"img",{"alt":58,"src":59,"title":60},"images","\u002Fcategory\u002Fblog\u002F20250726\u002Fimg01.webp","基础设施结构与资源更新方法",[],{"type":20,"tag":35,"props":63,"children":64},{},[65],{"type":26,"value":66},"如同大多数公司一致，长江计算的开发活动主要位于纯内网环境，因此如何将社区的基础设施与公司常用的基础设施兼容是拥抱社区的一大难题。基于常用场景，长江计算设计了一套技术解决方案，将openUBMC社区的相关开发资源，经过外网-非涉密内网-涉密内网的单向数据流形式，部署到基础设施。这样的网络架构旨在保障数据安全与开发环境的稳定性。",{"type":20,"tag":35,"props":68,"children":69},{},[70],{"type":26,"value":71},"因安全性而引入的额外部署流程，需要通过自动化提升效率。因此，在长江计算的部署流程中，源码和Conan组件的跨网络传输均支持脚本化的方式自动化运行。",{"type":20,"tag":46,"props":73,"children":75},{"id":74},"二基础设施配置简介",[76],{"type":26,"value":77},"（二）基础设施配置简介",{"type":20,"tag":35,"props":79,"children":80},{},[81],{"type":20,"tag":56,"props":82,"children":84},{"alt":58,"src":83},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg02.webp",[],{"type":20,"tag":35,"props":86,"children":87},{},[88],{"type":26,"value":89},"长江计算为 openUBMC 的本地化部署配置的基础设施具备功能完整性、易用性和安全性，为自研openUBMC商用发行版提供了坚实的技术支撑，有力地推动了BMC软件开发流程的规范化和高效化，对于其他企业开发者在构建类似的开发环境和流程方面具有一定的参考价值和借鉴意义。",{"type":20,"tag":28,"props":91,"children":93},{"id":92},"三开发者构建方案",[94],{"type":26,"value":95},"三、开发者构建方案",{"type":20,"tag":35,"props":97,"children":98},{},[99],{"type":20,"tag":56,"props":100,"children":103},{"alt":58,"src":101,"title":102},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg03.webp","构建镜像在开发者构建中的配置与使用",[],{"type":20,"tag":35,"props":105,"children":106},{},[107],{"type":26,"value":108},"构建Docker镜像是开发者构建和流水线构建的基础。构建Docker镜像上传到编译服务器可直接为开发者构建服务；而上传到容器镜像仓则是为流水线构建服务。",{"type":20,"tag":35,"props":110,"children":111},{},[112],{"type":26,"value":113},"在编译服务器上，为每位开发者创建独立编译容器，这样的设计保障了每位开发者的开发环境相对独立，避免相互干扰。",{"type":20,"tag":35,"props":115,"children":116},{},[117],{"type":26,"value":118},"开发者可以通过SSH连接到编译容器，在容器内进行开发工作。实际场景中，开发者可以在涉密台式机环境下，借助预处理好的编译容器，专注于代码编写与调试，无需过多关注环境配置等复杂问题，从而提高开发效率。",{"type":20,"tag":35,"props":120,"children":121},{},[122],{"type":26,"value":123},"另外，长江计算的编译容器支持个人数据持久化，同时也拥有只读公共目录。这样的设计便于后期维护时升级编译环境和开发材料传递。",{"type":20,"tag":28,"props":125,"children":127},{"id":126},"四流水线构建方案",[128],{"type":26,"value":129},"四、流水线构建方案",{"type":20,"tag":46,"props":131,"children":133},{"id":132},"一流水线需求分析",[134],{"type":26,"value":135},"（一）流水线需求分析",{"type":20,"tag":35,"props":137,"children":138},{},[139],{"type":20,"tag":56,"props":140,"children":142},{"alt":58,"src":141},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg04.webp",[],{"type":20,"tag":35,"props":144,"children":145},{},[146],{"type":26,"value":147},"代码门禁需求：",{"type":20,"tag":149,"props":150,"children":151},"ul",{},[152,164],{"type":20,"tag":153,"props":154,"children":155},"li",{},[156,162],{"type":20,"tag":157,"props":158,"children":159},"strong",{},[160],{"type":26,"value":161},"组件门禁流水线：",{"type":26,"value":163}," 当组件代码合入时，触发门禁检查，包括静态代码检查、单元测试以及单元测试覆盖率计算等，只有通过这些检查，代码才能顺利合入，确保组件代码的质量。",{"type":20,"tag":153,"props":165,"children":166},{},[167,172],{"type":20,"tag":157,"props":168,"children":169},{},[170],{"type":26,"value":171},"产品门禁流水线：",{"type":26,"value":173}," 产品版本因组件版本变化时，需要进行门禁检查，主要验证是否能构建出产品包，保障产品版本的完整性和可用性。",{"type":20,"tag":35,"props":175,"children":176},{},[177],{"type":26,"value":178},"版本构建发布需求：",{"type":20,"tag":149,"props":180,"children":181},{},[182,187],{"type":20,"tag":153,"props":183,"children":184},{},[185],{"type":26,"value":186},"组件版本发布时，需构建出二进制并归档，方便后续的使用与管理。",{"type":20,"tag":153,"props":188,"children":189},{},[190],{"type":26,"value":191},"产品转测版本发布时，要构建出 hpm 包并归档，同时触发冒烟测试，初步验证产品版本的基本功能是否正常。",{"type":20,"tag":46,"props":193,"children":195},{"id":194},"二组件流水线设计总览",[196],{"type":26,"value":197},"（二）组件流水线设计总览",{"type":20,"tag":35,"props":199,"children":200},{},[201],{"type":20,"tag":56,"props":202,"children":204},{"alt":58,"src":203},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg05.webp",[],{"type":20,"tag":35,"props":206,"children":207},{},[208],{"type":26,"value":209},"组件仓Merge合入时，会触发组件门禁流水线，此时会拉取组件代码，执行合入门禁检查，包括 静态代码检查、单元测试和组件出包校验，将检查结果反馈给开发人员。门禁检查结果将作为是否合入的标准。",{"type":20,"tag":35,"props":211,"children":212},{},[213],{"type":20,"tag":56,"props":214,"children":216},{"alt":58,"src":215},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg06.webp",[],{"type":20,"tag":35,"props":218,"children":219},{},[220],{"type":26,"value":221},"当涉及组件版本发布时，需要定时或者手动触发组件构建流水线，此时会拉取组件代码，进行版本构建，将组件版本发布到 Conan 仓库，实现组件的更新与共享。",{"type":20,"tag":46,"props":223,"children":225},{"id":224},"三产品流水线设计总览",[226],{"type":26,"value":227},"（三）产品流水线设计总览",{"type":20,"tag":35,"props":229,"children":230},{},[231],{"type":20,"tag":56,"props":232,"children":234},{"alt":58,"src":233},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg07.webp",[],{"type":20,"tag":35,"props":236,"children":237},{},[238],{"type":26,"value":239},"manifest仓代码Merge合入时，会触发产品门禁流水线，拉取组件代码，执行合入门禁检查，同时进行产品出包校验，确保能生成完整的产品包，之后可触发签名请求，保障产品安全性。",{"type":20,"tag":35,"props":241,"children":242},{},[243],{"type":20,"tag":56,"props":244,"children":246},{"alt":58,"src":245},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg08.webp",[],{"type":20,"tag":35,"props":248,"children":249},{},[250],{"type":26,"value":251},"当涉及产品版本发布时，需要定时或者手动触发产品构建流水线，拉取组件代码，执行版本构建，发布产品版本，并进行冒烟测试，全面验证产品性能与功能",{"type":20,"tag":46,"props":253,"children":255},{"id":254},"四流水线在软件开发过程中的模拟运用",[256],{"type":26,"value":257},"（四）流水线在软件开发过程中的模拟运用",{"type":20,"tag":35,"props":259,"children":260},{},[261],{"type":26,"value":262},"为说明4种流水线的作用和机制，本文使用箭头表示各种类型的流水线来模拟三个组件（A、B、C）与产品的构建与发布过程。其中蓝色向下的箭头是门禁流水线，青色向右是构建流水线；黑色边框为组件流水线，红色边框是产品流水线。",{"type":20,"tag":35,"props":264,"children":265},{},[266],{"type":20,"tag":56,"props":267,"children":269},{"alt":58,"src":268},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg09.webp",[],{"type":20,"tag":35,"props":271,"children":272},{},[273],{"type":26,"value":274},"由上图过程可知：此流水线的设计能深度贴合软件工程过程。",{"type":20,"tag":149,"props":276,"children":277},{},[278,288,298,308],{"type":20,"tag":153,"props":279,"children":280},{},[281,286],{"type":20,"tag":157,"props":282,"children":283},{},[284],{"type":26,"value":285},"一般多次特性合入才会发布版本：",{"type":26,"value":287}," 不管是组件还是产品，历经多次门禁流水线再通过一次构建流水线来发布版本。",{"type":20,"tag":153,"props":289,"children":290},{},[291,296],{"type":20,"tag":157,"props":292,"children":293},{},[294],{"type":26,"value":295},"保证产品仓一定能正常构建出版本：",{"type":26,"value":297}," 只有当组件完成构建流水线发布之后，通过修改manifest仓库并合入来触发的产品门禁流水线才能成功。反之，如果组件未经过构建，那么产品门禁流水线一定会因为缺对应组件而失败报错；",{"type":20,"tag":153,"props":299,"children":300},{},[301,306],{"type":20,"tag":157,"props":302,"children":303},{},[304],{"type":26,"value":305},"多组件依赖的产品版本更新：",{"type":26,"value":307}," 涉及到多组件依赖的需求时，多个组件的版本更新可以在产品的一次合入请求中实现。",{"type":20,"tag":153,"props":309,"children":310},{},[311,316],{"type":20,"tag":157,"props":312,"children":313},{},[314],{"type":26,"value":315},"产品仓的版本发布与组件版本发布分离：",{"type":26,"value":317}," 组件通过构建流水线发布版本后，并不一定要立即合入到产品仓，完全按组件和产品自身的开发节奏进行发布和版本搭配。",{"type":20,"tag":35,"props":319,"children":320},{},[321],{"type":26,"value":322},"通过组件门禁流水线、产品门禁流水线、组件构建流水线以及产品构建流水线的协同工作，全方位保障软件开发过程的质量与效率。门禁流水线对代码合入进行严格检查，构建流水线则负责版本的构建与发布，使得软件开发能按照既定的流程和标准顺利推进。",{"type":20,"tag":28,"props":324,"children":326},{"id":325},"五场景交流",[327],{"type":26,"value":328},"五、场景交流",{"type":20,"tag":35,"props":330,"children":331},{},[332],{"type":26,"value":333},"部署场景 ：企业自建 Conan 仓，需要将社区 Conan 二进制迁移到企业自己的开发环境中去。",{"type":20,"tag":35,"props":335,"children":336},{},[337],{"type":20,"tag":56,"props":338,"children":340},{"alt":58,"src":339},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg10.webp",[],{"type":20,"tag":35,"props":342,"children":343},{},[344],{"type":20,"tag":56,"props":345,"children":348},{"alt":58,"src":346,"title":347},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg11.webp","方案一的仓库数据更新方式",[],{"type":20,"tag":35,"props":350,"children":351},{},[352],{"type":26,"value":353},"方案一 ：通过仓库级联，将社区 Conan 仓接入到企业本地 Conan 仓库。理论上能下载到社区所有二进制，这种方法适用于实时能和社区仓库沟通的场景，操作相对简便，但可能存在网络稳定性以及权限控制等问题。",{"type":20,"tag":35,"props":355,"children":356},{},[357],{"type":20,"tag":56,"props":358,"children":361},{"alt":58,"src":359,"title":360},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg12.webp","方案二的仓库数据更新方式",[],{"type":20,"tag":35,"props":363,"children":364},{},[365],{"type":26,"value":366},"方案二 ：通过 conan download 下载，再上传到企业本地 conan 仓库。理论上也能下载到社区所有二进制。",{"type":20,"tag":35,"props":368,"children":369},{},[370],{"type":20,"tag":56,"props":371,"children":374},{"alt":58,"src":372,"title":373},"\u002Fcategory\u002Fblog\u002F20250726\u002Fimg13.webp","方案三的仓库数据更新方式",[],{"type":20,"tag":35,"props":376,"children":377},{},[378],{"type":26,"value":379},"方案三 ：通过 bingo 构建来下载，再上传到本地 Conan 仓库。这种方式只能下载某个组件、产品版本依赖的二进制，针对性较强，但无法获取社区全部二进制，不过它在处理特定依赖关系时较为实用。",{"type":20,"tag":35,"props":381,"children":382},{},[383],{"type":26,"value":384},"总之，如果能够访问到openUBMC社区的官方Conan远端，那么选择方案一做级联；如果想做离线部署，则选择方案二；如果只是需要打包特定某个组件、产品依赖的二进制，则选择方案三。",{"type":20,"tag":28,"props":386,"children":388},{"id":387},"六总结",[389],{"type":26,"value":390},"六、总结",{"type":20,"tag":35,"props":392,"children":393},{},[394],{"type":26,"value":395},"长江计算基于 openUBMC 的开发者构建与流水线构建实践展示了完整且系统的构建流程搭建。从基础设施的合理配置到开发者构建的便捷实现，再到流水线构建的精细化设计，以及对Conan远端本地化部署的有效应对策略，都给予了openUBMC社区开发者诸多启示。在实际开发过程中，开发者可以借鉴这些实践经验，结合自身项目特点，不断优化构建体系，提升开发效率，保障软件质量，从而在激烈的市场竞争中占据有利地位，加速软件产品的交付与迭代，更好地满足用户需求与市场变化。",{"title":7,"searchDepth":397,"depth":397,"links":398},4,[399,401,406,407,413,414],{"id":30,"depth":400,"text":33},2,{"id":41,"depth":400,"text":44,"children":402},[403,405],{"id":48,"depth":404,"text":51},3,{"id":74,"depth":404,"text":77},{"id":92,"depth":400,"text":95},{"id":126,"depth":400,"text":129,"children":408},[409,410,411,412],{"id":132,"depth":404,"text":135},{"id":194,"depth":404,"text":197},{"id":224,"depth":404,"text":227},{"id":254,"depth":404,"text":257},{"id":325,"depth":400,"text":328},{"id":387,"depth":400,"text":390},"markdown","content:zh:blogs:20250726.md","content","zh\u002Fblogs\u002F20250726.md","zh\u002Fblogs\u002F20250726","md","商业实践 | openUBMC社区开发流水线使能长江计算高质量交付 一、引言 在软件开发流程中，构建环节至关重要，它直接影响着开发效率与软件质量。为保证openUBMC的本地化部署并提升开发效率，长江计算提出了一套面向企业开发者的构建方案与流水线构建方案。这一套基于离线部署的方案，涵盖了基础设施配置、构建方案设计等方面，有助于深入理解openUBMC构建体系的搭建与优化。 二、基础设施配置 （一） 基础设施与资源更新总览  如同大多数公司一致，长江计算的开发活动主要位于纯内网环境，因此如何将社区的基础设施与公司常用的基础设施兼容是拥抱社区的一大难题。基于常用场景，长江计算设计了一套技术解决方案，将openUBMC社区的相关开发资源，经过外网-非涉密内网-涉密内网的单向数据流形式，部署到基础设施。这样的网络架构旨在保障数据安全与开发环境的稳定性。 因安全性而引入的额外部署流程，需要通过自动化提升效率。因此，在长江计算的部署流程中，源码和Conan组件的跨网络传输均支持脚本化的方式自动化运行。 （二）基础设施配置简介  长江计算为 openUBMC 的本地化部署配置的基础设施具备功能完整性、易用性和安全性，为自研openUBMC商用发行版提供了坚实的技术支撑，有力地推动了BMC软件开发流程的规范化和高效化，对于其他企业开发者在构建类似的开发环境和流程方面具有一定的参考价值和借鉴意义。 三、开发者构建方案  构建Docker镜像是开发者构建和流水线构建的基础。构建Docker镜像上传到编译服务器可直接为开发者构建服务；而上传到容器镜像仓则是为流水线构建服务。 在编译服务器上，为每位开发者创建独立编译容器，这样的设计保障了每位开发者的开发环境相对独立，避免相互干扰。 开发者可以通过SSH连接到编译容器，在容器内进行开发工作。实际场景中，开发者可以在涉密台式机环境下，借助预处理好的编译容器，专注于代码编写与调试，无需过多关注环境配置等复杂问题，从而提高开发效率。 另外，长江计算的编译容器支持个人数据持久化，同时也拥有只读公共目录。这样的设计便于后期维护时升级编译环境和开发材料传递。 四、流水线构建方案 （一）流水线需求分析  代码门禁需求： 组件门禁流水线：  当组件代码合入时，触发门禁检查，包括静态代码检查、单元测试以及单元测试覆盖率计算等，只有通过这些检查，代码才能顺利合入，确保组件代码的质量。 产品门禁流水线：  产品版本因组件版本变化时，需要进行门禁检查，主要验证是否能构建出产品包，保障产品版本的完整性和可用性。 版本构建发布需求： 组件版本发布时，需构建出二进制并归档，方便后续的使用与管理。 产品转测版本发布时，要构建出 hpm 包并归档，同时触发冒烟测试，初步验证产品版本的基本功能是否正常。 （二）组件流水线设计总览  组件仓Merge合入时，会触发组件门禁流水线，此时会拉取组件代码，执行合入门禁检查，包括 静态代码检查、单元测试和组件出包校验，将检查结果反馈给开发人员。门禁检查结果将作为是否合入的标准。  当涉及组件版本发布时，需要定时或者手动触发组件构建流水线，此时会拉取组件代码，进行版本构建，将组件版本发布到 Conan 仓库，实现组件的更新与共享。 （三）产品流水线设计总览  manifest仓代码Merge合入时，会触发产品门禁流水线，拉取组件代码，执行合入门禁检查，同时进行产品出包校验，确保能生成完整的产品包，之后可触发签名请求，保障产品安全性。  当涉及产品版本发布时，需要定时或者手动触发产品构建流水线，拉取组件代码，执行版本构建，发布产品版本，并进行冒烟测试，全面验证产品性能与功能 （四）流水线在软件开发过程中的模拟运用 为说明4种流水线的作用和机制，本文使用箭头表示各种类型的流水线来模拟三个组件（A、B、C）与产品的构建与发布过程。其中蓝色向下的箭头是门禁流水线，青色向右是构建流水线；黑色边框为组件流水线，红色边框是产品流水线。  由上图过程可知：此流水线的设计能深度贴合软件工程过程。 一般多次特性合入才会发布版本：  不管是组件还是产品，历经多次门禁流水线再通过一次构建流水线来发布版本。 保证产品仓一定能正常构建出版本：  只有当组件完成构建流水线发布之后，通过修改manifest仓库并合入来触发的产品门禁流水线才能成功。反之，如果组件未经过构建，那么产品门禁流水线一定会因为缺对应组件而失败报错； 多组件依赖的产品版本更新：  涉及到多组件依赖的需求时，多个组件的版本更新可以在产品的一次合入请求中实现。 产品仓的版本发布与组件版本发布分离：  组件通过构建流水线发布版本后，并不一定要立即合入到产品仓，完全按组件和产品自身的开发节奏进行发布和版本搭配。 通过组件门禁流水线、产品门禁流水线、组件构建流水线以及产品构建流水线的协同工作，全方位保障软件开发过程的质量与效率。门禁流水线对代码合入进行严格检查，构建流水线则负责版本的构建与发布，使得软件开发能按照既定的流程和标准顺利推进。 五、场景交流 部署场景 ：企业自建 Conan 仓，需要将社区 Conan 二进制迁移到企业自己的开发环境中去。   方案一 ：通过仓库级联，将社区 Conan 仓接入到企业本地 Conan 仓库。理论上能下载到社区所有二进制，这种方法适用于实时能和社区仓库沟通的场景，操作相对简便，但可能存在网络稳定性以及权限控制等问题。  方案二 ：通过 conan download 下载，再上传到企业本地 conan 仓库。理论上也能下载到社区所有二进制。  方案三 ：通过 bingo 构建来下载，再上传到本地 Conan 仓库。这种方式只能下载某个组件、产品版本依赖的二进制，针对性较强，但无法获取社区全部二进制，不过它在处理特定依赖关系时较为实用。 总之，如果能够访问到openUBMC社区的官方Conan远端，那么选择方案一做级联；如果想做离线部署，则选择方案二；如果只是需要打包特定某个组件、产品依赖的二进制，则选择方案三。 六、总结 长江计算基于 openUBMC 的开发者构建与流水线构建实践展示了完整且系统的构建流程搭建。从基础设施的合理配置到开发者构建的便捷实现，再到流水线构建的精细化设计，以及对Conan远端本地化部署的有效应对策略，都给予了openUBMC社区开发者诸多启示。在实际开发过程中，开发者可以借鉴这些实践经验，结合自身项目特点，不断优化构建体系，提升开发效率，保障软件质量，从而在激烈的市场竞争中占据有利地位，加速软件产品的交付与迭代，更好地满足用户需求与市场变化。",[14],[424,424],null,1785415973904]