0
点赞
收藏
分享

微信扫一扫

UI组件库接入Gitlab CICD实践

1 背景

目前部门维护自己的组件库(​​miui-desgin​​​),并发布到了公司私有的​​npm​​​库(由​​JFrog artifactory​​​搭建)。组件库几乎是照搬了​​antd​​​的文件组织结构和打包方式,而组件的使用说明文档也是使用了​​dumi​​。而组件库和文档的发布仍采取本地执行命令并发布的方式,虽然前期制定了发布流程和规范,但从结果上看,依然的存在很多的问题。例如:发布环境不统一、发布流程无法保证、发布流程需要一定的学习成本、每次发布都需要一定的时间成本等。并且随着项目越来越复杂,参与人数越来越多,以上问题会表现的更加的突出,最终导致的正式包内容的不可控。

而要解决解决手动发布组件库的问题,可以借助​​Gitlab CICD​​​的能力,将组件库的发布和文档的部署过程搬到线上来执行。不过由于大部分的开源项目在​​Github​​​上,且​​npm​​库的发布也并没有采用自动化,因此可以参考的开源组件自动发布流程并不多。不过借助网络上的零散资料和自身部门对组件库管理的规范,整理出如下的UI库自动发布方案。

2 方案

2.1 手动发布流程

组件库的发布包含两项发布工作,其一是UI库的发布,其二是组件使用文档的发布。根据部门制定的组件库发布规范,手动发的流程大体如下图所示:

UI组件库接入Gitlab CICD实践_Gitlab CICD

 ⚠ 说明

  • 更新version:由发布者按照​​语义版本控制​​​规范自行修改​​package.json​​​中的​​version​​字段的属性值。
  • 添加版本tag:按版本号加v表示tag名称(例如v1.1.1)。

2.2 发布流程拆分

根据部门目前​​UI​​​库的发布过程,结合​​Gitlab​​​的​​CICD​​​能力,可以将整个发布流程拆分为三个任务,分别是代码测试任务、​​UI​​库发布任务和文档打包部署任务。每个任务具体负责的工作如下图所示:

UI组件库接入Gitlab CICD实践_Gitlab CICD_02

相比于手动发布流程,自动发布流程添加了​​code test​​​和推送​​release​​​到​​Gitlab​​​两个子任务,这是为了更规范的发布​​UI​​库和文档。

2.3 自动发布流程

借助​​Gitlab​​​的​​CICD​​​能力,当代码合并到​​master​​​之后,会自动触发工作流。然后工作流会依次执行代码测试任务、​​UI​​​库发布任务和文档打包部署任务。同时为了保证​​UI​​​库和文档发布的严谨,在​​UI​​​库发布任务之前添加了审批环节,需要手动触发该任务的执行并经过审批后,才会执行​​UI​​库的发布和文档的部署。

UI组件库接入Gitlab CICD实践_Gitlab CICD_03

UI组件库接入Gitlab CICD实践_Gitlab CICD_04

2.4 UI库版本生成规则

​UI​​​库的发布过程借助了​​semantic-release​​​工具,其完成了​​UI​​​库发布任务中除了打包外的所有子任务。UI库版本的生成严格执行​​语义版本控制​​​规范(​​X.Y.Z​​​),并通过分析上次发布代码(当前最新​​tag​​​的代码)到当前代码新增的​​commit message​​来确定待发布的版本号。

版本生成规则如下:

  • ​fix​​​或​​perf​​​类型的提交,会将​​PATCH​​版本号加1
  • ​feat​​​类型的提交,会将​​MINOR​​版本号加1
  • 包含​​breaking change​​​字符串的提交,会将​​MAJOR​​号加1

如果一次发布过程中包含多个提交,则使用所有提交对应版本号中的最大值作为待发布的版本号。例如原版本号为1.2.3,当前代码相比于1.2.3的代码新增了1个​​fix​​​和1个​​feat​​提交,当前代码的版本号为1.3.0(即1.2.4和1.3.0中取较大的值)。

如果一次发布过程中的提交都没有命中版本生成规则,UI库发布的任务依然会执行,但由于没有UI库要发布的内容,会跳过本次的发布(不执行​​push​​​、​​release​​​、​​publish​​等操作)。从实际效果上看,这种情况下只会执行代码测试和文档的打包部署。这种场景对于只修改和发布说明文档很有意义,可以避免无意义的UI库版本的升级。

2.5 代码推送权限控制

为了更好的规范代码提交和发布流程,应该禁止普通开发者直接往​​master​​​提交代码,而是通过新建分支进行开发,之后再发送​​merge​​​请求合并到​​master​​​,经过代码​​review​​​和代码测试之后,最终合并进入​​master​​​,并触发组件库发布流程。​​Gitlab​​​本身支持设置保护分支和允许推送到​​master​​​的角色,一般情况下,可以设置只允许​​Maintainers​​​提交代码到​​master​​​,这样普通开发者便无法直接提交到​​master​​。

UI组件库接入Gitlab CICD实践_semantic-release_05

但由于历史原因,部门成员所在的组整体被赋予了​​Maintainers​​​角色,为了禁止开发者往​​master​​​提交代码,​​roles​​​需要选择​​No one​​​,而这又会导致​​release-bot​​​反向推送到​​master​​​失败。不过除了设置角色之外,​​Gitlab​​​还支持选择​​deploy key​​。

UI组件库接入Gitlab CICD实践_自动发布_06

可以按照官方文档的提示生成并配置​​deploy key​​​,同时将私钥配置到项目​​CICD​​​配置的环境变量中.。通过​​yml​​​文件的如下配置,可以在​​UI​​​库发布阶段,使用​​deploy key​​来反推代码到master。

before_script:
- mkdir -p <sub>/.ssh
# 将生成私钥写入.ssh中
- echo "$RELEASE_PRIVATE_KEY" > </sub>/.ssh/id_ed25519; chmod 0600 ~/.ssh/id_ed25519
- echo "StrictHostKeyChecking no " > /root/.ssh/config
# 重置origin
- git remote rm origin
- git remote add origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
- npm config set registry https://xxxx.xiaomi.net/xxxx/npm/mi-npm

3 流程源码

3.1 依赖

项目使用​​semantic-release​​工具来发布UI库,需要提前安装以下的依赖。

  • ​@semantic-release​
  • ​@semantic-release/commit-analyzer​
  • ​@semantic-release/release-notes-generator​
  • ​@semantic-release/changelog​
  • ​@semantic-release/gitlab​
  • ​@semantic-release/npm​
  • ​@semantic-release/git​

3.2 CICD环境变量

需要配置的环境变量有三个:

  • ​NPM_TOKEN​​​:​​@semantic-release/npm​​发布包到私有源会默认读取该参数。
  • ​GITLAB_TOKEN​​​:​​@semantic-release/gitlab​​​发布​​release​​​到​​Gitlab​​会读取该参数。
  • ​RELEASE_PRIVATE_KEY​​​:​​deploy key​​​对应的私钥,用于反向推送版本修改信息和​​changelog​​​到​​master​​。

3.3 YML配置

# 规则
.rules:
- &is-merge-request-to-production
if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $PRODUCTION_BRANCH
# 生产分支 + 不是由发布机器人反推的commit
- &is-release
if: $CI_COMMIT_REF_NAME != $PRODUCTION_BRANCH || $CI_COMMIT_TITLE =<sub> /^chore:\srelease\s/
when: never

# 设置环境变量默认值
variables:
# 打包反向推送tag、changelog的git用户名
GIT_AUTHOR_NAME: 'release-bot'
PRODUCTION_BRANCH: 'master'
# 审批人
CI_APPROVER: xxx@xiaomi.com

default:
image: node:14-alpine
before_script:
# 设置为小米私有源
- npm config set registry https://xxxx.xiaomi.net/xxxx/npm/mi-npm

cache:
key: $CI_PROJECT_ID
paths:
- node_modules

stages:
- test
- publish_npm
- deploy_docs

test:
stage: test
script:
- yarn
- yarn test
rules:
- *is-merge-request-to-production
- *is-release
- when: on_success

build_and_publish_npm:
stage: publish_npm
# node14 + git 环境
image: timbru31/node-alpine-git:14
approval: true
before_script:
- mkdir -p </sub>/.ssh
- echo "$RELEASE_PRIVATE_KEY" > <sub>/.ssh/id_ed25519; chmod 0600 </sub>/.ssh/id_ed25519
- echo "StrictHostKeyChecking no " > /root/.ssh/config
- git remote rm origin
- git remote add origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
- npm config set registry https://xxxx.xiaomi.net/xxxx/npm/mi-npm
script:
- yarn
- yarn build
- yarn semantic-release
rules:
- *is-release
- when: manual


build_and_deploy_docs:
stage: deploy_docs
script:
- yarn
- yarn deploy:site
rules:
- *is-release
- when: on_success

3.4 releaserc配置

{
"branches": ["master"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
"@semantic-release/gitlab",
"@semantic-release/npm",
[
"@semantic-release/git",
{
"assets": ["package.json", "CHANGELOG.md"],
"message": "chore: release ${nextRelease.version}"
}
]
]
}

4 结语

通过以上的改造,基本上解决了手动发布带来的所有问题,使得整个发布过程变得更加的规范可控。同时对于开发者来说,也无需花费时间来学习发布的流程,组件库的发布对于开发者来说只需要点击按钮申请发布就可以了。需要注意的是,在该流程下,​​changelog​​​和版本号的生成严重的依赖​​commit message​​​,为了更好的规范​​commit message​​​的格式,可以借助​​lint-staged​​​插件在代码提交时对其进行校验(​​miui-design​​项目中已添加该配置,因此本文不再赘述)。

不过以上的方案也存在一个问题,就是只能发布正式版本的包而无法发布​​alpha​​​或者​​beta​​​版本的包,我猜测这可能也是开源库没有采用自动化发布的原因之一。不过由于目前部门维护的组件库并不会发布​​alpha​​​或者​​beta​​版本,因此暂时没有这个问题,以后有机会再研究一下。

举报

相关推荐

0 条评论