TDesign 开源协作及基建
TDesign 开源协作及基建

TDesign 开源协作及基建

Tags
开源
组件库
基建
Published
May 30, 2022
Author
本文是我在 TDesign 开放生态日同名分享的文字稿,内容为 TDesign 开源过程中基础设施建设的探索实践。 总共分为四个部分:第一个部分是背景,第二个部分是 TDesign 在开源过程中的一些流程和工具,第三个部分是 TDesign 在 GitHub 上建设的一站式工作流,最后是总结和展望。

Part1 背景

熟悉的同学都知道 TDesign 是去年12月23日 开始正式对外开源。我们的内容也得从对外开源讲起。
notion image
对外开源,那我们究竟要做什么呢,如果要做得更加专业,背后隐含着什么工作呢?
开源是不是把源代码放到托管平台就好了?
要回答这个问题,我们可以这样来推导。要做什么,首先得思考目的是什么?
TDesign 为什么要开源,开源的目的和收益是什么?商业化吗,显然不是。
我列举了一些 TDesign 开源时候预期的收益
  • 更大体量的业务场景
  • 更多的测试资源
  • 更多的开源资源和 Code Review
  • 对外影响力
如果开源有这样的好处,有没有什么准入条件呢?如果只是开放源代码,我们就能拿到这样的收益,那显然这是一件在容易不过且没有门槛的事情。
我的答案是首先得提供基本吸引力和独特的用户价值去吸引社区参于贡献,形成一个杠杆,然后拿到收益。然后再加上社区的宣发和运营,以及到达开源基准规范的源代码,包括能够容纳反馈和贡献的工作流和基础设施。这样以来 TDesign 才能够吸引到一批受众,反过来,TDesign 吸引的开发者能够为 TDesign 的建设去做贡献,以提供更好的产品价值服务用户。
这样就是一个价值的正向循环:
notion image

Part2 开源流程和工具

说完开源杠杆和正循环的基本逻辑,我们可以看下 TDesign 的开源模式是:内网孵化,外网建设。
沉淀的流程和工具套件正是为了服务这个渐进式的过程。
notion image

2.1 需求分析

面对要服务的对象和问题,我们首先需要进行需求的分析。如下列举了一些开源的几种基准需求,除了专业规范的项目结构和代码质量等,当然也有一些未遇到过的棘手问题,比如说信息安全和舆论风险,以及部署基础设施的外网改造等。
notion image

2.2 开源风险应对

TDesign 要开源,为了提高开源影响力和竞争力,想要保留在内部开源协作过程中的代码记录,临近 TDesign 开源时候友商的组件库出现了开源过程后源代码的舆论,这个小插曲给 TDesign 提了个醒,需要我们对代码开放去进行一个更好的风险规避。
notion image
我们虽然有官方的开源审核流程 和 内部提供的代码检测能力,但是依然不能覆盖我们在源代码扫描和处理上的诉求,因为大部分开源项目都是开一个新仓库去重新开始,而 TDesign 更想要可以溯源的推出。
notion image
于是我们在开源办公室指引的代码检查能力上做了更多拓展和调研。
notion image

2.3 基础设施选型

解决完了上述应对风险的点,我们在对外开源做基础设施迁移时,也遇到了一些小问题。
我们在已经使用了如蓝盾/Oange CI/CDN-GO/腾讯云 COS 等内部基础设施和能力,到底哪些应该保留使用,哪些应该去寻找替代品呢。在讨论后,我们有一个比较基本的原则:对外开源应当尽可能的使用社区化的基础设施和资源。
原因有这么几个点:
  • 暂无公司级别的开源专项资源经费/降低核算成本
  • 内部基础设施的权限会影响到外部贡献者协作的流畅,并带来信息安全风险
  • 基础设施选型 follow 项目,是整体方案的一部分,部分不开放会影响开源效果
notion image
在此基础上我们会选行一些对更加匹配项目类型和对开发者更加友好的基础设施,包括以下几个选型。
一、流水线已知是我们已经重度使用了GitHub Actions,回顾一下原因有这么几点:
1. 平台集成,不需要绑定响应任何 WebHook
notion image
2. GitHub 丰富的开源集成生态市场,易于搭建
notion image
3. 配置即代码,大量的 CI/CD 就在代码旁边。能跟随代码仓库一起去进行版本管理。
notion image
4. 云端部署模型,GitHub 提供慷慨的计算资源。每个 workflow 会独享 1 核虚拟 CPU, 3.75GB 内存, 网络权限和 100GB 的磁盘空间, 感觉比我的 VPS 性能还好。
二、部署资源则是换到了 Surge,更加适合前端开发人员使用。
notion image

2.4 流程沉淀和套件集合复用

这个图就是 TDesign 开源过程中沉淀下来的一些流程,包括腾讯开源官方提供的获取资格/开源评审/开源发布这三个基础的流程。TDesign 自有比如收集贡献者信息/Git 重写以及一些基础设施迁移。同时沉淀了一些工具套件的集合和服务包括代码检查流水线、相似度检查工具、历史重写工具、GitHub Actions、腾讯云 Serverless、CodeCC、CDN Surge。
notion image

2.5 成果

  • 服务了14个仓库的迁移
  • 发现了平均200+的代码问题
  • 迁移效率提升3倍以上
  • 流水线相关资源零成本
  • ……

Part3 一站式工作流

notion image
第三部分的内容则是在 TDesign 在开源之后,主要服务对象变成了不限于内部建设的协作,如何容纳和保驾护航更多社区的反馈和贡献,成为了我们要思考和解决的问题。

3.1 场景分析

首先,我们对开源协作过程中的角色进行了分类,分别是使用者/贡献者/维护者。我们会尝试还原某一类场景中的协作过程。
如说下图是 TDesign 用户使用反馈的一个泳道图。
notion image

3.2 需求收集

除了独立分析之外,我们会去收集成员在协作过程中的一些痛点。不断的反馈建议,才是保证 TDesign 基础设施建设需求有效性的最佳手段。
notion image
痛点和需求很多,我们也有优先级和成本的一些考量,我们会把影响 TDesign 使用列为较高优先级,开发效率/开发体验/维护成本等增益性需求放到第二梯队。

3.3 实施规划

结合上述自主的场景分析和需求收集,我们形成了一张实施的全览图,TDesign 一站式工作流的蓝图。
下图标记了一些黄色的块,这些是专注在协作层面的,下文会用来举例呈现给读者。
notion image

3.4 ISSUE 生命周期

这是一张关于 issue 的流程图,TDesign 会在各个环节围绕场景进行标准化和自动化。
notion image
issue 模版:首先是 TDesign 的 issue 模版,大家可能会小看这个东西,甚至会觉得提高了反馈的门槛,但其实在 GitHub 这样一个异步沟通为主的平台,每次信息传递带来的高成本要求我们去提高信息的质量和带宽。TDesign 在这块做了一个 GitHub Page 用做 issue-helper 页面,可以帮助 TDesign 的使用者来标准化的反馈问题。同时,TDesign 利用了2021年 GitHub 内测的 issues-forms 模版,更加贴近平台减少反馈流失。
notion image
自动分配跟进人:第二步是有一个社区的反馈来了,那么我们如何承接这个问题。TDesign 有一个管理页面去把所有端/组件的维护者和设计师等都进行了管理,根据 issue 模版 check 过的反馈会指定对应组件并且附带端信息,触发了 issue 的相关流水线从这个管理页面拿到对应的关联维护人员,然后在对应 issue 下评论直接 @ 对应人员。读者可以在下图看到对应预览:
notion image
额外的触发贡献者通知:同时 TDesign 会有一些触发对贡献者的通知,包括定期的统计异常和未活动的告警。TDesign 每天统计各个仓库的一些未关闭的 issue Top10,对30天没有活动的 issue 去进行一个提醒。对用户 reopen 的 issue 再次去进行一个通知。
notion image
确认问题:如果某个 issue 已经有 TDesign 对应的维护着同学去跟进了,他首先要做的事情就是确认这个问题。TDesign 采取了标签分类的方式,比如说:
可以通过赋予一个 help 的标签。去告诉我们的开源社区这个问题是大家都可以来处理的,包括提问题的这个使用者;也可以去通过一个需要你提供一个实际用例的标签去提醒 TDesign 的这个反馈者,你可能需要提供一个实际的重现实例帮助维护着去更好的排查问题。
notion image
触发使用者通知:issue 的关闭,我们会通过版本发布和答复/修复去触发它。同时 TDesign 会定期的去把关闭的 issue 和 pull request 去对我们的用户进行一个通知。
notion image

3.5 组件库发版更新

TDesign 的发版更新也是比较独有:发布流程 iwiki 。它大概有三个特点:
第一个特点是基于 PR,目前我们已知市面上大部分开源项目都是基于仓库的 commit。
第二个特点是链路自动。
第三个特点是做到了很好的嵌入平台。
我们整个流程的自动化和标准化也是依据于规范,实际上,它也是规范/流程/技术工程的结合产物。
notion image
提交 Release PR:首先我们是需要去提一个 Release PR,整个流程重度依托于 GitHub Actions。利用 GitHub Actions 组合式条件的一个判断限定去触发特殊的流程。
notion image
name: Auto Release on: pull_request: branches: [develop] types: [opened, synchronize, reopened, closed] paths: - "package.json" issue_comment: types: [edited] jobs: generator: runs-on: ubuntu-latest if: > github.event_name == 'pull_request' && github.event.pull_request.merged == false && startsWith(github.head_ref, 'release/') steps: - run: echo "The head of this PR starts with 'release/'" - uses: actions/checkout@v3 - uses: 94dreamer/auto-release@develop id: changelog env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
生成间隔 PR 日志:然后根据 GitHub 开放 API 这样一个拉取日志的能力去查找对应的我们的日志。
async function generateLog() { const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf-8')) const [owner, repo] = context.payload.repository.full_name.split('/'); const releases = await octokit.rest.repos.generateReleaseNotes({ owner, repo, tag_name: pkg.version, target_commitish: 'develop', }); // 拉取 Release 包含对应的 PR const PRList = await Renderer.getPRNotes(releases.data.body); // 根据 PR 标签/分支/模版填写内容 输出对应日志 const logs = Renderer.renderMarkdown(PRList); core.setOutput('changelog', logs) }
评论 Release PR:第三步就是通过 GitHub Actions 的推送能力,把我们刚刚生成的日志同步到 TDesign 对应 PR 的内容区当中。
- name: 添加日志到 PR 的评论 uses: peter-evans/create-or-update-comment@v1 with: issue-number: ${{ github.event.pull_request.number }} body: | ${{ steps.changelog.outputs.changelog }}
notion image
推送文件改动 & Git Tag:只需要我们的维护者把这一行删掉,我们整体的文件改动包含 ChangeLog 的 GitHub 评论。ChangeLog 就会自动的提交到我们的仓库当中。这是一个提交 Commit 的实例,然后我们打 Tag 也是一样的。
name: Auto Release on: issue_comment: types: [edited] comment_add_log: runs-on: ubuntu-latest if: github.event.sender.login == github.event.issue.user.login steps: - name: 从文件改动读取版本号 id: comment run: echo "::set-output name=branch::${BASH_REMATCH[1]}" - name: checkout 到对应 PR 分支 uses: actions/checkout@v3 with: ref: ${{ steps.comment.outputs.branch }} - name: 推动更新日志到 CHANGELOG.md run: | txt=$(cat CHANGELOG.md) body='${{ github.event.comment.body }}' echo "${txt%%##*}${body}${txt##*---}" > CHANGELOG.md git add CHANGELOG.md git commit -m "chore: changelog's changes" git push
Build & Npm Publish:接下来我们会去对整个开源仓库进行一个 Build 和 Publish
notion image
官网部署 & 公告:接下来就是的一个自动化的官网部署和公告
notion image

3.5 流水线的复用

我们还有许多的工作流,同时我们有14个仓库,流水线的复用是时常被提及的一个问题。那怎么复用呢?
配置即代码,我复制粘贴不就好了吗
可以回答大家是,但是也不完全是。因为复制粘贴背后隐藏着维护时候的巨大成本。
这里给大家列举了一些 TDesign 在 Github Actions 流水线复用上的一些总结:
01、使用工作流模版
  • 组织共享,在 .github 存储库中定义
  • 类似 ISSUE 模版的 YAML 配置
  • 定义正则来匹配仓库
  • 支持创建时自定义更改
  • 无法同步更新,本质还是“配置及代码”的复制粘贴
02、“调用者”工作流
  • 工作流在同一个存储库或调用的工作流存储在公共存储库中
  • 定义“重用工作流”,可被满足条件流水线调用
  • 更易于维护和促进最佳实践
  • 无法调用“调用者”工作流,最多2级调用
  • 示例:TDesign 各仓库的的 PR 和 Publish 流水线由主仓库“重用工作流”提供,其他组件库还暂时没发现
03、自定义 Actions
  • 在公开仓库用编写自定义代码与调用仓库交互
  • 支持 JavaScript / Docker Actions 和 复合 Actions,拓展性强
  • 封装良好,支持发行版管理和版本使用
  • 步骤级别,无法串联工作流的步骤和其他 Actions
04、共享工作流工件
  • 工作流允许存储临时文件,可在工作流之间共享
  • GitHub 提供了上传和下载的 Actions
  • 只能共享结果
  • 场景:npm cache / 测试覆盖率报告 / 构建产物
05、跨仓库文件同步
  • 编写跨仓库同步工作流
  • 支持正则匹配中工作流文件到指定仓库和位置推送
  • 本质是自动化“配置即代码”的复制粘贴和 Git 提交
  • 子仓库修改冲突,强制一致性

3.6 成果

  • 服务了5000+次社区反馈和贡献
  • 发版时间成本降低了60%
  • ……

Part4 总结和展望

把 TDesign 的整个开源协作和基建做个总结,可以分为四个阶段:
第一个阶段我们是以解决问题为先,TDesign 开源的基建实际上是面对特定场景下问题的实践。
然后我们会去对这些问题中的重复问题的解决做工具化,实现单点工具,实际上是一个归类,我们会判断优先值和成本出发。
第三个阶段,我们是标准化和自动化的一个阶段。自动化的前提是要我们流程的标准化,当然规范的执行也要依靠自动化。
第四个环节就是系统和价值量化的过程,就是结合我们的平台、流程、规范以及技术工具的一个综合应用。近些年来比较流行的 devops 的一个思想,可能会跟他有点相似。
notion image
当然之间的演化离不开人和事情。目的就是为了服务人和事,组建库的发展才能够带动我们本身基础设施建设的诉求。
一个人的贡献也非常的难以支撑起来,一群人才能够走得更远,希望我们有更多的开发同学一起加入到我们 TDesign 组件库开发和基础设施的建设当中。