更新日志自动生成
之前我都是手动修改
CHANGELOG.md
,用来记录更新日志,感觉操作起来有点心累,也不是很规范。好在已有前人种树,于是我就考虑利用
conventional-changelog-cli
自动生成和更新
CHANGELOG.md
,真的好用!
什么是conventional-changelog
Generate a changelog from git metadata
根据
git
元数据生成更新日志,而
conventional-changelog-cli
则是相关的命令行工具。
安装conventional-changelog-cli
npm install -g conventional-changelog-cli
复制
初始化生成CHANGELOG.md
cd my-project
conventional-changelog -p angular -i CHANGELOG.md -s
复制
以上命令是基于最后一次的
Feature
,
Fix
,
Performance Improvement or Breaking Changes
等类型的
commit
记录生成或更新
CHANGELOG.md
。如果你希望根据之前所有的
commit
记录生成完整的
CHANGELOG.md
,那么可以试试下面这条命令:
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
复制
工作流
代码添加到暂存区
这一步没有什么特殊,日常撸代码,然后将工作区的内容添加到暂存区。
git add .
复制
规范commit message
一个规范的commit message一般分为三个部分Header,Body 和 Footer。Header包含type, scope, subject等部分,分别用于描述commit类型,影响范围,commit简述。Body则是详细描述,可以分多行写。Footer主要用于描述不兼容改动(Breaking Change)或者关闭issue(Closes #issue)。
格式如下:
<type>(<scope>): <subject>
<body>
<footer>
复制
举个栗子:
feat(支持自动部署): 结合conventional-changelog,配合部署脚本完成部署任务
conventional-changelog是一个很好的工具,用于自动生成changelog,再配上自定义的部署脚本,整个部署流程就显得更规范了
Breaking Change: 比较大的更新
Closes #315
复制
其中,
Header
是必需的,
Body
和
Footer
可以省略。
大致了解规范后,就可以上工具了,这里我们用到的是
commitizen
。
npm install -g commitizen
复制
接着在项目根目录运行以下命令:
commitizen init cz-conventional-changelog --save --save-exact
复制
运行成功后,
package.json
会新增如下内容:
"devDependencies": {
"cz-conventional-changelog": "^3.1.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
复制
git commit
这一步用
git cz替代
,
cz
就是指
commitizen
,通过交互式命令行完成
commit
操作。
PS D:\robin\frontend\spa-blog-frontend> git cz
[email protected], [email protected]
? Select the type of change that you're committing: feat: A new feature
? What is the scope of this change (e.g. component or file name): (press enter to skip) 支持自动部署
? Write a short, imperative tense description of the change (max 86 chars):
(37) 结合conventional-changelog,配合部署脚本完成部署任务
? Provide a longer description of the change: (press enter to skip)
? Are there any breaking changes? No
? Does this change affect any open issues? No
[master ee41f35] feat(支持自动部署): 结合conventional-changelog,配合部署脚本完成部署任务
3 files changed, 15 insertions(+), 3 deletions(-)
复制
处理版本号,更新CHANGELOG
接着我们要更新
npm
包的版本号,结合
npm version
和
conventional-changelog
使用,可以同时更新
CHANGELOG.md
。
好的,我们先准备好脚本:
"scripts": {
"start": "vue-cli-service serve",
"build": "vue-cli-service build",
"deploy": "node deploy",
"version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
"postversion": "npm run deploy"
}
复制
根据实际版本情况选择更新
patch/minor/major
版本。假设我们更新的是
minor
版本号,那么操作命令如下:
npm version minor -m '特性版本更新'
复制
执行这条命令会更新
package.json
中的
version
字段,
同时会执行
conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md
,更新
CHANGELOG.md
。
执行完这条命令后,可以看到
CHANGELOG.md
已经被修改了。
CHANGELOG自动更新
npm钩子触发部署脚本
通过
postversion
钩子触发部署脚本
node deploy
,开始进行部署工作。
deploy.js
文件内容如下:
const { execFile } = require('child_process');
const version = process.env.npm_package_version;
execFile('deploy.sh', [version], { shell: true }, (err, stdout, stderr) => {
if (err) {
throw err;
}
console.log(stdout);
});
复制
这里利用了
nodejs
的
child_process
模块执行子进程,调用了
execFile
执行了
deploy.sh
,并将
npm
包版本号作为参数传递给了
deploy.sh
。
deploy.sh
文件内容如下:
#!/bin/bash
npm run build
htmldir="/usr/share/nginx/html"
uploadbasedir="${htmldir}/upgrade_blog_vue_ts"
appenddir=$1
uploaddir="${uploadbasedir}/${appenddir}"
projectdir="/usr/share/nginx/html/blog_vue_ts"
scp -r ./dist/. txcloud:${uploaddir}
ssh txcloud > /dev/null 2>&1 << eeooff
ln -snf ${uploaddir} ${projectdir}
exit
eeooff
echo done
复制
以上命令主要做的事情是:
-
执行构建任务npm run build
- 将构建得到的
文件夹中的内容通过dist
传输到服务器,通过版本号区分各个版本。scp
-
配置的是监听nginx
端口,指向80
,而我通过软连接将/usr/share/nginx/html/blog_vue_ts
再次指向到blog_vue_ts
下的版本目录,如upgrade_blog_vue_ts
。每次发布版本时,以上脚本会修改软连接,指向目标版本,如upgrade_blog_vue_ts/0.5.4
,完成版本过渡。upgrade_blog_vue_ts/0.6.0
我这里使用了软连接改进了之前的部署脚本,既可以在服务器保留各个历史版本文件夹,也不用考虑处理
index.html
与静态资源分离的问题。
lrwxrwxrwx 1 root root 47 Feb 3 21:35 blog_vue_ts -> /usr/share/nginx/html/upgrade_blog_vue_ts/0.6.0
复制
linux服务器项目版本文件夹
如果要回退版本,也可以通过修改软连接的方式实现,还是比较方便的。
推送到remote
最后别忘了把代码
push
到远程仓库。
git push
复制
更新日志
changelog
查看也变得很方便了,修改了什么内容一目了然,并且可以直接跳转到
commit
历史,
issue
等。
github上的changelog
番外
可以看到,我是通过
deploy.js
调用了
deploy.sh
。之前本想直接在
npm scripts
中调用
deploy.sh
并传入版本号参数的,但是试了几种写法都不行,这里也记录一下。
"deploy": "deploy.sh npm_package_version"
复制
"deploy": "deploy.sh $npm_package_version"
复制
看起来在
npm scripts
中调用
sh
脚本时,只能写字面量参数,传变量作为参数好像行不通。
下面这种字面量参数写法是可以的,但是就有点呆呆的感觉了,而且与自动化部署的主题不符。
"deploy": "deploy.sh 0.6.0"
复制
所以我目前还是选择通过
deploy.js
作为中间者来调用
deploy.sh
的。
结语
需要承认的是,我以上所述的部署流程是以我的个人项目为例说明,可能不是很规范,但是也算是通过自己的理解和摸索,完整地搞了一套部署流程,并没有借用
jenkins
等工具。有了这段自动化部署的学习经历后,相信学习和使用
jenkins
会变得更轻松。接下来我会继续优化和规范自己的部署流程,
jenkins
理所当然会出现在我的计划表中。