当前位置: 首页 > article >正文

利用流水线实现版本一键发布

目录

      • 1. 背景
      • 2. 实现步骤
        • 3.1 前置条件
        • 3.2 更新版本号和拉出发布分支
        • 3.3 生成 diffCommit
        • 3.4 自动触发联动编译
        • 3.5 让通知更友好
      • 3. 总结

1. 背景

通常我们发布版本时会有这样几个步骤,更改版本号,拉出 release 分支,生成发布包。但是博主所在的项目组有点特殊,整个项目分为两个工程,Unity 工程和 Android 工程,需要 unity 工程打出 aar 包,Android 工程引用这个 aar,然后生成 apk。
所以我们发版的时候会有以下一些步骤:

  1. 在主干分支上更新 Android 工程的 version_code 和 version_name;
  2. 拉出 Android 的发布分支;
  3. 拉出 Unity 的发布分支;
  4. 生成 Unity 的 aar 包,并更新到对应的 Android 发布分支上;
  5. 打出 apk;
  6. 记录当前发布分支和上个发布分支的差异提交(方便测试同学针对性测试);

这么一通操作下来,大半天都过去了。如果能有个按钮,按一下自动帮助我们完成这些步骤就好了,我想到了使用流水线的方式来实现。

2. 实现步骤

目前我们的项目都是使用 gitlab 进行托管的,所以一键版本发布的功能也是基于 gitlab 流水线来实现的。
最终,我们实现了能够一键触发版本发布,先来看看最终的实现效果:
如下所示为触发版本发布的 python 脚本,我们只需要输入对应的参数,就能够一键触发了。
传递的参数中,ref 表示分支名,variables[***] 会写入到 gitlab 的环境变量当中。

def trigerReleaseVersion(trigger, version_code, version_name, base_unity_branch, base_android_branch,
                         release_branch, pre_branch):
    token = "***"
    webhookUrl = "https://***/trigger/pipeline"
    data = {
        "token": token,
        "ref": base_android_branch,
        "variables[BUILD_TAG]": "releaseVersionBuild",
        "variables[TRIGGER]": trigger,
        "variables[VERSION_CODE]": version_code,
        "variables[VERSION_NAME]": version_name,
        "variables[BASE_UNITY_BRANCH]": base_unity_branch,
        "variables[RELEASE_BRANCH]": release_branch,
        "variables[PRE_BRANCH]": pre_branch
    }
    response = requests.post(webhookUrl, data=data)
    print(response.status_code)
    return response.status_code

当然也可以通过一些网络接口工具去触发
在这里插入图片描述

3.1 前置条件

我们在工程的 yml 文件当中增加一个专门用于版本发布的任务,并设置只有当环境变量 BUILD_TAG 的值为 releaseVersionBuild 时才会被触发,触发之后会执行我们的 python 脚本。

releaseVersionBuild:
  stage: build
  rules:
    - if: '$BUILD_TAG == "releaseVersionBuild"'
      when: always
  allow_failure: true
  script:
    - python3 main.py "releaseVersion"
  tags:
    - unity-ci
3.2 更新版本号和拉出发布分支

这一步相对来说比较容易,对于 Android 工程来说,我们需要修改版本号,提交变更,拉出发布分支,这几个功能都可以使用 python 的 git 库来实现。
1.clone 仓库并切换到指定的分支:

repo = git.Repo.clone_from(repo_url, directory)
repo.git.checkout(base_android_branch)

2.更改版本号,并提交代码:

with open(f'{directory}/gradle.properties', 'r') as file:
    content = file.read()
    origin = content

content = re.sub(r'VERSION_CODE=\d+', f'VERSION_CODE={version_code}', content)
content = re.sub(r'VERSION_NAME=.+', f'VERSION_NAME={version_name}', content)

if(origin == content):
    print("not change")
    print("不需要push新版本")
else:
    print("changed")
    with open(f'{directory}/gradle.properties', 'w') as file:
        file.write(content)

    repo.index.add(['gradle.properties'])
    repo.index.commit(f'更新版本号到{version_name}')
    repo.git.push('origin', base_android_branch)
    print("版本push成功")

3.拉出发布分支,并 push 到远端

repo.git.checkout('-b', release_branch, base_android_branch)
repo.git.push('origin', release_branch)

而对于 Unity 工程来说,我们并不需要修改版本号,所以可以直接使用 gitlab 的接口,触发创建发布分支

def createBranch(project_id, baseBranch, newBranch, privateToken):
    url = f"https://gitlab.***/api/v4/projects/{project_id}/repository/branches?branch={newBranch}&ref={baseBranch}"
    headers = {
        "PRIVATE-TOKEN": privateToken
    }
    response = requests.post(url, headers=headers)
    if response.status_code == 201:
        data = response.json()
        return (True,"")
    else:
        print(f"Error: {response.status_code}")
        print(response.json())
        return (False,response.text)
3.3 生成 diffCommit

获取两个分支之间的差异,虽然可以使用 git 指令,但如果本地操作,再将其保存为文档给到测试同学,而且每次更新都需要重新生成再给一份,想想都觉得麻烦。
所以我创建了一个飞书多维表格,专门用于记录不同分支之间的差异提交记录,而且 gitlab 接口也支持获取分支之间的差异提交,这样每次编译的时候,都获取一下差异提交,再更新到多维表格当中就可以了。

获取不同分支之间的差异提交:

def getCommitDiff(project_id, fromBranch, toBranch, private_token):
    url = f"https://gitlab.***/api/v4/projects/{project_id}/repository/compare"
    headers = {
        "PRIVATE-TOKEN": private_token
    }
    params = {
        "from": fromBranch,
        "to": toBranch
    }
    response = requests.get(url, headers=headers, params=params)
    if response.status_code == 200:
        data = response.json()
        commits = data['commits']
        return commits
    else:
        print(f"Error: {response.status_code}")
        print(response.json())
        return None

更新多维表格的记录可以参考飞书开放平台的文档:
https://open.feishu.cn/document/server-docs/docs/bitable-v1/notification

在这里插入图片描述
还有一个问题需要解决,就是当我们发版的时候指定了 preBranch ,也就是和当前分支的对比的发布分支。
本来是想着可以通过程序来计算前一个发布分支,比如当前的发布分支是 release/1.2,那么前一个发布分支就是 release/1.1,但是实际发现有的时候会有一些临时版本,例如 release/1.1.5 或者 release/1.1_temp 之类的特殊版本,所以还是需要人工手动指定。
人工指定完了之后,还需要有个地方记录,这样每次有了新的提交,都需要去获取前一个分支,然后重新进行对比。同样可以记录在多维表格当中。

在这里插入图片描述

3.4 自动触发联动编译

我们可以在 yml 文件里面创建一个任务,只要有任何变更就触发,这样代码提交的时候就会触发执行我们的 python 脚本,我们可以在脚本里面判断当前的分支,如果分支名是 release/*** ,那么就可以开始版本发布的编译流程。

defaultTask:
  stage: build
  rules:
    - changes:
        - '*'
      when: always
  resource_group: $CI_COMMIT_REF_NAME
  allow_failure: true
  script:
      - C:\\Application\\Python\\python.exe main.py "unityCompiler" #触发unity编译
  after_script:
    - C:\\Application\\Python\\python.exe main.py "triggerAndroid" #触发Android编译
  tags:
    - hmi3d-ci-windows

当 unity 编译完成之后,拿到了 aar 的版本号,此时可以触发 Android 流水线进行编译,并将aar 的版本号当作参数传递。其中 Android 发布分支和 unity 的发布分支的分支名是一样的。

def trigerAndroidProject(unityBranch, androidBranch, jobType, version, tag, user):
    token = "***"
    webhookUrl = "https://gitlab.***/trigger/pipeline"
    data = {
        "token": token,
        "ref": androidBranch,
        "variables[JOB_TYPE]": jobType,
        "variables[VERSION]": version, # aar的版本号
        "variables[BUILD_TAG]": tag,
        "variables[TRIGGER]": user,
        "variables[UNITY_COMMIT_MSG]": Utils.getLastCommitInfo(),
        "variables[UNITY_BRANCH]": unityBranch,
        "variables[ANDROID_BRANCH]": androidBranch,
        "variables[BUILD_TIME]": Utils.getCurrentDateTime()
    }
    response = requests.post(webhookUrl, data=data)
    print(response.status_code)
    return response.status_code

这样就能够实现代码提交之后,自动触发 Unity 和 Android 两个工程联动编译。

3.5 让通知更友好

当编译完成之后,可以让飞书机器人发送消息进行提醒,这样就可以避免需要主动去流水线上查看是否编译结束,而且飞书机器人当中也可以携带各种参数,显示当前的编译信息。
在这里插入图片描述

3. 总结

这样我们就可以实现版本一键发布,并让通知更加友好,包打出来之后,测试同学可以直接在群里面看到消息,并开始测试,不需要互相通知。


http://www.kler.cn/news/284248.html

相关文章:

  • 【生日视频制作】奔驰梅赛德斯小汽车提车交车仪式AE模板修改文字软件生成器教程特效素材【AE模板】
  • 【精选】基于Hadoop的热点事件分析的设计与实现(全网最新定制,独一无二)
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • deepin(深度)社区亮相2024 RISC-V中国峰会,全力推动RISC-V生态发展
  • Python中的“for循环”:探索其无限潜力
  • 别让努力付之东流!私域增长停滞不前的7大冲突解析
  • ThermoParser 介绍
  • 【设计模式-代理】
  • Java算法之选择排序(Selection Sort)
  • 神经网络—卷积层
  • Zookeeper的监听机制及原理解析
  • Selenium 自动化测试框架 API 详解
  • Nginx中的权重轮询机制:实现高效负载均衡
  • 使用Lora微调LLM——笔记
  • EmguCV学习笔记 VB.Net 第9章 视频操作
  • maven的5种打包方式:springboot-maven-plugin详解
  • 故障诊断 | 基于小波时频图与Swin Transformer的轴承故障诊断方法(PyTorch)
  • 4.2 python获取单元格的属性
  • 单片机-串口通信(二)
  • .NET Razor类库 - 静态资源组件化
  • Zoom iOS 转录例子
  • 何为大模型服务器?如何明智地挑选?
  • HTML爱心流星雨
  • 6种有效的时间序列数据特征工程技术(使用Python)
  • 产品经理角度分析:朋友圈点赞与评论仅共同好友可见
  • 华为 2024 届校园招聘-硬件通⽤/单板开发——第一套(部分题目分享,完整版带答案,共十套)
  • 【机器学习-监督学习】神经网络与多层感知机
  • 影视会员充值API接口如何开发?
  • 从插件plugin和钩子hook 到“智能化自动化”架构
  • ubuntu环境下部署LNMP集成环境超详细图文教程