背景
1.因为我们的现场版本发布是比较频繁的,关于本次发布为了解决什么问题,修复了什么BUG。这个全靠项目经理自觉,并不是每次发布都有写,也不一定每次都能写的全,我想有一个能兜底的机制。
2.这个时候我想起了github发布版本时有一个“auto-generate release notes”功能,它通过 git logs 命令,将两次版本变化之间的git message信息导出成markdown格式的文档,如果我们的gitea有这样一个工具,那就太棒了。
3.在gitea官网和github上进行了查阅,发现gitea目前不打算抄这个功能,未来也不会做,而我们的git服务端用的是gitea,于是我想通过drone CI流水线来实现这个功能。
4.通过查阅,我发现nodejs有一个很火的工具https://github.com/conventional-changelog/standard-version 能够完成这件事,只要我们开发人员提交的 git message是符合https://www.conventionalcommits.org/和https://semver.org/规范的即可。
5.根据这个规范,找到vscode里有一个插件”Conventional Commits”工具是非常契合的。
6.结局是我们的开发人员,只需要在vscode上安装好这个”Conventional Commits”工具,并且根据工具提示来提交代码,后续就可以自动生成changelog了,从而达到标准化“代码提交”和“发布日志”的目的
效果图
下面这个Changelog由发布之后的流水线自动生成
开发人员做什么
在vscode里下载该插件,插件扩展ID vivaxy.vscode-conventional-commits
提交代码的时候,按照工具提示一路选择即可
运维人员做什么
根据https://github.com/conventional-changelog/standard-version库来编写一个简单的流水线工具
这里我用的代码是python,流水线运行环境是DroneCI,git服务端是gitea
废话不多说,下面直接上代码,可以通过 docker build命令
docker build -t drone-changelog-plugin:1.0.1 .
去制作drone的流水线镜像
main.py
import os import shutil import requests def search_tag_info(git_url,token, repo): ''' 搜索git上的tag信息 :param git_url: git 的地址 :param token: git 的access token :param repo: git 待查询的git仓库信息 :return: tag信息集合 ''' url = "https://"+git_url+"/api/v1/repos/" + repo + "/releases" headers = {'accept': 'application/json', 'Authorization': 'token ' + token, 'Content-Type': 'application/json' } response = requests.get(url, headers=headers) tag_list = response.json() return tag_list def modify_tag_body(git_url,token, repo, tag_id, body): ''' 修改git仓库的tag里的内容 :param git_url: git 的地址 :param token: git 的access token :param repo: git 待查询的git仓库信息 :param tag_id: git tag的id信息 :param body: 需要修改的内容,一般是changelog.md文件 :return: ''' url = "https://"+git_url+"/api/v1/repos/" + repo + "/releases/" + str(tag_id) headers = {'accept': 'application/json', 'Authorization': 'token ' + token, 'Content-Type': 'application/json' } body = { "body": body } response = requests.patch(url, json=body, headers=headers) if __name__ == '__main__': print(os.environ) tag = os.environ["DRONE_TAG"] branch = os.environ["DRONE_REPO_BRANCH"] username = os.environ["DRONE_NETRC_USERNAME"] password = os.environ["DRONE_NETRC_PASSWORD"] git_repo = os.environ["DRONE_REPO"] git_token = os.environ["PLUGIN_TOKEN"] src_file = "/lzw/.versionrc" dst_foleder = os.environ["DRONE_WORKSPACE"] git_url= os.environ["PLUGIN_GIT_SERVER"] shutil.copy(src_file, dst_foleder) # 获取当前仓库里所有的tag信息 tag_info_list = search_tag_info(git_url,git_token, git_repo) # 获取最新的一个tag now_tag = tag_info_list[0] # 获取所有的tag信息,这个地方是因为standard-version的特性, # 要获取所有的tag信息,再删掉当前的tag信息, # 再使用standard-version 重新生成一个tag信息 os.system("git remote set-url origin https://'" + username + "':'" + password + "'@"+git_url+"/" + git_repo) os.system("git fetch --all") os.system("git tag -d " + tag) cmd = 'standard-version --tag-prefix "" --release-as ' + tag print(cmd) os.system(cmd) # standard-version命令会产生一个CHANGELOG.md文件 with open('CHANGELOG.md', encoding='utf-8') as f: line = f.read() print("tag len is:" + str(len(tag_info_list))) # 判断一下目前有几个tag,分割保留最新的git tag 变更信息 if len(tag_info_list) > 1: pre = tag_info_list[1] list = line.split(" " + pre['tag_name'] + " ") # print(list[0]) now_content = list[0] else: now_content = line # 把CHANGELOG.md中本次变更的传到git的tag信息里 modify_tag_body(git_url,git_token, git_repo, now_tag['id'], now_content)
Dockerfile
FROM python:3.9-buster LABEL maintainer="357244849@qq.com" RUN set -eux \ && sed -i "s@http://ftp.debian.org@https://repo.huaweicloud.com@g" /etc/apt/sources.list \ && sed -i "s@http://security.debian.org@https://repo.huaweicloud.com@g" /etc/apt/sources.list \ && apt-get update \ && apt-get install -y nodejs npm ENV NODE_PATH="/usr/lib/node_modules" ENV LANG=C.UTF-8 PYTHONUNBUFFERED=1 RUN npm i -g standard-version WORKDIR /lzw ADD . /lzw RUN pip install -r /lzw/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple CMD ["python3","/lzw/main.py"]
requirements.txt
requests
.versionrc
{ "types": [ {"type": "feat","section": "Features"}, {"type": "fix","section": "Bug Fixes"}, {"type": "docs","section": "Documentation" }, {"type": "style","section": "Styling" }, {"type": "refactor","section": "Refactors" }, {"type": "perf","section": "Performance" }, {"type": "test","section": "Tests" }, {"type": "build","section": "Build System" }, {"type": "ci","section": "CI" }, {"type": "chore","section": "Chore","hidden":true }, {"type": "revert","section": "Reverts" } ] }
如何嵌入到DroneCI流水线呢
在drone.yml文件里嵌入如下yml即可
--- kind: pipeline type: kubernetes name: tag steps: - name: generator change log image: drone-changelog-plugin:1.0.1 settings: token: XXXXXX git_url: XXXXXX trigger: event: - tag