跳转到主要内容

Buildbot持续集成工具的扩展

项目描述

Build Status

Ursa Labs为Apache Arrow构建的Buildbot配置

Ursabot是基于buildbot框架的持续集成框架。ursabot的主要目标是执行各种构建、基准和打包任务,用于Apache Arrow,但ursabot也可以用于任意项目。

显著特性

  • a独立的项目抽象,使项目配置模块可重用,并支持多个项目的简洁主配置
  • 通过命令行界面进行本地可重复构建
  • 在构建失败时附加到docker工作进程的交互式shell
  • 为docker工作进程进行本地源挂载
  • 声明性构建器配置和docker构建器,使得与docker潜在工作进程协同工作更加容易
  • 扩展的github钩子,通过github评论驱动buildbot
  • 基于click的评论解析器
  • 改进的变更过滤器,可以根据构建属性进行筛选
  • 重新实现的github报告器:状态报告器、评论报告器和审查报告器
  • 用于与重新实现的报告器一起使用的易于扩展的格式化类
  • 基于新样式ShellCommand步骤实现的方法
  • 一个令牌旋转器,用于使用多个GitHub令牌与GitHub服务一起使用
  • 一个Docker镜像工具,用于维护和构建层次化的Docker镜像
  • 命令行界面和附加工具

驾驶Ursabot

允许PR审查者在审查过程中按需请求额外的检查,这使得我们在审查时更容易施加额外的审查,同时通过使用人类专业知识来确定需要哪些检查来节省CI带宽。

通过评论

Ursabot通过webhook接收GitHub事件。它监听提及@ursabot的pull request评论。它遵循命令行界面的语义,要查看可用的命令,请在pull request上添加评论:@ursabot --help

@ursabot GitHub用户将回复或反应已经开始为您构建。命令解析器在commands.py中实现。

目前可用的命令

  • @ursabot build:触发所有ursabot测试。这些测试会自动运行,但这是一个强制重新构建的方便方式。
  • @ursabot benchmark:触发C++基准测试,并将结果作为GitHub评论发送回去,并突出显示回归。
  • @ursabot crossbow test cpp-python:触发在test.yml中定义的cpp-python测试组,并响应一个指向GitHub UI中提交的crossbow分支的URL,显示构建状态。
  • @ursabot crossbow package -g wheel -g conda:触发在tasks.yml中定义的wheelconda crossbow打包组。
  • @ursabot crossbow package wheel-win-cp35m wheel-win-cp36m:仅触发显式传递的两个任务。

注意,如果提交信息包含跳过模式,例如[skip ci][ci skip],则命令不会触发任何构建。为了驾驶ursabot,用户必须具有'OWNER'、'MEMBER'或'CONTRIBUTOR 角色

通过Web UI

您也可以在buildbot UI中启动特定架构/配置的构建。导航到构建 > 构建器,选择一个构建器,然后点击右上角的构建apache/arrow按钮。这将触发强制调度器,您可以在其中指定要构建的分支和/或提交。将来,专用构建器将具有不同的字段来提供必要的信息。

通过CLI

Buildbot支持直接向集群提交本地补丁并触发特定构建器。TryScheduler是一个测试本地更改而不污染git历史的非常实用的方式

buildbot try \
  --connect=pb \
  --master=... \
  --username=... \
  --passwd=... \
  --get-builder-names

如果有人想使用这个功能,请提出问题,因为这需要自定义凭证。

安装ursabot和CLI

本地运行它有助于开发、测试新功能以及调试问题,而无需触及生产实例。

安装需要至少Python 3.6

cd /path/to/ursabot
pip install -e .

现在ursabot命令可用,该命令在当前目录中查找master.cfg文件。master.cfg可以通过--config选项显式传递

ursabot -c path/to/master.cfg

描述加载的主配置

ursabot desc

描述加载的项目配置

ursabot project desc  # for master configs with a single project
ursabot project -p arrow desc  # for master configs with multiple projects

如何验证配置

checkconfig命令在主配置上运行健全性检查和各种验证。大多数时候,如果checkconfig通过,则主配置可以成功运行(除非有一些仅在运行时才可用的变量)。

ursabot checkconfig

ursabot命令默认从当前目录加载master.cfg,但可以通过--config参数显式定义配置文件。

ursabot -c arrow/master.cfg checkconfig

顶级文件master.cfg包含ci.ursalabs.org的生产配置,因此需要额外的依赖,如pass。要安装pass

which apt && sudo -H apt install -V -y pass
which brew && brew install pass

运行本地Ursabot实例

安装后,必须初始化主数据库

ursabot -v upgrade-master

启动/停止/重启主服务器

ursabot -v start|stop|restart

定义配置环境(prod|test)并启动服务

export URSABOT_ENV=test  # this is the default
buildbot restart ursabot
tail -f ursabot/twisted.log

然后在浏览器中打开http://localhost:8100

本地可重复执行的命令

构建者可以使用ursabot project build命令在本地运行,而不需要使用Web界面。

在主服务器上测试AMD64 Conda C++构建者

ursabot project build 'AMD64 Conda C++'

使用github pull request号140测试AMD64 Conda C++构建者

ursabot project build -pr 140 'AMD64 Conda C++'

使用本地仓库测试AMD64 Conda C++

ursabot project build -s ~/Workspace/arrow:. 'AMD64 Conda C++'

其中~/Workspace/arrow是本地Arrow仓库的路径,而.是工作者的构建目录下的目标目录(在这种情况下:/buildbot/AMD64_Conda_C__.

为构建传递多个buildbot属性

ursabot project build -p prop=value -p myprop=myvalue 'AMD64 Conda C++'

失败时附加

Ursabot支持通过附加普通shell到仍然运行的工作者来调试失败的构建 - 其中构建之前已经失败。

使用--attach-on-failure-a标志。

ursabot project build --attach-on-failure `AMD64 Conda C++`

配置Ursabot

构建master配置发生在master.cfg文件中。最初,buildbot加载名为BuildmasterConfig的字典,但为了使其更灵活和模块化,ursabot引入了ProjectConfigMasterConfig抽象。 ProjectConfig包含测试Apache Arrow或Ursabot自身等项目所需的所有相关信息。ProjectConfig可以独立运行,必须传递给一个提供对原始buildbotBuildmasterConfig的薄抽象的MasterConfig对象。一个MasterConfig可以包含多个ProjectConfig对象。通过包含其他项目配置,可以在项目的仓库内维护与项目相关的设置,而不是在解耦的用于构建master的专用设置。

添加新的构建器

在ursabot中,最接近传统基于yaml的CI配置的抽象是构建者。在最简单的情况下,构建者由在工作者上作为shell命令执行的步骤序列定义。以下示例构建者假定工作者上已安装apt-getgit

from buildbot.plugins import util, worker
from ursabot.steps import ShellCommand
from ursabot.builders import Builder
from ursabot.schedulers import AnyBranchScheduler


repo = 'https://github.com/example/repo'


class TestBuilder(Builder):
    tags = ['example-build', 'arbitrary-tag']
    steps = [
        GitHub(
            name='Clone the test repository',
            repourl=repo,
            mode='full'
        ),
        ShellCommand(
            name='Install dependencies',
            command=['apt-get', 'install', '-y'],
            args=['my', 'packages']
        ),
        ShellCommand(
            name='Execute tests',
            command=['my-custom-test-runner', util.Property('test-selector')]
        )
    ]


# in the master.cfg
local_worker = worker.LocalWorker('my-local-worker')
simple_builder = TestBuilder(
    workers=[local_worker],
    properties={
        'test-selector': 'all'
    }
)
scheduler = AnyBranchScheduler(
    name='my-scheduler-name',
    builders=[simple_builder]
)

project = ProjectConfig([
    name='example/repo',
    repo='https://github.com/example/repo'
    workers=[local_worker],
    builders=[simple_builder],
    schedulers=[scheduler]
])

master = MasterConfig(
    title='TestConfig',
    projects=[project]
)

DockerBuilder提供了更多灵活性,更快的构建和更好的工作者隔离,Ursabot广泛使用DockerBuilders

from ursabot.docker import DockerImage
from ursabot.builders import DockerBuilder
from ursabot.workers import DockerLatentWorker


miniconda = DockerImage(
    'conda',
    base='continuumio/miniconda3',
    arch='amd64',
    os='debian-9'
)


class TestDockerBuilder(DockerBuilder):
    tags = ['build-within-docker-container']
    steps = [
        # checkout the source code
        GitHub(args0),
        # execute arbitrary commands
        ShellCommand(args1),
        ShellCommand(args2),
        # ...
    ]


docker_worker = DockerLatentWorker(
    name='my-docker-worker'
    arch='amd64'
    password=None,
    max_builds=2
)

# instantiates builders based on the available workers, the Builder's
# images and the workers are matched based on their architecture
docker_builders = TestDockerBuilder.combine_with(
    workers=[docker_worker],
    images=[miniconda]
)

scheduler = AnyBranchScheduler(
    name='my-scheduler-name',
    builders=docker_builders
)

project = ProjectConfig([
    name='example/repo',
    repo='https://github.com/example/repo'
    images=[miniconda],
    workers=[docker_worker],
    builders=docker_builders,
    schedulers=[scheduler]
])

master = MasterConfig(
    title='TestConfig',
    projects=[project]
)

定义Docker镜像

Arrow支持多个平台,具有广泛的功能,因此有很多依赖项。在每次构建中安装它们将消耗时间和资源,因此ursabot提供可重用的Docker镜像。

ursabot.docker模块中有一个小的Docker实用程序来定义分层镜像。它使用在Python中实现的DSL而不是纯Dockerfile。以下是一个演示其用法的小示例

from ursabot.docker import DockerImage, ImageCollection
from ursabot.docker import RUN, ENV, CMD, ADD, apt, conda


miniconda = DockerImage(
    name='conda',
    base='continuumio/miniconda3',
    arch='amd64',
    os='debian-9'
)
pandas = DockerImage(
    name='pandas',
    base=miniconda,
    steps=[
        RUN(conda('pandas'))
    ]
)
pyarrow = DockerImage(
    name='pyarrow',
    base=miniconda,
    steps=[
        RUN(conda('pyarrow'))
    ]
)

images = ImageCollection([miniconda, pandas, pyarrow])

# create a docker image for each of the previous ones running jupyter notebook
jupyter_steps = [
    RUN(conda('jupyter')),
    CMD([
        'jupyter', 'notebook',
        '--ip', '0.0.0.0',
        '--no-browser',
        '--allow-root'
    ])
]
images.extend(
    DockerImage(
        name=image.name,
        base=image,
        tag='jupyter',
        steps=jupyter_steps
    )
    for image in images
])

# build all of the images in topological order
images.build()

# filter the images
print(images.filter(name='pyarrow', tag='jupyter'))

尝试运行预先安装了pyarrow的jupyter

docker run -p 8888:8888 amd64-debian-9-pyarrow:jupyter

Ursabot有一个CLI界面来构建Docker镜像

ursabot docker build --help

列出Arrow C++ amd64 conda cpp镜像

ursabot --verbose docker --arch amd64 --variant conda --name cpp list

附加过滤

ursabot docker --arch amd64 list
ursabot docker --arch amd64 --variant conda list
ursabot docker --arch amd64 --variant conda --name cpp list
ursabot docker --arch amd64 --variant conda --name cpp --tag worker list
ursabot docker --arch amd64 --variant conda --name cpp --os debian-9 list

构建并推送Arrow C++ amd64 conda cpp镜像

ursabot --verbose docker --arch amd64 --variant conda --name cpp build --push

构建并推送所有arm64v8 alpine镜像

ursabot --verbose \
  docker --docker-host tcp://arm-machine:2375 --arch arm64v8 --os alpine-3.9 \
  build --push

开发Ursabot

Buildbot不通过二进制轮分布其测试套件,因此为了运行单元测试,必须从源代码安装buildbot。

pip install --no-binary buildbot -e .
pytest -v ursabot

pre-commit钩子

安装pre-commit,然后设置git 钩子,运行pre-commit install

向ci.ursalabs.org添加新的工作者

添加Docker潜在工作者需要在workers.yaml配置文件中添加工作者条目。需要名称、架构和可由构建主访问的Docker主机(见workers.yaml中的示例)。添加非Docker工作者也是可能的,但必须在master.cfg中注册。

可能的进一步改进

这些已经被讨论过,并且很有价值,但它们绝对是“锦上添花”的,应该在主要目标实现后再进行。

  • 用于存储基准测试结果的数据库
  • 用于托管构建工件的中心站
  • 显示所有平台和配置的构建健康情况的仪表板

更接近Ursabot相关

  • 用于扩展的多主设置
  • 设置WAMP/Crossbar以重启构建主而不会取消正在进行的构建
  • Windows容器和工作者(虚拟化节点中的Docker)

项目详情


下载文件

下载适合您平台文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

ursabot-0.1.0.tar.gz (101.0 kB 查看哈希值)

上传时间

构建分布

ursabot-0.1.0-py3-none-any.whl (85.9 kB 查看哈希值)

上传时间 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面