欢迎你们前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~node
本文由 angel_郁 发表于 云+社区专栏
Buildbot是一个基于Python的持续集成系统,用于自动化软件构建,测试和发布过程。python
在本教程中,咱们将演示如何设置持续集成系统以自动测试对存储库的新更改。咱们将使用一个简单的Node.js应用程序来演示测试过程和必要的配置。为了将咱们的测试环境与Buildbot主机隔离,咱们将建立一个Docker镜像做为Buildbot worker运行。而后,咱们将配置Buildbot主服务器以观察GitHub存储库的更改,每次检测到新的更改时自动进行测试。git
要学习本教程,您须要:github
另外,在开始本教程以前须要完成如下内容:web
在咱们开始配置Buildbot以前,咱们将看一下咱们将用于本教程的示例存储库。sql
在您的Web浏览器中,访问咱们将用于演示的GitHub上的hello hapi应用程序。这个应用程序是一个简单的“hello world”程序,带有一些单元和集成测试,用hapi编写的一个Node.js Web框架。docker
因为此示例用于演示各类持续集成系统,您可能会注意到一些文件用于为其余系统定义管道。对于Buildbot,咱们将在服务器上而不是在存储库中定义构建步骤。shell
稍后,咱们将在咱们的存储库中为Buildbot设置webhook,以便更改将自动触发新测试。如今,咱们须要建立本身的存储库分支。数据库
单击屏幕右上角的Fork按钮:npm
GitHub fork 按钮
若是您是GitHub组织的成员,可能会询问您在哪里使用fork存储库:
哪里使用fork存储库
选择账户或组织后,存储库的副本将添加到您的账户中:
存储库的副本将添加到您的账户
您将在Buildbot配置中使用fork的URL。如今咱们有了一个存储库URL,咱们能够开始配置Buildbot了。
咱们将从设置Docker开始,以便Buildbot使用它来执行构建。首先,咱们须要配置Docker和Buildbot之间的访问。以后,咱们须要建立一个Docker镜像以用于咱们的容器。
为Buildbot配置Docker访问
咱们须要容许Buildbot和Docker在几个不一样的级别进行通讯。
首先,咱们须要确保Buildbot进程能够访问Docker守护程序。咱们能够经过将作到这一点buildbot用户的docker组:
$ sudo usermod -aG docker buildbot
下次从新启动Buildbot主服务器时,这个新组将可用于Buildbot,咱们稍后会这样作。
咱们还须要确保Buildbot知道如何与Docker通讯。因为Buildbot是用Python编写的,它利用docker-py
Python包而不是直接发出Docker命令。
您能够输入如下命令安装docker-py
:
$ sudo -H pip install docker-py
最后,咱们须要打开从容器到主机系统和外部世界的网络访问。咱们能够经过在防火墙中容许docker0
的接口例外来实现此目的。
经过输入如下内容容许从docker0
界面访问流量:
$ sudo ufw allow in on docker0
Buildbot和Docker如今应该可以有效地相互通讯。
建立一个Docker镜像以用做Buildbot Worker
接下来,咱们将建立一个Docker容器,用做Buildbot worker来运行咱们的测试。Buildbot能够动态启动Docker容器以用做worker,但首先须要使用包含的一些Buildbot worker组件构建容器。
幸运的是,Buildbot项目提供了一个基本的Buildbot worker映像,该镜像已经配置了全部特定于Buildbot的需求。咱们只须要将此镜像用做基础并安装咱们项目所需的其余依赖项。
在咱们的例子中,咱们将使用的示例应用程序是Node.js应用程序,所以咱们须要确保Node.js在镜像上可用。
要定义咱们的镜像,请建立并打开Dockerfile在主目录中调用的文件:
$ nano ~/Dockerfile
在这个文件中,咱们使用了基于Buildbot worker的镜像FROM buildbot/buildbot-worker:master
。以后,咱们能够切换到root
用户安装Node.js
,而后切换回buildbot用户运行实际命令:
〜/ Dockerfile
FROM buildbot/buildbot-worker:master USER root RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - RUN apt-get install -y nodejs USER buildbot
完成后保存并关闭文件。
一旦咱们拥有了Dockerfile
,咱们就能够从中构建咱们的镜像。咱们将调用镜像npm-worker
来明确咱们安装的额外依赖项:
$ docker build -t npm-worker - < ~/Dockerfile
Docker将根据咱们在其中列出的命令开始构建您的镜像Dockerfile
。它将下拉基本镜像及其依赖层,安装Node.js
,而后将生成的环境保存到一个名为npm-worker
的镜像中。
如今咱们有了Docker镜像,咱们能够配置Buildbot主机来使用它。
由于咱们正在定义一个全新的构建过程,而且由于到目前为止咱们对主配置的定制不多,因此咱们将从头开始配置。为避免丢失当前信息,咱们将原始文件移动到备份文件:
$ sudo mv /home/buildbot/master/master.cfg /home/buildbot/master/master.cfg.bak
显示备份文件的配置,以便咱们能够复制一些重要值以在新配置中使用:
$ sudo cat /home/buildbot/master/master.cfg.bak
咱们要转移到新配置的重要部分是用户凭据和权限。在输出中查找c['www']['authz']
和c['www']['auth']
开头的配置部分:
. . . c['www']['authz'] = util.Authz( allowRules = [ util.AnyEndpointMatcher(role="admins") ], roleMatchers = [ util.RolesFromUsername(roles=['admins'], usernames=['Sammy']) ] ) c['www']['auth'] = util.UserPasswordAuth({'Sammy': 'Password'}) . . .
将这些行复制并保存在某处,以便之后能够引用它们。咱们将这些详细信息添加到咱们的新Buildbot主配置中,以保留咱们的用户和身份验证设置。
如今,建立一个新master.cfg
文件,咱们能够在其中从新定义Buildbot实例的行为:
$ sudo nano /home/buildbot/master/master.cfg
咱们将在此文件中定义新的Buildbot主配置。
设置基本项目配置
Buildbot配置文件其实是一个Python模块,它以牺牲一些复杂性为代价提供了极大的灵活性。
咱们将从一些基本配置开始。将如下行粘贴到您的文件中:
/home/buildbot/master/master.cfg
# -*- python -*- # ex: set filetype=python: from buildbot.plugins import * c = BuildmasterConfig = {} # Basic config c['buildbotNetUsageData'] = None c['title'] = "Hello Hapi" c['titleURL'] = "https://github.com/your_github_name/hello_hapi" c['buildbotURL'] = "https://buildmaster_domain_name/" c['protocols'] = {'pb': {'port': 9989}}
该文件的顶部包含一些注释,许多文本编辑器可以解释这些注释以正确应用语法高亮显示。而后,咱们从buildbot.plugins
包中导入全部内容,以便咱们可使用工具来构建配置。
Buildbot配置所有由名为BuildmasterConfig
的字典定义,所以咱们将此变量设置为空字典以启动。
咱们建立一个名为c
的速记变量,设置为同一个字,以减小整个文件中所需的输入量。
下面的配置中须要注意的一些事项:
buildbotNetUsageData
设置为None
。若是要向开发人员报告使用状况数据,请将其更改成字符串"basic"
。title
和titleURL
反映项目的名称和GitHub的仓库。使用指向您本身的fork的连接。buildbotURL
设置为Buildbot主服务器的SSL安全域名。记得从https://
开始并以尾部斜杠/
结束。protocol
定义并不会和本地主机绑定。咱们须要经过Docker桥接网络docker0
容许来自Docker容器的链接。配置Docker Worker
接下来,咱们须要定义咱们的Docker worker。Buildbot将根据须要使用Docker来配置工做人员。为此,它须要知道如何链接到Docker以及使用哪一个映象。
将如下内容粘贴到文件的底部:
/home/buildbot/master/master.cfg
. . . # Workers c['workers'] = [] c['workers'].append(worker.DockerLatentWorker("npm-docker-worker", None, docker_host='unix://var/run/docker.sock', image='npm-worker', masterFQDN='buildmaster_domain_name'))
该c['workers'] =[]
行演示了咱们在完成配置时将使用的基本约定。咱们将配置字典中的键设置为空列表。而后,咱们将元素附加到列表以实现实际配置。这使咱们能够在之后添加其余元素。
为了定义咱们的worker,咱们建立一个worker.DockerLatentWorker
实例并将其追加到worker
列表中。咱们将此工做者命名为npm-docker-worker
,以便稍后在配置中引用它。而后咱们将docker_host
设置为Docker的套接字位置,并提供咱们建立的Docker镜像的名称(在咱们的例子中为npm-worker)。咱们将masterFQDN
设置为Buildbot master的域名,以确保容器能够到达主服务器,而无论服务器的内部主机名设置如何。
配置调度程序
接下来,咱们将定义一个调度程序。Buildbot使用调度程序根据从变动源或更改挂钩收到的更改来决定什么时候以及如何运行构建(稍后咱们将配置更改挂钩)。
将如下配置粘贴到文件的底部:
/home/buildbot/master/master.cfg
. . . # Schedulers c['schedulers'] = [] c['schedulers'].append(schedulers.SingleBranchScheduler( name="hello_hapi", change_filter=util.ChangeFilter(project='your_github_name/hello_hapi', branch='master'), treeStableTimer=3, builderNames=["npm"]))
咱们使用相同的方法将配置附加到空列表中。在这种状况下,咱们附加一个schedulers.SingleBranchScheduler
实例。这容许咱们在存储库中观察单个分支,并简化了配置。
咱们将调度程序命名为“hello_hapi”以正确识别它。而后咱们定义一个更改过滤器。来自不一样来源的许多不一样变动集能够交给调度程序。更改过滤器定义一组标准,用于肯定此特定调度程序是否应处理相关更改。在咱们的例子中,咱们根据项目名称进行过滤,这将由GitHub webhook和咱们但愿观看的分支报告。
接下来,咱们将treeStableTimer设置为3秒,该treeStableTimer肯定等待其余更改的时间量。这有助于防止Buildbot为与密切相关的更改排队许多小型构建。最后,咱们定义当更改符合咱们的条件时应该使用的构建器的名称(咱们将暂时定义此为构建器)。
为Node.js项目配置构建工厂
接下来,咱们将配置一个用于处理Node.js项目的构建工厂。构建工厂负责定义构建或在咱们的案例测试中应该采起的步骤。它经过定义util.BuildFactory
实例而后添加应执行的顺序步骤来完成此操做。
将如下内容粘贴到文件的底部:
/home/buildbot/master/master.cfg
. . . # Build Factories npm_f = util.BuildFactory() npm_f.addStep(steps.GitHub(repourl='git://github.com/your_github_name/hello_hapi.git', mode='full', method='clobber')) npm_f.addStep(steps.ShellCommand(command=["npm", "install"])) npm_f.addStep(steps.ShellCommand(command=["npm", "test"]))
首先,咱们定义一个名为npm_f的构建工厂。咱们添加的第一步是steps.GitHub
实例。在这里,咱们设置应该下拉到构建器中的存储库。咱们设置mode
为“full”
和method“clobber”
以在每次提取新代码时彻底清理咱们的存储库。
咱们添加的第二个和第三个步骤是steps.ShellCommand
对象,它们定义在构建期间在存储库中运行的shell命令。在咱们的例子中,咱们须要运行npm install
以收集项目的依赖项。以后,咱们须要运行npm test
以运行咱们的测试套件。在大多数状况下,建议将命令定义为一个list (["npm","install"])
,以防止shell对命令中的元素应用不须要的扩展。
配置构建器
一旦咱们有一个添加了步骤的构建工厂,咱们就能够设置一个构建器。构建器将咱们已定义的许多元素绑定在一块儿,以肯定构建的执行方式。
将如下配置粘贴到文件的底部:
/home/buildbot/master/master.cfg
. . . # Builders c['builders'] = [] c['builders'].append( util.BuilderConfig(name="npm", workernames=["npm-docker-worker"], factory=npm_f))
咱们将一个util.BuilderConfig
对象附加到builders
列表中。请记住,咱们的构建工厂名为npm_f
,咱们的Docker工做者称为npm-docker-worker
,咱们定义的调度程序将把任务传递给名为npm的worker。。咱们的构建器定义了这些元素之间的关系,以便咱们的调度程序的更改将致使构建工厂步骤在Docker worker中执行。
配置数据库和Web界面
最后,咱们能够配置数据库和Web界面设置。与以前的许多项目不一样,这两个设置被定义为字典而不是列表。该db
字典只指向/home/buildbot/master
目录中已有的state.sqlite
文件。www
词典包含大量额外配置。
将如下内容粘贴到文件的底部。将您从原始Buildbot主配置中复制的身份验证信息替换为如下身份验证块:
/home/buildbot/master/master.cfg
. . . # Database c['db'] = { 'db_url': "sqlite:///state.sqlite",} # Web Interface c['www'] = dict(port=8010, plugins=dict(waterfall_view={}, console_view={})) # Auth info copied from the original configuration c['www']['authz'] = util.Authz( allowRules = [ util.AnyEndpointMatcher(role="admins") ], roleMatchers = [ util.RolesFromUsername(roles=['admins'], usernames=['Sammy']) ] ) c['www']['auth'] = util.UserPasswordAuth({'Sammy': 'Password'}) # End of auth info copied from the original configuration # GitHub webhook receiver c['www']['change_hook_dialects'] = { 'github': { 'secret': 'your_secret_value', 'strict': True, } }
在定义数据库设置以后,咱们建立一个www
字典,该字典首先定义要侦听的端口以及要包含在Web UI中的一些视图。接下来,咱们添加从先前的Buildbot配置文件中提取的身份验证要求。
最后,咱们在www
字典中定义了一个名为change_hook_dialects
的字典。咱们使用它来定义一个GitHub更改挂钩,它将侦听来自GitHub的webhook消息。为您的机密选择一个安全密码,GitHub将使用该密码来验证它将发送的消息。
完成后,保存并关闭文件。
此时,咱们已经彻底从新配置了Buildbot主进程。咱们须要从新启动Buildbot主进程来实现更改。
在咱们这样作以前,检查咱们的文件是否有重要的语法错误。因为咱们从头开始重建配置,所以咱们极可能会引入一些错误。
输入如下命令检查文件的语法:
$ sudo buildbot checkconfig /home/buildbot/master
该命令将报告它找到的任何问题。若是未找到任何错误,您将收到以下消息:
Config file is good!
若是报告了任何错误,请仔细阅读错误消息,以便更好地了解错误。再次打开配置文件以尝试解决任何问题。
若是再也不出现任何错误,请输入如下命令从新启动Buildbot主服务:
$ sudo systemctl restart buildbot-master
输入如下命令检查操做是否成功:
$ sudo systemctl status buildbot-master
● buildbot-master.service - BuildBot master service Loaded: loaded (/etc/systemd/system/buildbot-master.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2017-06-27 19:24:07 UTC; 2s ago Main PID: 8298 (buildbot) Tasks: 2 Memory: 51.7M CPU: 1.782s CGroup: /system.slice/buildbot-master.service └─8298 /usr/bin/python /usr/local/bin/buildbot start --nodaemon Jun 27 19:24:07 bb5 systemd[1]: Started BuildBot master service
若是服务可以成功从新启动,则会将其标记为活动状态。
在示例存储库中建立GitHub Webhook
如今Buildbot配置了一个Web端点来接受GitHub webhook帖子,咱们能够为咱们的fork配置一个webhook。
在Web浏览器中,导航到示例项目存储库的fork:
https://github.com/your_github_user/hello_hapi
单击“设置”选项卡以查看项目设置。在设置页面的左侧菜单中,单击Webhooks(GitHub可能会提示您在此过程当中从新输入密码以确认您的身份):
项目设置
单击右侧的“ 添加webhook”按钮以添加新的webhook。
下面的页面将包含一个用于定义webhook的表单。在Payload URL字段中,添加项目的GitHub更改的URL。这是经过指定https://
协议,而后是Buildbot master的域名,而后是/change_hook/github
构建的。
将内容类型设置为application/x-www-form-urlencoded
。在“密码”字段中,输入您在Buildbot主配置文件中选择的秘密密码。您能够选中“Just push”事件触发器,勾选“Active”复选框:
添加新的webhook
完成后,单击“ 添加webhook”按钮。
您将返回到项目的webhooks索引,在该索引中将显示您的新webhook。若是刷新几回,则应在webhook旁边显示绿色复选标记图标,表示邮件已成功传输:
webhooks索引
若是您看到红色的X,请再次单击webhook,而后向下滚动到Recent Deliveries部分。若是您单击failed delivery,能够得到有关出现问题的更多信息。
如今咱们已经有了webhook,咱们能够测试以确保当咱们对存储库进行更改时,Buildbot会被警告,触发Docker中的构建,而且可以成功执行测试套件。
在GitHub fork的主页面中,单击绿色“克隆或下载”按钮左侧的“ 建立新文件 ”按钮:
建立新文件
在随后的屏幕上,建立dummy_file
并填写一些文本:
dummy_file
完成后,单击页面底部的“ 提交新文件”按钮。
接下来,访问您的Buildbot Web界面,若是您还没有经过身份验证,请登陆。
根据您提交dummy_file
到存储库后的时间长度,您可能会看到正在进行的构建,以下所示:
Buildbot 正在构建
若是构建已经完成,则它将位于“最近构建”部分中:
构建完成
咱们定义的构建器名称“npm”用于标记构建。在该示例中,咱们还能够从先前的主配置中看到较早的样本构建器运行。
不管进度如何,单击构建器名称和内部版本号连接以访问构建详细信息页面。此视图包含有关所执行的构建的信息。咱们添加到构建工厂的每一个步骤都将显示在其本身的部分中:
构建详细信息
若是单击某个步骤,将显示该命令的输出。若是出现问题,这能够帮助调试:
调试输出
在上面的输出中,咱们能够验证Buildbot是否在咱们的测试套件中成功运行了三个测试。
若是构建未成功完成,您可能但愿检查的其余一些区域是构建详细信息页面上的其余选项卡以及/home/buildbot/master/twistd.log
文件。
调整Buildbot服务
在咱们完成以前,咱们应该对咱们的Buildbot服务进行一些调整。
目前,咱们为再也不使用的工做人员定义了buildbot-worker
服务(咱们的Docker工做程序在须要时自动启动)。
咱们应该中止并禁用old worker。
要中止正在运行的服务并禁止它在引导时启动,请输入:
$ sudo systemctl stop buildbot-worker $ sudo systemctl disable buildbot-worker
Removed symlink /etc/systemd/system/buildbot-master.service.wants/buildbot-worker.service.
上面的输出结果代表工做人员下次启动时不会启动。要验证服务是否再也不运行,请输入:
$ sudo systemctl status buildbot-worker
● buildbot-worker.service - BuildBot worker service Loaded: loaded (/etc/systemd/system/buildbot-worker.service; disabled; vendor preset: enabled) Active: inactive (dead) Jun 27 21:12:48 bb6 systemd[1]: Started BuildBot worker service. Jun 27 21:55:51 bb6 systemd[1]: Stopping BuildBot worker service... Jun 27 21:55:51 bb6 systemd[1]: Stopped BuildBot worker service.
咱们应该作的最后一件事是在Buildbot主服务和Docker守护进程之间创建一个soft依赖项。因为Buildbot主服务没法在没有Docker的状况下配置new workers,所以咱们应该定义此要求。
打开/ etc / systemd / system
目录中的buildbot-master.service
文件以调整服务文件:
$ sudo nano /etc/systemd/system/buildbot-master.service
在[Unit]
部分中,将docker.service
添加到network.target
项以后的After指令中。添加另外一个名为docker.service
的Wants
指令。Wants创建了一个软依赖,而After
指令创建了起始顺序:
/etc/systemd/system/buildbot-master.service
[Unit] Description=BuildBot master service After=network.target docker.service Wants=docker.service [Service] User=buildbot Group=buildbot WorkingDirectory=/home/buildbot/master ExecStart=/usr/local/bin/buildbot start --nodaemon [Install] WantedBy=multi-user.target
完成后保存并关闭文件。
从新加载systemd守护程序和服务以当即应用配置:
$ sudo systemctl daemon-reload $ sudo systemctl restart buildbot-master
如今应该在Docker可用以后启动Buildbot主进程。
在本教程中,咱们将Buildbot配置为使用webhooks监听对GitHub存储库的更改。收到更改后,Buildbot会根据自定义Docker镜像启动容器以测试新提交。Docker镜像包含一个Buildbot工做器实例以及测试项目代码所需的依赖项。这容许Buildbot在对存储库进行更改时根据须要动态启动Buildbot worker。
参考文献:《How To Set Up Continuous Integration with Buildbot on Ubuntu 16.04》
问答
相关阅读
此文已由做者受权腾讯云+社区发布,原文连接:https://cloud.tencent.com/dev...
欢迎你们前往腾讯云+社区或关注云加社区微信公众号(QcloudCommunity),第一时间获取更多海量技术实践干货哦~
海量技术实践经验,尽在云加社区! https://cloud.tencent.com/dev...