跳到内容

ROSE 编译器框架/持续集成

来自维基教科书,为开放世界提供开放书籍
使用 Git 和 Jenkins 的 ROSE 持续集成(为简单说明省略代码审查)

如果没有自动化的持续集成,我们经常会遇到以下情况:

  • 开发人员 A 向我们中央 Git 仓库的 master 分支提交了一些内容。提交包含一些错误,导致我们的构建失败,并且修复需要很长时间。然后中央 master 分支会处于损坏状态数周,因此没有人可以签出/签入任何内容。
  • 开发人员 A 离线做了很多很棒的工作,持续了几个月。但后来发现她的工作与另一个开发人员的工作不兼容。她的工作存在无法解决的合并冲突。

ROSE 项目使用了一个工作流程,该工作流程自动执行了 持续集成 的核心原则,以便将不同开发人员的工作整合在一起变得毫不费力。由于集成过程只将通过所有测试的更改集成到 ROSE 中,因此我们鼓励所有开发人员与最新版本保持同步。

ROSE 开发人员使用的开发模型的概述。

  • 步骤 1:利用基于 Git 的分布式源代码仓库,每个开发人员应该首先从我们的中央 Git 仓库(或其镜像/克隆/分支)克隆自己的仓库。
  • 步骤 2:然后,可以在私有仓库中独立地开发功能或修复错误。开发人员可以创建任意数量的私有分支。每个分支都应该与该开发人员正在处理的功能相关联,并且应该是相对短命的。开发人员可以将更改提交到私有仓库,而无需与共享仓库保持活跃的连接。
  • 步骤 3:当工作完成并经过本地测试(make、make check 和 make distcheck -j#n)后,她可以拉取来自中央仓库 master 分支的最新提交。
  • 步骤 4:然后,她可以将私有仓库中积累的所有提交推送到共享仓库中的分支。我们为每个开发人员在中央仓库中创建一个专用分支,并建立分支的访问控制,以便只有授权的开发人员才能将提交推送到共享仓库的特定分支。
  • 步骤 5-6(自动):来自开发人员私有仓库的任何提交都不会立即合并到共享仓库的 master 分支。

事实上,我们有访问控制来阻止任何开发人员将提交推送到共享仓库的 master 分支。一个名为 Jenkins 的持续集成服务器正在积极监视中央仓库中每个开发人员的分支,并在检测到新的提交后,将对该分支启动全面的提交测试。最后,如果所有测试通过,Jenkins 将新的提交合并到中央仓库的 master 分支。如果单个测试失败,Jenkins 将报告错误,负责的开发人员应该在他们的私有仓库中解决错误,然后再次推送改进的提交。

因此,中央 Git 仓库的 master 分支基本上是稳定的,可以成为我们外部发布的良好候选者。在中央 Git 仓库的 master 分支之上,我们在 Jenkins 中进一步进行更全面的发布测试。如果所有发布测试通过,将基于 master 分支的外部版本在外部发布。

Jenkins 上的测试

[编辑 | 编辑源代码]

我们使用 Jenkins(http://hudson-rose-30:8080/)来测试添加到中央 Git 仓库的开发人员发布候选分支的提交。

测试分为三类:

  • 集成:用于检查新的提交是否能通过各种 "make check" 规则、兼容性测试、可移植性测试、配置测试等。如果所有测试通过,提交将被合并(或集成)到中央仓库的 master 分支。
  • 发布:使用外部基准对更新后的中央仓库 master 分支进行额外的一组测试。如果所有测试通过,master 的头部将被发布为一个稳定的快照,用于公共文件包发布(由 "make dist" 生成)。
  • 其他:目前用于信息目的,没有在我们的生产工作流程中使用。

因此,对于每个推送(一个或多个提交到 -rc 分支),它将经过两个阶段:集成测试阶段和发布测试阶段。

每个开发人员有责任确保他们的提交能通过两个阶段的测试,方法是通过修复测试发现的任何错误

安装的软件包

[编辑 | 编辑源代码]

这里列出了 Jenkins 安装和使用的软件包。

  • Yices: /export/tmp.hudson-rose/opt/yices/1.0.34

开发 Jenkins

[编辑 | 编辑源代码]

几个配置

GCC_VERSION=4.4.7
BOOST_VERSION=1_47_0
source /nfs/casc/overture/ROSE/opt/rhel6/x86_64/rose_environment.sh
__rose__JAVA_VERSION_HOME=/nfs/casc/overture/ROSE/opt/rhel6/x86_64/java/jdk/1.7.0_51
GCC_VERSION=4.8.1
BOOST_VERSION=1_50_0
source /nfs/casc/overture/ROSE/opt/rhel6/x86_64/rose_environment.sh
__rose__JAVA_VERSION_HOME=/nfs/casc/overture/ROSE/opt/rhel6/x86_64/java/jdk/1.7.0_51

检查测试结果

[编辑 | 编辑源代码]

可以手动跟踪您的提交在 Jenkins 测试管道中的进度(http://hudson-rose-30:8080/)。但这样做可能会很乏味和难以管理。

因此,我们提供了一个仪表板(http://sealavender:4000/)来总结对您的发布候选分支 (-rc) 的提交以及每个集成测试的通过/失败状态。

注意:所有测试作业(最终)都可能通过,但实际的集成未执行。这通常发生在您的作业之一出现系统故障时,例如,因此需要手动重新启动。如果您发现所有作业都已通过,但您的工作尚未集成,请联系 Jenkins 管理员。

经常失败的任务

[编辑 | 编辑源代码]

ROSE 编译器框架/Jenkins 失败 中查看详细信息。

与代码审查的连接

[编辑 | 编辑源代码]
Github Enterprise 和 Jenkins 之间的连接

实际上,现在大多数 LLNL 开发人员被要求首先将内容推送到 Github Enterprise 进行 代码审查,而不是直接推送到我们的中央 Git 仓库。Github Enterprise 的代码审查仓库和我们的中央 Git 仓库之间的同步是自动化的。

自动拉取

[编辑 | 编辑源代码]

自动拉取:我们在 (https://hudson-rose-30:8443/jenkins/) 还有一个 Jenkins 服务器,它充当 Github 企业版和我们主要生产 Jenkins 之间的桥梁。

  • 对于 Github 企业版上的每个私有仓库,我们都有一个 Jenkins 任务来监控 master 分支以获取已批准的拉取(合并)请求。如果有任何新的已批准的提交,该任务将把提交转移到该开发人员的中央仓库的 -reviewed-rc 分支。

自动拉取任务的配置

  • 源代码管理
  • 构建触发器:轮询 SCM,计划 "* * * * *"
  • 执行 shell
##
## Add /nfs as remote
##
## `|| true`: don't error if remote exists
##
git remote add nfs /nfs/casc/overture/ROSE/git/ROSE.git || true
git fetch nfs

##
## Push to /nfs *-rc
##
if [ -n "$(git log --oneline nfs/master..github/master)" ]; then
  git push --force nfs "$GIT_BRANCH":refs/heads/oun-reviewed-rc
fi

自动推送

[编辑 | 编辑源代码]

自动推送:一个 Jenkins 任务负责将最新的中央 master 内容传播到 github.llnl.gov 上的所有私有仓库。

该任务的配置

  • 源代码管理
    • Git: /nfs/casc/overture/ROSE/git/ROSE.git
    • 要构建的分支:*/master
  • 构建触发器:在其他项目构建后构建:提交
  • 执行 Shell
USERS="\
user1\
user2
"

for user in $USERS; do
  tmpfile="$(mktemp)"
  ( git push [email protected]:"$user"/rose.git origin/master:refs/heads/master 2>"$tmpfile" ) || true
  set +e
  cat "$tmpfile"
  cat "$tmpfile" | grep -q "non-fast.*forward"
  if [ $? -eq 0 ]; then
    echo "Sending error email to [${user}@llnl.gov] because their github/master is non-fast-forwardable"
    # email details are omitted here.
  fi
done

重现 Jenkins 任务故障

[编辑 | 编辑源代码]

几个关键要素

  • Jenkins 脚本库
  • 正确的 ROSE 版本
  • 硬件机器
  • 环境

假设一个失败的任务是 https://hudson-rose-44.llnl.gov:9443/jenkins/job/development-compile-with-autotools-default-EDG-RHEL6/892/gcc=4.4.7,label=RHEL6,rhel=6/parameters/

步骤

#!/bin/bash -ex

export GCC_VERSION="$gcc"

rm -rf ./jenkins-build-scripts/ || exit 1
git clone [email protected]:jenkins/dev/jenkins-build-scripts.git || exit 1
source ./jenkins-build-scripts/config/env-Linux.sh $gcc $rhel || exit 1
./jenkins-build-scripts/development/development-compile-with-autotools-default-EDG-RHEL6.sh $gcc || exit 1
  • 相同的配置页面包含一个配置矩阵,其中包含所有用户定义的参数和值,包括 gcc 版本、操作系统版本和其他参数。

现在手动签出提交,并使用传递的正确 gcc 版本和 rhel 版本运行脚本

  • ../jenkins-build-scripts/config/env-Linux.sh "4.4.7" 6
  • git clone [email protected]:rose/scratch/rose sourcetree
  • cd sourcetree/
  • git checkout -b autopar 83abd459eee1b575b4e7fab04a9f1dfc4955f02a
  • git submodule init
  • git submodule update
  • ../jenkins-build-scripts/development/development-compile-with-autotools-default-EDG-RHEL6.sh 4.4.7

待办事项

[编辑 | 编辑源代码]

高优先级

  • 在手动代码审查开始之前添加一个预筛选任务。预筛选任务可以确保要审查的代码将使用最少的警告消息进行编译,并且具有运行测试所需的 make check 规则。
  • 为每个测试的最终结果启用电子邮件通知
  • 逐步添加更多使用外部基准的编译测试,作为集成测试。
    • 最初的两个任务:spec cpu 基准 + NPB Fortran 基准
  • 更好地与 Github 企业版集成

在 Jenkins 中安装用于测试的第三方软件。

  • Yices (http://yices.csl.sri.com/)
    • 下载 Yices1,最新版本更好。
    • 解压缩 yices 的 tarball 包,然后是 YICES_INSTALL,类似于 yices-1.0.34
    • 使用 ROSE/configure 选项输入 --with-yices=YICES_INSTALL
    • 将 YICES_INSTALL/lib 设置为 Linux 的 LD_LIBRARY_PATH 和 mac 用户的 DYLD_LIBRARY_PATH,这类似于将 Boost/lib 添加到 LD_LIBRARY_PATH
  • 用于生成图形的文件:随时添加新版本的幻灯片:链接
华夏公益教科书