持续交付:静态分析

这是“连续交付”系列的第三篇文章。 CI工具设置以Jenkins启动并运行结束,等待我们使用它。 另一方面,特拉维斯(Travis)被搁置一旁,很快我们就会明白为什么。

在本文中,我们将探讨静态分析,这是我们在交付管道中应执行的第一类任务。 既然这是我们的出发点,那么让我们看一下简短的解释。

静态分析

静态程序分析是对没有实际执行程序的情况下执行的计算机软件的分析(对执行程序执行的分析称为动态分析)。

在我们的案例中,我们将专注于Java和三种类型的分析:

  • Checkstyle :查找违反编码约定的情况。
  • Findbugs :在已编译的Java代码中查找错误。
  • PMD :寻找Java源代码中的潜在问题。

即使在示例中使用Java,相同的想法也适用于任何其他语言。 这三个工具都很有价值,并且执行不同的功能(即使存在重叠的区域)。 组合并正确设置它们后,它们可以对代码提供良好的初始评估,这些代码可用于决定是否值得继续进行其余的传递管道。 请记住,我们失败的速度越快,我们就会知道如何解决。 因此,静态分析通常是第一道防线。 所有流行的IDE都支持静态分析,因此在很多情况下,甚至在进入Jenkins和Travis之类的工具之前,都可以检测到问题。

在较大的项目中,您可能需要使用SonarQube 。 出于本文的目的,我们决定在没有Sonar的情况下寻求简单和极简的解决方案。

格斗风格 Checkstyle是一种开发工具,旨在帮助程序员编写遵守编码准则的Java代码。

Checkstyle是高度可配置的,并且可以使其支持几乎所有编码标准。 提供了一个支持Sun代码约定的示例配置文件。 同样,还为其他众所周知的约定提供了其他示例配置文件。

我的经验是,在大多数情况下,需要自定义配置文件。 预先定义的规则通常是一个过大的杀伤力,在某些情况下可能会导致生产力下降而没有任何实际收益。 但是,一旦团队成立并开始使用最适合的(定制)样式(通常是配置更改的反复试验类型的结果),则代码可读性明显提高。 关于编码标准,位于“同一页上”使每个人在阅读和编写代码时都更加自在。

臭虫 Findbugs尝试查找可能导致bug的“已知问题”。 与我学会了爱与恨的checkstyle不同,如果有的话,checkstyle需要很多摆弄,而Findbugs产生的警告几乎总是可能的缺陷,在某种程度上可能是有害的。 Findbugs的优点是它通常会发现真正的缺陷并且误报率很低。 不利的一面是,它需要编译后的代码。 理想情况下,应该在实际编译之前首先进行静态分析,并且Findbugs迫使我们创建类文件以运行它。

pmd_logo PMD在Java源代码中查找潜在的问题,可能的错误,未使用的和次优的代码以及过于复杂的表达式。 它发现的实际问题的数量通常比Findbugs的数量少。 另一方面,它可以发现与最佳实施不当(或运气不佳)相关的问题。

詹金斯的职位设置

现在该开始在我们的交付管道中实施静态分析了。 本文中的示例将使用TechnologyConversationsCD存储库中的源代码。 Src目录包含从网球比赛kata复制的源代码。 为了使我们的Jenkins作业正常工作,我们必须从存储库中提取代码,运行静态分析并发布结果。

所有执行将由Gradle执行。 本文将不会详细介绍Gradle的工作原理,也不会介绍为什么我们选择使用Ant,Maven和其他构建工具。 有关更多详细信息,请访问Gradle网站

让我们从安装缺少的程序和几个Jenkins插件开始。

上一篇文章CI Tools设置中创建的Dockerfile将需要进行修改。 我们首先将GIT客户端和Gradle添加到我们的容器中。

[Dockerfile]
# GIT
RUN apt-get install -q -y git

# Gradle
ADD https://services.gradle.org/distributions/gradle-1.12-all.zip /opt/gradle-1.12-all.zip
RUN unzip /opt/gradle-1.12-all.zip -d /opt/
ENV GRADLE_HOME /opt/gradle-1.12
ENV PATH $PATH:$GRADLE_HOME/bin

完整的源代码可以在我们的GitHub存储库中的Dockerfile中找到。

一旦安装了所有软件(GIT,Gradle,Jenkins等),我们将需要添加缺少的插件。 到此时,您应该已经熟悉Docker。

[Dockerfile]
# Jenkins: Plugins
ADD https://updates.jenkins-ci.org/latest/git.hpi /jenkins/plugins/git.hpi
ADD https://updates.jenkins-ci.org/latest/gradle.hpi /jenkins/plugins/gradle.hpi
ADD https://updates.jenkins-ci.org/latest/analysis-collector.hpi /jenkins/plugins/analysis-collector.hpi
ADD https://updates.jenkins-ci.org/latest/checkstyle.hpi /jenkins/plugins/checkstyle.hpi
ADD https://updates.jenkins-ci.org/latest/findbugs.hpi /jenkins/plugins/findbugs.hpi
ADD https://updates.jenkins-ci.org/latest/pmd.hpi /jenkins/plugins/pmd.hpi

完整的源代码可以在我们的GitHub存储库中的Dockerfile中找到。

为简洁起见,本文对Dockerfile进行了其他一些小的更改。 请从仓库中获取完整副本。

将Dockerfile推送到GitHub并由Docker编译后,我们的新容器就可以从Vagrantfile或手动运行中使用。

要重新加载我们的Vagrant VM,请从Vagrantfile所在的目录中运行以下命令:

[Vagrantfile]
vagrant reload --provision

您可以通过在喜欢的浏览器中打开http:// localhost:4567来查看Jenkins服务器。 我们已经下载并安装了插件(更多信息可以在http:// localhost:4567 / pluginManager / installed中找到 )。 与服务器上设置的GIT和Gradle一起,我们准备开始创建我们的第一份工作。

职位

创建新的詹金斯工作很容易。 左侧菜单中的第一项是“新项”。 在“项目名称”中键入“ myFirstJob”,选择“构建自由样式的软件项目”,然后单击“确定”按钮。 在詹金斯(Jenkins)的工作中,一个人可以完成的任务数量非常多。 但是,我们仅关注代码分析。 我们将执行以下操作:

  • 拉码
  • 运行分析
  • 发布结果

拉码

詹金斯吉特 选择“ GIT”作为“源代码管理”,然后添加您的存储库。 出于本练习的目的,您可以使用我们的仓库: https : //github.com/vfarcic/TechnologyConversationsCD.git

接下来,我们需要设置触发器,使詹金斯提取代码。 通常,您将创建一个GitHub钩子,该仓库钩子将在回购内容更改时通知您的Jenkins实例。 但是,我们将采用其他方法并定期提取代码。 这种做法背后的原因是因为我们当前正在localhost上运行。 在生产中,请使用钩子而不是如下所述进行拉动。

jenkinspollscm 在“ Build Triggers”的“ Pool SCM”部分中设置“ * * * * *”。 5 * s表示每小时的每一分钟或一周中的每一天的每一天。 调度语法与Linux cron中使用的语法非常相似。 Jenkins提供的解释对于大多数用户来说通常就足够了。

现在,Jenkins每分钟都会拉动GitHub。 如果这些拉出之一检测到代码更改,则此作业会将代码拉到工作区。 接下来,我们将使用此代码进行操作。

运行Gradle任务

由于Gradle是我们选择的武器,因此我们将使用它来进行静态分析。 要启用Checkstyle,Findbugs和PMD分析,我们要做的就是添加插件。 这是位于源代码根目录中的build.gradle文件的摘录:

apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'

完整的源代码可以在我们的GitHub存储库中的build.groovy中找到。

詹金斯格勒 而已。 这三行代码创建了新的Gradle任务,例如:checkstyleMain,checkstyleTest,findbugsMain等。我们感兴趣的是任务“ check”。 它将运行所有静态分析任务。 目前,它们包括上述内容。 只需放置新插件即可添加更多内容。

要从Jenkins运行Gradle任务,请从“构建”部分的“添加构建步骤”列表中选择“调用Gradle脚本”。 由于我们已经确定,我们唯一需要的任务就是“检查”,这正是应该在“任务”字段中输入的内容。

发布分析结果

詹金斯分析出版社 我们快到了。 剩下的就是发布结果,以便可以轻松获得它们。

要发布Checkstyle结果,请从“添加构建后操作”列表中选择“发布Checkstyle分析结果”。 “ Checkstyle结果”字段应具有
值“ build / reports / findbugs / *。xml”。 对于Findbugs和PMD,应重复相同的设置。 查看“高级”按钮后面隐藏的选项,尤其是“状态阈值”。 “高级”部分中最重要的选项可能是“始终运行”复选框。 没有它,发布者仅在没有静态分析警告的情况下运行。

运行工作

现在我们已完成所有设置,唯一缺少的是运行作业。 我们已经将作业设置为只要GIT存储库发生更改就可以运行。 詹金斯的工作将在我们下一次推动后尽快进行。 如果还不够,您可以通过导航到该作业并单击屏幕左侧的“立即构建”链接来运行任何作业。 新版本将开始。 完成后,Checkstyle,Findbugs和PMD报告将位于构建结果内。

Jenkins作业设置摘要

乍一看,所有这些步骤似乎令人生畏。 但是,经过一些实践,整个过程应该不会超过15分钟。 我们做了以下工作:

  • 修改了Dockerfile以包括安装Gradle和GIT的说明。
  • 修改了Dockerfile以下载所需的Jenkins插件。
  • 重新加载了我们的Vagrant VM
  • 创建了一个新的Jenkins作业,该作业将代码从我们的GIT存储库中提取出来,从Gradle构建脚本中运行“检查”任务,最后发布结果。

这仅仅是个开始。 在我们迈向持续交付的道路上,还有许多其他步骤和概念可供探索。 其中一些将在下一篇文章中进行探讨。 现在,我们将重点转移到Travis上,看看如何使用云解决方案来做同样的事情。

特拉维斯

travis徽标 不久您将看到,Travis(至少是云版本)需要的工作量比Jenkins的本地实例少得多。 通常,要使用Travis(除了已注册),我们要做的就是:

  • 从GitHub存储库中启用构建
  • 使用说明创建.travis.yml文件

从GITHub存储库中启用构建

Travis仅适用于GIT存储库。 您可以分叉我们在本文中一直使用的那个。 如果您从未分叉过GITHub仓库,请按照以下说明进行操作:

travis存储库 假设您已经登录,要启用某些GITHub存储库的构建过程,请单击您的名称下的“帐户”。 接下来的屏幕应列出您拥有的所有存储库,并且,如果您分叉了CD存储库,则应为列出的存储库。 打开它。

分叉的存储库本身已经带有.travis.yml。 完整文件很短。

[.travis.yml]
language: java

before_install:
  - chmod +x gradlew

env:
  - TERM=dumb

notifications:
  email:
  - viktor@farcic.com

完整的源代码可以在我们的GitHub存储库中的.travis.yml中找到(以及您刚刚创建的源代码)。

您可能会注意到的第一件事是,与詹金斯不同,我们不需要告诉特拉维斯该怎么办。 单独解决它是足够聪明的。 我们只需要指定一些东西,例如将使用的通知电子邮件。 作为一般规则,特拉维斯要求我们指定非标准的东西,那些他自己无法解决的东西。 如果一个项目是使用某种标准完成的(就像我们正在使用的示例代码一样),Travis完全有能力知道该怎么做。 在这种情况下,除其他外,它将以与Jenkins相同的方式运行Gradle任务“检查”。 如果构建过程的任何部分失败,Travis将停止执行并通过电子邮件(或我们指定的任何其他通信方式)通知我们。

而已。 要对示例代码进行静态分析以便在Travis中工作,我们几乎不需要做任何事情。 仅需要简单的.travis.yml文件。 一个很大的优点是配置文件与我们其余的代码存储在一起。 这大大简化了存储和维护。

Travis的主要缺点是唯一的结果(不会导致某些“黑客”)是日志输出。 没有詹金斯(Jenkins)制作的漂亮报道。 这不一定是坏事。 持续集成,部署和交付的总体思想是,没有新闻是好消息。 如果没有失败,请忽略它。 另一个重要因素是周期很短。 同时应该只有很少的故障,应该优先解决的问题是在团队继续工作之前。 在大多数情况下,通过执行这两项操作(仅针对失败和较短的周期采取措施),就不需要“花哨的”报告了。 但是,达到这一点可能会花费很多时间,许多组织将要求您采取中间步骤,生成报告……如果是这样,詹金斯可能是更好的选择。 就我而言,我同时使用了两者,但是如果我只选择其中之一,那就是特拉维斯。

其他工具

传统表明,这是一个比较详细地比较詹金斯和特拉维斯的好时机。 我将其留给读者。 本系列中即将发表的文章将继续使用两者,并不断进行比较。 现在,我想介绍一些其他工具。

外星人zap-header Drone.io是一个有趣的工具。 在某些方面,它类似于Travis。 在另一些方面,它倾向于詹金斯。 最好的例子是配置。

  • Travis依赖于一个简单的文件来进行所有配置,并且该文件是代码的一部分。
  • Jenkins通过其插件系统提供了无限的可能性。 为此付出的代价可能是增加设置和管理所需的时间。
  • Drone.io都不是。 没有像Travis那样的配置文件,也没有像Jenkins那样的无限可能。 使用Drone.io Web GUI完成配置。 使用“像向导一样”的界面很容易,但仍有一些不足之处。

Travis和Jenkins都提供了功能强大而又不同的方式来配置作业。 Drone.io使用了一个有趣的概念,它仍然需要完善才能使其成为CI / CD工具的头号竞争者。 例如,没有明显的方法在Java项目中使用Gradle。 一旦将其设置为Groovy,它就会起作用。

很高兴看到Drone.io在接下来的几个月中取得进展。

BuildHive是许多基于云的CI服务之一。 它建立在詹金斯(Jenkins)之上。 想法本身非常有趣。 可以将云上的Jenkins转换为功能,而不必担心维护本地服务器。 但是,BuildHive减少了所有功能。 用户没有得到最喜欢的关于Jenkins的东西(插件和无尽的可能性),而回报却很少。 也许除了眼神之外,它还有更多,但对我而言,这是非常令人失望的经历。

Circleci Circle与Travis一样容易上手。 选择仓库,仅此而已。 生成已执行,没有任何问题。 与travis一样,可以使用位于存储库根目录中的circle.yml文件进行其他配置。 请查看本文代码所使用的circle.yml 。 作为附加选项,还有一个Web界面,该界面允许进行调整而无需创建circle.yml文件。

我在本文使用的存储库上运行Circle时注意到的第一件事就是速度。 它比Travis快得多。 但是,这本身并不能说明太多,因为代码仅由两个类组成,很少依赖。 因此,我尝试了一个更大的大型项目(Scala,Play,AngularJS,还有更多依赖项...)。 结果令人失望。 第一次跑步比特拉维斯慢得多。 就像困惑依赖关系一样,它重复了多次相同的长时间提取依赖关系的过程,与Play和SBT测试相混淆,并且两次运行相同的设置,等等。这是非常痛苦的经历,直到29岁之后分钟,大约比Travis慢5-7倍(同一过程通常需要4-6分钟左右)。 我只能假设Scala / Play组合不是Circle喜欢的。 但是,不久之后,Circle与我联系,对问题进行了解释并立即解决。 从那时起,项目的执行时间从29分钟减少到2-3分钟,大约是Travis的一半。

另一个缺点是,除了14天的试用期外,与Travis一样,OSS项目没有免费服务。

对于那些愿意付款的人,Circle是Travis的绝佳替代品。 它使用相同的原理,速度更快,并且拥有真正强大的客户支持。

摘要

我们在Jenkins和Travis上都设置了静态分析。 詹金斯(Jenkins)凭借其插件和Web UI大放异彩,事实证明Travis的设置要容易得多。 两种工具都提供了功能强大(但又非常不同)的自定义作业方式。

下一篇文章将在“持续集成和交付”流程中提供更多详细信息。 我们列表的下一个是测试和代码覆盖率。

我们将把Circle添加到现有工具集中。 所有示例都将使用Jenkins(本地服务器),Travis(云)和Circle(云)完成。 如果您认为探索更多工具是个好主意,请告诉我。

翻译自: https://www.javacodegeeks.com/2014/05/continuous-delivery-static-analysis.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值