CI/CD - Python Django 项目在 Jenkins 上的实践
准备工作
Jenkins
这里的Jenkins由于需要集成Python环境,安装Jenkins的方式有很多种,鉴于Devops和docker的流行,我选择在docker的安装方式。
如果不考虑Python的特殊需求(如 Python3),可以直接使用Jenkins(注意不是docker官方镜像jenkins - Docker Official Images , docker 官方的镜像版本较老,不建议使用)提供的docker镜像进行构建 Jenkins - jenkins/jenkins, 官方提供的镜像中Python的版本还是停留在2.x版本,所以如果你打算使用Python3构建你的系统的话,需要在这个镜像的基础上配置Python3的环境,常见的做法就是编写Dockerfile然后基于这个镜像进行构建。
以下是对应的Dockerfile
1 | FROM jenkins/jenkins:lts-alpine |
也可直接在dockerhub上使用这个镜像 dockerhub - aibyte/jenkins_python3
Django 工程
该工程主要是用于提供HTTP REST 服务,后期会考虑整合合适的前端框架用于支持一个完整的fullstack project。
因此对与Django工程的组成考虑是使用 Django
+ Django REST Framework
(DRF)
再考虑到Django工程与Jenkins之间的整合,将django-jenkins
集成进工程
Django-Jenkins插件
安装配置方法请参考下面的链接:
如果以上的配置完成,那么你就可以通过python manage.py jenkins
执行单元测试以及其他静态代码检查(例如 pylint 和 pep8)
工程需要具备的条件
测试,测试还是测试。
作为TDD的理性拥护者,坚信没有测试的代码是不可信任的。
当然,单元测试也是分为不同层次进行实践的,越是靠近用户操作层的测试执行起来难度越大,变化的频度也会越大,所以良好的分层设计和可测架构的设计就很重要了。
从Django的架构模式来看,view 层其实是controller + service 的混合实现层, model层是比较传统的业务模型。
因此从测试的策略来看,一般单元测试会选择从model层开始。
以下是一个简单典型的model单元测试 testcase:
1 | from django.test import TestCase |
注意: 这里继承的是django.test
模块下的 TestCase
类(特别是在测试数据库这一层的case场景时), 而不是直接选择 unittest
下的 TestCase
的原因是:
unittest 的测试case 避免了执行事务和刷新db的开销,但是同时它也使得这些测试case在testsuite的执行行为不可预测。
配置 Jenkins 让一个简单Freestyle 流程跑起来
创建 Jenkins Freestyle工程
配置 Source Code Management
这里我选择的是Github作为源代码的管理工具,可以选择使用ssh key的方式来与Github进行checkout源代码操作,详细的操作请参考 Connecting to GitHub with SSH
配置 build step
选择 Add build step
-> Execute shell
在Command中填写:
1 | /usr/bin/virtualenv --python=python3.6 env |
保存(Save)并应用(Apply)
到了这一步如果没有什么配置问题其实就可以触发一个在Jenkins上的构建了,可以在Job下点击Build Now
然后查看构建结果。
配置 Build Triggers
这里考虑两种构建:
- Daily build
这种构建是每天在固定的时间段执行的构建行为,主要是定期检查和维护项目可构建及健康度的一种构建行为。
这里我选择的构建配置是在每天凌晨1点进行,配置如下:
1 | TZ=Asia/Shanghai |
- Git commit build
这种构建是在每次的Git push 后触发一次构建,是常见的构建策略。
为了实现这个构建配置,需要在对应的Github工程中配置 Webhook。
Github 配置位置:项目 settings -> Webhooks
在填写payload URL时,如果你没有自定义Jenkins的Github webhook,那么这个配置会是http://<your-jenkins-domain>/github-webhook/
当然,你也可以在你的Jenkins系统配置中查看,具体位置是:
Manage Jenkins -> Configure System -> Github -> Advanced -> Override Hook URL
锦上添花的配件
POST build 后的通知插件
如果不想使用老套的邮件进行通知,完全可以使用类似 Slack Slack-Notification, 和 lark Jenkins CI机器人的方式进行通知。
还可以做的一些事
测试更多的部分
Mocked Client 测试
- Response 测试
Headless browser 测试(selenium)
- 其他测试话题
- 测试多DBdjangoproject - tests-and-multiple-databases
- 如何组织编写testrunner支持可复用组件的测试djangoproject - Using the Django test runner to test reusable applications
djangoproject - Advanced testing topics
更新
Jekins on docker(2020年9月30日)
以上的Jenkins on docker的安装方式相对比较传统,配合Jenkins流水线(pipline)可以使用在docker中运行docker实现持续交付的CI/CD系统。
使用docker安装Jenkins
1 | sudo docker network create jenkins |
详细说明参见 官方文档
使用pipeline 进行CI/CD 可以参考以下官方文档:
设置docker应用随系统重启后自动启动:
1 | sudo docker update --restart unless-stopped jenkins-docker |