背景
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