2020-05-31 记一次使用 CI 的开源项目开发
项目地址:https://github.com/CaoMeiYouRen/super-search-hub
本项目开源在 GitHub 上。因为 travis-ci 和 docker 都只对开源项目免费,索性就直接开源了。
项目本身倒是没必要多提,本次还是想聊聊持续集成的那些事情。
dependabot
dependabot是 GitHub 推出的一个提醒依赖更新机器人,当你项目的依赖有更新的时候就会自动推送一个 Pull requests
travis-ci
travis-ci 是一个知名的 CI 工具,只需要在项目根目录下编写 .travis.yml 文件即可,例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| language: node_js node_js: 12.15.0 services: - docker install: - npm install script: - npm run lint - npm run build deploy: provider: script skip_cleanup: true on: branch: master script: - npm run release cache: directories: - node_modules notifications: webhooks: urls: - secure: pCBLuzxjzjdLTHZhse4z66lQJsyrklML1lPfwZSQfgBJLMteyrY9bXqH0uXxzw7UpnFvFQRZjOanDQh+78M1U43PoXzGzONcRc8FTMOSGgCiLd7w7ZNaKaBP+uCzvnS2Y0uHZpZcb0QxCvLTBMQGpO6NztcDTYAoVmWtok0/IwNdHI45Bh4kefNT5L9WE2M09R9J7dLI42feHzNyf7iSHEEJTOi7V5v++FdnRzdA+Vy/UtESpN4RviAJ4E/FXMQhuJ6ili9w/P4qPBJyMTtn9XxRmkSXP+UIwWNoojl/UcbnAKFVywcQzQkyfqe4grz1xmeyoSDX/PopMwpok+/N7pBY4/UWz8k16GlISOifME5MfZ/SHhP5BS/yYV5Pih8iHwMaM0gqXIo2nuBVdBF7pB3058zbIovM0v2FSg3wV2z+4PLeS4UsWaxt5Iqpq0YoWvkOmCMB8aqP1acqCKplkqNw3sU3WJ7mIU8xTd9U5PPYGHeF86h+BLMdz8nYHI8n8n1muKUMaW8MZ4G7jLlOX31Fx07VVjAOAhj0rWAz9qVOKjZFhFh+HmaBgY84zR6zQzZnNtD42vsaNrbKkXsOIrc7cSDdAkkM/7xUeOl+Y0Inr5ElALTpKz5oem7P0M1AN2Z/IAYVYuI9Sre0uFEsbnPbGZ54c7s5/k2r4WFztMk=
|
在这里着重要提的就是加密配置中的关键字段了。
需要先下载 travis-cli ,下载方式见文档。需要 Ruby 环境,自行下载即可。
1 2
| gem install travis travis version
|
另外,gem 在国内访问也是慢的要死,配置一下国内镜像即可
接下来就是登陆了
此处有一个惊天大坑,那就是 travis-ci.com、travis-ci.org 是同一家公司的两个网站。本来是一个用于商用,一个用于开源,但后来合并了,目前使用的是 travis-ci.com。
但是登陆时默认使用的是 api.travis-ci.org
而不是 api.travis-ci.com
因此需要添加 --com
来切换源
后面的看文档就行了
使用时添加为- secure
字段就行
semantic-release
本项目的 release 部分使用了 semantic-release。这是一个挺好用的 release 工具
只需要在项目根目录下新建一个 .releaserc.js 文件即可,例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| module.exports = { plugins: [ [ '@semantic-release/commit-analyzer', { config: 'conventional-changelog-cmyr-config', }, ], [ '@semantic-release/release-notes-generator', { config: 'conventional-changelog-cmyr-config', }, ], [ '@semantic-release/changelog', { changelogFile: 'CHANGELOG.md', changelogTitle: '# super-search-hub', }, ], '@semantic-release/npm', '@semantic-release/github', [ '@semantic-release/git', { assets: [ 'dist', "docs", 'CHANGELOG.md', 'package.json', ], }, ], [ '@semantic-release/exec', { prepareCmd: 'npm run docs:build && docker build -t caomeiyouren/super-search-hub .', }, ], [ 'semantic-release-docker', { name: 'caomeiyouren/super-search-hub', }, ], ], }
|
cz-conventional-changelog
包括 commitizen、cz-conventional-changelog、conventional-changelog-cli、conventional-changelog-cmyr-config。最后一个是日志格式,可以自定义。
下面来具体说明下如何实现自动化生成日志。
首先,要生成日志,那么必须对 git commit 做风格约束。因此使用 commitizen、cz-conventional-changelog 来提交日志。
在 package.json 文件中配置
1 2 3 4 5
| "config": { "commitizen": { "path": "cz-conventional-changelog" } }
|
之后使用 git cz 即可提交符合要求的 git commit
除此之外,为了防止有人不按规矩来,使用 husky、validate-commit-msg 来校验提交的 git commit 是否符合格式
当提交完 git commit 后,执行
1
| conventional-changelog -p cmyr-config -i CHANGELOG.md -s -r 0
|
来生成日志。
当然如果使用了 CI 就没有这一步了,生成日志这种活也应该交给 CI
jenkins
本项目还有一个需求,那就是当 travis-ci 编译完成后通知自己的服务器进行部署。
自建的 CI 选择了 jenkins,jenkins 也提供了 webhook 来触发部署。
但在这里遇到了一个问题。
最新版的 jenkins 对于 CSRF (跨站请求伪造) 进行了防护,请求中必须带有 crumb 才行,直接访问是 403 的。
经过一番搜寻后找到了解决方法。既然无法直接访问的话那就自己写个中转吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| async function jenkinsAPI(url: string, query: any = {}, data: any = {}, method: any = 'GET') { const jenkinsAxios = axios.create({ baseURL: 'https://xxx.yyy.zzz', auth: { username: JENKINS.JENKINS_USERNAME, password: JENKINS.JENKINS_PASSWORD, }, })
const crumbIssuer = await jenkinsAxios.get('/crumbIssuer/api/json') const result = await jenkinsAxios(url, { method, params: query, data, headers: { 'Content-Type': 'application/json', [crumbIssuer.data?.crumbRequestField]: crumbIssuer.data?.crumb, Cookie: crumbIssuer.headers['set-cookie'][0], }, timeout: 10000, }) return result }
|
调用这个函数即可
webpack
本项目使用 webpack 来打包,生成的 dist 文件只需要有 node 环境就能运行,无需安装任何依赖。再结合 docker 技术,就生成了一个体积极小的镜像。主要体积是 node.js 这个运行时,代码部分极小
docker
docker 在本项目中用于部署。
话说回来,既然本项目已经使用 webpack 来打包了,只有一个 dist/index.js 文件用于部署,可以讲是非常方便了,那么为什么还是要用 docker?
要说原因的话还是因为 docker 部署比真机部署更加方便,更新起来也更加方便。
同时 docker 部署下运行环境都是一致的,而真机可能会因为种种原因导致 node.js 的版本不一样(尤其是在版本更迭极快的今天)。同时 docker 也能一键解决依赖问题。所以还是更加推荐 docker 部署。
顺便附上一个我用的部署命令行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| /usr/bin/docker-compose stop if [ $? -ne 0 ];then echo -e "${red} 停止旧容器失败 ${font}" fi
/usr/bin/docker system prune -a -f if [ $? -ne 0 ];then echo -e "${red} 删除旧容器失败 ${font}" fi
/usr/bin/docker-compose up -d --build if [ $? -ne 0 ];then echo -e "${red} 启动新容器失败 ${font}" fi
|
本文作者:草梅友仁
本文地址: https://blog.cmyr.ltd/archives/5a4ebd1.html
版权声明:转载请注明出处!