返回介绍

持续集成

发布于 2025-04-20 18:52:16 字数 7031 浏览 0 评论 0 收藏

持续集成(Continuous Integration,CI)是一种软件开发实践。持续集成的目的简单而明确,就是让产品可以快速迭代,同时还能保持高质量。当有人向代码库的主分支提交代码时,持续集成服务器会尝试去构建整个产品,包括单元测试、Web 测试、代码质量分析等等。如果构建通过,说明改动的代码被成功地集成了,否则就说明本次构建有问题需要修复,在修复完成之前这些代码是不能被合并到主分支的。

持续表示会不断获取反馈,响应反馈。对于 Python Web 开发来说,集成主要是指测试和代码审查。不断地集成和修正集成的结果,直到达到集成要求。这种方式有如下优点:

  • 更快地发现潜在问题,更容易定位错误。
  • 实现测试自动化。
  • 让整个团队高效准确地工作,可以有效避免由不同人开发的单个小模块可以单独工作,但集成为一个大系统则失败的问题。

CI 服务器根据源代码的变更触发构建,监控测试结果。目前常用的 CI 服务器有 5 种。

1.Jenkins:一个用 Java 编写的开源持续集成工具,它有丰富的插件和完善的 API,可以自由扩展。豆瓣的持续集成系统也基于 Jenkins。虽然它很受欢迎,但是 Python 工程师很难对其进行二次开发,页面和功能也有些陈旧。

2.Travis CI:一个针对 GitHub 的云服务平台,只对开源项目提供免费的 CI 服务。

3.GitLab CI:为 GitLab 提供持续集成服务的开源服务器。

4.Buildbot:用 Python 编写的一个开源 CI 系统。Google Chromium、Python、MongoDB、Mercurial、WebKit、Zope 等项目都使用它来作为持续集成工具。

5.Strider:一个使用 Node.js 开发的、开源持续集成和发布服务器。目前它已经支持 GitHub、Bitbucket、Gitlab 等平台,支持 Python、Ruby、Node.js 和其他自定义的应用。

本节将使用 Buildbot 实现 GitHub 开源项目的持续集成。首先在 GitHub 上创建一个用来测试的项目 https://github.com/dongweiming/tola。项目的结构如下:

其中 test_pytest.py 使用 8.3 节的测试代码。setup.cfg 是 INI 格式的配置文件,可以把支持的命令的默认设置放入这个配置文件中,而不需要在命令行指定:

[pytest]
norecursedirs=venv # virtualenv 创建的环境目录不需要验证

使用“python setup.py test”是常见的测试方式,需要创建 setup.py 文件:

from setuptools import find_packages, setup
from setuptools.command.test import test as TestCommand
     
     
class PyTest(TestCommand):
     
    def run_tests(self):
        import pytest
        errno=pytest.main([])
        exit(errno)
     
     
setup(
    name='Aiglos',
    ...
    packages=find_packages(
        exclude=["*.tests","*.tests.*","tests.*","tests"]), # 最后安装的时候需要
            排除测试相关的文件
    zip_safe=True, # 出于性能考虑,通常可以把包打包成 zip 文件。如果包内没有数据文
        件、C 扩展等就可以选择压缩
    test_suite='tests', # 指定测试套件的目录
    tests_require=['pytest'], # 测试需要安装的依赖,不需要使用 install_requires
    cmdclass={'test':PyTest}, # 自定义了命令类
    ...
)

Buildbot 的环境数据都存在数据库中,本节将使用 MySQL 存储这些数据。Buildbot 的稳定版本是 0.8.12,但是此版本还不兼容 MySQL 5.7,需要使用更新的 0.9 版本:

> pip install buildbot==0.9.0b9 buildbot-www==0.9.0b9 buildbot-worker==0.9.0b9 buildbot
     -waterfall-view==0.9.0b9 buildbot-console-view==0.9.0b9

Buildbot 0.9 做了比较大的改动,现在 buildbot-slave 更名为 buildbot-worker,并把集成的 Web 应用独立成了 buildbot-www。buildbot-waterfall-view 和 buildbot-console-view 是额外的组件,分别用瀑布和终端视图的方式展示集成结果。

Master 是主控端,首先配置 Master:

> buildbot create-master -r/srv/build_bot
> cp/srv/build_bot/master.cfg.sample/srv/build_bot/master.cfg

更新 master.cfg 的如下配置:

# 修改项目相关信息,其中 title 和 buildbotURL 的设置会在邮件中展示出来
c['title']='Tola'
c['titleURL']="https://github.com/dongweiming/tola"
c['buildbotURL']="http://localhost:9000/"
    
# 设置数据库的地址,其中参数 sql_mode=MYSQL40 是为了兼容 MySQL 5.x
c['db']={
    'db_url':"mysql://web:web@localhost:3306/r?sql_mode=MYSQL40",
}
    
# 执行集成任务的 worker 设置
c['workers']=[worker.Worker('slave1', '456')]
    
# 构建步骤。构建分两步:先克隆代码,然后执行 python setup.py test
factory=util.BuildFactory()
factory.addStep(
    steps.Git(repourl='git://github.com/dongweiming/tola.git', mode='incremental'))
factory.addStep(steps.ShellCommand(command=["python","setup.py","test"]))
# 设置触发构建的条件,GitPoller 会监控这个版本库,如果版本库有变化就会触发一次新
    的构建
c['change_source']=[]
c['change_source'].append(changes.GitPoller(
   'git://github.com/dongweiming/tola.git',
   workdir='gitpoller-workdir', branch='master',
   pollinterval=10))
# pollinterval 表示检查间隔,默认是 300s,时效性不够,这里改成了 10s
     
# 构建设置,使用 worker 名字为 slave1 来执行构建,构建名字是 runtests
c['builders']=[]
c['builders'].append(
    util.BuilderConfig(name="runtests",
                       workernames=["slave1"],
                       factory=factory))
     
# Builbot 的 Web 页面设置:使用端口 9000,登录用户为 dongwm,密码为 123
c['www']={
    'port':9000,
    'plugins':dict(waterfall_view={}, console_view={}),
    'auth':util.UserPasswordAuth({'dongwm':'123'})
}
    
c['services']=[]
    
from buildbot.plugins import reporters
    
#添加邮件监控设置,接收邮件的是 xxx@gmail.com 和对项目感兴趣的作者
mn=reporters.MailNotifier(fromaddr="buildbot@mailgun.org",
                         relayhost="smtp.mailgun.org",
                         extraRecipients=['xxx@gmail.com'],
                         smtpUser="postmaster@xxx.mailgun.org",
                         smtpPassword="smtpPassword")
c['services'].append(mn)

其中发送监控邮件的 MailNotifier 类的 extraRecipients 通常是一个邮件组,这样相关工程师就都可以收到邮件了。

启动 Master:

> buildbot upgrade-master/srv/build_bot # 更新配置都需要执行这步
> buildbot start/srv/build_bot

接着创建和配置执行任务的 Worker:

> buildbot-worker create-worker /srv/build_bot_worker localhost:9989 slave1 456

Worker 不一定与 Master 在同一个服务器上。启动 Worker:

> buildbot-worker start /srv/build_bot_worker

现在 push 代码到 tola 项目就会触发自动构建了。访问 http://localhost:9000,然后使用上面设置的 dongwm/123 登录。看一下最近的构建记录(单击“Recent Builds”),如图 8.1 所示。

图 8.1 最近的构建记录

构建成功的效果如图 8.2 所示。

图 8.2 构建成功

构建失败的效果如图 8.3 所示。

图 8.3 构建失败

通过构建的 ID 可以看到构建过程,比如看 ID 为 1 的 Shell 记录(Shell 是配置的 factory.addStep 的第二步),地址就是 http://localhost:9000/#/builders/1/builds/4/steps/1/logs/stdio。

我们也会收到包含构建结果的邮件,如图 8.4 所示。

图 8.4 包含构建结果的邮件

使用 Tox 集成

Tox 是一个通用的 Virtualenv 管理和测试命令行工具,它的目标是提供最先进的自动化打包、测试和发布功能。Tox 只能在终端使用命令行的方式做测试,多用于本地环境的测试或者集成进 CI 服务器。它最大的特性是支持一次性验证多个版本的 Python 解释器下的包的集成情况,在开源项目中使用比较广泛。

我们先安装它:

> pip install tox

Tox 用到的目录结构:

Tox 配置如下:

[tox]
envlist=py{2.7,3.5} # 是 py27,py35 的简写,也就是默认创建 Python 2.7 和 Python 3.5 这两
     个虚拟环境
skipsdist=True # Tox 默认会使用 sdist 构建包,对于测试来说没有必要,而且构建还会
     要求存在 README、setup.py 等文件,并且保证 setup.py 的格式符合要求等,所以本例跳
     过了这步
[testenv] # 默认的集成方案
deps=pytest # 集成需要的依赖
commands={posargs:py.test} # 可以把调用的命令的参数通过 posargs 传给 Tox 来使用
    
[testenv:flake8] # 非默认的集成方案,需要使用 tox -e flake8 才能调用
basepython=python2.7 # 使用 Python 2.7 这个解释器完成工作
deps=
    pytest # 依赖可以多行
    -rrequirements.txt # 文件中有相关的其他依赖:flake8
commands=
    {posargs:py.test} # 相当于执行两步:第一步执行 py.test,第二步验证代码规范问题
    flake8 .

可以使用如下命令集成:

> tox # 默认方案,会创建 py27 和 py35 这两个虚拟环境,目录默认在当前目录的.tox 目录
    下,使用的命令就是 pytest
> tox-e flake8 # 使用 testenv:flake8 这个块中的集成方案
> tox-e py2.7 # 只创建 py27 的集成方案,它和 tox-e py27 同义,但是由于之前执行 tox 的
    时候创建过,所以更节省时间
> tox--py.test-k test_eval # 只测试了 test_eval 相关的三个测试,这就是{posargs:py.
    test}的作用
> tox-e py27--python # 进入 Python 2.7 的 Python 交互模式
> tox-e py27--python-m SimpleHTTPServer # 可以支持多个参数

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。