JaCoCo 代码覆盖率实践分享

本文适用的是 Gradle 来构建和适用 JaCoCo。

分别介绍了 build.gradle 的文件配置,执行测试和生成报告,报告参数说明,以及如何忽略指定的包或类从而影响测试覆盖率的结果。

build.gradle 文件配置

比如使用 gradle 来管理的项目可以在 build.gradle 里添加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
plugins {
id 'jacoco'
}


jacoco {
toolVersion = "0.8.5"
}

test {
useJUnitPlatform()
exclude '**/**IgnoreTest.class' // 如果有 test case 不通过,如有必要可以通过这样忽略掉
finalizedBy jacocoTestReport // report is always generated after tests run
}

jacocoTestReport {
dependsOn test // tests are required to run before generating the report
reports {
xml.enabled true
csv.enabled false
html.destination file("${buildDir}/reports/jacoco")
}
}

执行测试,生成代码覆盖率报告

然后执行 gradle test 就可以了。之后可以可以在 build\reports\jacoco 目录下找到报告了。

JaCoCo报告

重点是如何分析报告。打开 index.html,报告显示如下:

JaCoCo报告首页

报告参数说明

Read More

Pythonic 是什么意思?

什么是 Pythonic

由于 Python 的跨平台、易读、易写、丰富的package等众多特性,Python 对于 DevOps/测试开发 工程师是非常好的语言之一。

我也用它完成了很多工作,同时也投入了更多时间来深入去学习 Python,想去写出更优秀、更 Pythonic 的代码。

Pythonic 这个词是几年前一位非常资深的华人程序员他在给我培训的时候总提到了项目中有一些代码不够 Pythonic,需要重构。根据语境,我理解他的意思:Pythonic 就是以 Python 的方式来写代码!

即:充分利用 Python 语言的特性来产生清晰、简洁和可维护的代码。Pythonic 的意思是指代码不仅仅是语法正确,而是遵循 Python 社区的惯例,并以其预期的方式使用该语言。

举例

以下是 C/C++ 程序员的一段代码:

1
2
3
4
5
6
7
int a = 1;
int b = 100;
int total_sum = 0;
while (b >= a) {
total_sum += a;
a++;
}

如果没有学习 Python 编程模式,那么将上面的代码改用 Python 来写可能会是这样:

1
2
3
4
5
6
a = 1
b = 100
total_sum = 0
while b >= a:
total_sum += a
a += 1

如果是真正的 Python 程序员用 Pythonic 的方式来写,应该是这样的:

1
total_sum = sum(range(1, 101))

关于 Pythonic 的“官方介绍”

其实,Python 命令行里已经秘密“隐藏”了关于 Pythonic 的介绍。只要打开 Python 控制台,输入 import this,你就能看到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
C:\Users\xshen>python
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
>>>

直译过来是:Tim Peters的《Python的禅意》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
美丽的比丑陋的好。
明确的比含蓄的好。
简单的比复杂的好
复杂的比复杂的好
扁平的比嵌套的好。
稀疏比密集好。
可读性很重要。
特殊情况不特殊,不足以打破规则。
虽然实用性胜过纯粹性。
错误永远不应该默默地通过。
除非明确沉默。
在面对模棱两可的情况下,拒绝猜测的诱惑。
应该有一个--最好只有一个--明显的方法。
虽然这种方式一开始可能并不明显,除非你是荷兰人。
现在总比不做要好。
虽然从不比现在*好。
如果实现很难解释,那就是个坏主意。
如果实现很容易解释,它可能是个好主意。
命名空间是一个非常棒的想法--让我们做更多的命名空间!

关于 Pythonic 你 get 到了吗?

Different branches have different default parameters in Jenkins

Problem

When you use Jenkins multibranch pipeline, you may want to have different default parameters settings for defferent branches build.

For example:

For develop/hotfix/release branches, except regular build, you also want to do some code analyzes, like code scanning, etc.
For other branches, like feature/bugfix or Pull Request that you just want to do a regular build.

So you need to have dynamic parameter settings for your multibranch pipeline job.

Solution

So for these cases, how to deal with Jenkins multibranch pipeline. Here are some code snippet that is works well in my Jenkinsfile.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def polarisValue = false
def blackduckValue = false

if (env.BRANCH_NAME.startsWith("develop") || env.BRANCH_NAME.startsWith("hotfix")
|| env.BRANCH_NAME.startsWith("release")) {
polarisValue = true
blackduckValue = true
}

pipeline {
agent { node { label 'gradle' } }

parameters {
booleanParam defaultValue: polarisValue, name: 'Polaris', description: 'Uncheck to disable Polaris'
booleanParam defaultValue: blackduckValue, name: 'BlackDuck', description: 'Uncheck to disable BD scan'
}

stages {
// ...
}
}

Google 的代码审查法则以及我的实践和思考

Code Review 每个人都知道它很好,应该去好好做,但往往执行起来效果并不好。一来读别人代码需要花时间,往往还需要对方给你讲,执行成本太高;二来自己手头的工作也很多,时间不允许,执行不到位。

如果你还不知道如何开展 Code Review 以及如何定规则,Google 的这篇关于 Code Review 的文章可供借鉴,里面提到了很多具体的 Review 法则。

Google 的代码审查法则

在进行代码审查时,应确保:

  • 代码经过精心设计
  • 该功能对代码用户很有帮助
  • 任何 UI 更改都是明智的,并且看起来不错
  • 任何并行编程都是安全完成的
  • 代码没有比需要的复杂
  • 开发人员没有实现他们将来可能需要的东西,但不知道他们现在需要什么
  • 代码具有适当的单元测试。
  • 测试经过精心设计
  • 开发人员对所有内容使用了清晰的名称。
  • 注释清晰实用,并且主要说明原因而不是原因
  • 代码已正确文档化(通常在g3doc中,Google内部工程文档平台)。
  • 该代码符合我们的样式指南

确保检查要求你检查的每一行代码,查看上下文,确保你在改善代码运行状况,并称赞开发人员所做的出色工作。

https://google.github.io/eng-practices/review/reviewer/looking-for.html

下面我在结合我的经验从流程、自动化、自我要求方面分享一些想法。

流程

规避任何不经 Review 的代码进入到主分支

我使用的是 Bitucket,因此下面都是以 Bitucket 为例。GitHub 以及 GitLab 在设置上大同小异。

  • 打开分支权限设置里的选项 Prevent changes without a pull request 打开它。另外,这个选项里也可以添加 Exception,就是这些人可以不通过 Pull Reuqest 来提交代码。

  • 在 Merge Check 里开启 Minimum approvals 这个选项,我的设置 Number of approvals = 1,及比如有一人点击 Approve 按钮才允许 Merge

自动化

通过 CI/CD,自动化进行编译和测试验证

  • 建立自动化构建和自动化测试的 Pipeline,能够在创建 Pull Request 的时候,或是针对任何分支进行构建和测试。比如 Jenkins 的 Multi-branch pipeline 功能。

  • 当上面的 Pipeline 已经稳定,开启在 Bitucket 的 Merge Check 里 Minimum successful builds 选项,以防止任何没有通过编译和测试的代码进入主分支。

  • 可以通过写一个小工具来分析每次的 Pull Request 里有哪些文件做了修改,假定这些文件过往的历史中哪个人修改的次数最多,就认为这个人对这部分的代码最为熟悉,然后推荐他来作为 Reiewer。这里的推荐机制可以再完善,这里只是提供一个思路。

    自我要求

最后我想从责任感和品味来谈谈自我要求。

这个不是每个人都有的,如果你喜欢你的产品,你觉得自己的工作很有意义,那么你一定愿意去保障你每提交的任何代码的正确性。不论我作为提交者还是 Reviewer,在对代码修改不是特别有把握的时候,我会请教更资深的程序员来一起 Review,古话说,三人行必有我师焉,来看看别人有什么建议。

另外,我觉得想成为一个优秀的程序员,那么一定要有“品味”,而且品味是能够培养出来的。就跟看画展一样,你看到的优秀的作品越多,品味就会提升的越快,才会知道当初自己画的那个“小鸡吃米”不香了。因此要多看看外面的世界,尤其是那些大厂,大牛的代码。

Jenkins upgrade issue "Windows agents won't start" workaround

Today, when I tried to upgrade my team’s Jenkins server from Jenkins 2.235.1 to Jenkins 2.263.3, I met a problem that can not launch the Windows agent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[2021-01-29 23:50:40] [windows-agents] Connecting to xxx.xxx.xxx.xxx
Checking if Java exists
java -version returned 11.0.2.
[2021-01-29 23:50:40] [windows-agents] Installing the Jenkins agent service
[2021-01-29 23:50:40] [windows-agents] Copying jenkins-agent.exe
ERROR: Unexpected error in launching an agent. This is probably a bug in Jenkins
Also: java.lang.Throwable: launched here
at hudson.slaves.SlaveComputer._connect(SlaveComputer.java:286)
at hudson.model.Computer.connect(Computer.java:435)
at hudson.slaves.SlaveComputer.doLaunchSlaveAgent(SlaveComputer.java:790)
...
...
at java.lang.Thread.run(Thread.java:748)
java.lang.NullPointerException
at hudson.os.windows.ManagedWindowsServiceLauncher.launch(ManagedWindowsServiceLauncher.java:298)

This issue had been raised in the Jenkins Jira project: JENKINS-63198 and JENKINS-63198

There is also a Windows Support Updates guide here that mentioned this problem.

Finally, I fixed this problem by the following steps:

  1. Update windows-slaves-plugin to the lastest version 1.7 (fixes for Jenkins 2.248+)

Then the error should be like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[2021-01-30 23:53:40] [windows-agents] Connecting to xxx.xxx.xxx.xxx
Checking if Java exists
java -version returned 11.0.2.
[2021-01-30 23:53:47] [windows-agents] Copying jenkins-agent.xml
[2021-01-30 23:53:48] [windows-agents] Copying agent.jar
[2021-01-30 23:53:48] [windows-agents] Starting the service
ERROR: Unexpected error in launching an agent. This is probably a bug in Jenkins
org.jinterop.dcom.common.JIException: Unknown Failure
at org.jvnet.hudson.wmi.Win32Service$Implementation.start(Win32Service.java:149)
Caused: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor219.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.kohsuke.jinterop.JInteropInvocationHandler.invoke(JInteropInvocationHandler.java:140)
Also: java.lang.Throwable: launched here
  1. Then change jenkins-agent.exe.config file. remove or comment out this line <supportedRuntime version="v2.0.50727" /> as below

also do this for jenkins-slave.exe.config in case it also exists.

1
2
3
4
5
6
7
8
9
10
11
<configuration>
<runtime>
<!-- see http://support.microsoft.com/kb/936707 -->
<generatePublisherEvidence enabled="false"/>
</runtime>
<startup>
<!-- this can be hosted either on .NET 2.0 or 4.0 -->
<!-- <supportedRuntime version="v2.0.50727" /> -->
<supportedRuntime version="v4.0" />
</startup>
</configuration>
  1. Then try to Launch agent.

If it still does not work and has this error message “.NET Framework 2.0 or later is required on this computer to run a Jenkins agent as a Windows service”, you need to upgrade your .NET Framework.

Here is a link for update .NET Framework.

Hopefully, this could help you to fix connect the issue of the Windows agent. Let me know in case of any questions.

2021年DevOps工程师的学习路线

DevOps 实际上是什么意思?🤔

DevOps 是一种软件开发方法,涉及持续开发,持续测试,持续集成,部署和监视。这一系列过程跨越了传统上孤立的开发和运营团队,DevOps 试图消除它们之间的障碍。

因此,DevOps 工程师基本上与 Development 和 Operations 团队合作。它是这两个主要部分之间的链接。

概念与工具

DevOps 包括诸如构建自动化、CI/CD、基础架构即代码等概念,并且有许多工具可以实现这些概念。由于这些工具数量众多,因此可能会造成混乱和压倒性的结果。

最重要的是要了解概念,并为每个类别的学习找一种特定的工具。例如,当你已经知道什么是 CI/CD 并知道如何使用 Jenkins 时,也将很容易学习同类型的其他替代工具。

接下来让就来看看学习 DevOps 需要掌握哪些技能。

1)软件开发的概念

作为一名 DevOps 工程师,你不会直接对应用程序进行编程,但是当你与开发团队紧密合作以改善和自动化他们的任务时,你需要了解以下概念:

  • 开发人员的工作方式
  • 他们正在使用哪个 git 工作流程
  • 如何配置应用程序
  • 自动化测试

2)操作系统

作为 DevOps 工程师,你负责准备在操作系统上部署应用程序的所需要的基础结构环境。并且由于大多数服务器是 Linux 服务器,因此你需要了解 Linux 操作系统,并善于使用命令行,所以你需要知道:

  • 基本的 Shell 命令
  • Linux 文件系统
  • 管理服务器的基础知识
  • SSH 密钥管理
  • 在服务器上安装不同的工具

3)网络与安全

你还需要了解网络和安全性的基础知识才能配置基础架构,例如:

  • 配置防火墙以保护应用程序
  • 了解 IP 地址,端口和 DNS 的工作方式
  • 负载均衡器
  • 代理服务器
  • HTTP/HTTPS

但是,要在 DevOps 和 IT Operations 之间划清界线,你不是系统管理员。因此,在这里不需要高级知识,理解和了解基本知识就够了。IT 方面是这些 SysAdmins,Networking 或 Security Engineers 人的专长。

4)容器化

随着容器成为新标准,你可能会将应用程序作为容器运行,这意味着你需要大致了解:

  • 虚拟化的概念
  • 容器的概念
  • 学习哪个工具? Docker - 当今最受欢迎的容器技术

5)持续集成和部署

在 DevOps 中,所有代码更改(例如开发人员的新功能和错误修复)都应集成到现有应用程序中,并以自动化方式连续地部署到最终用户。因此,建立完整的 CI/CD 管道是 DevOps 工程师的主要任务和职责。

在完成功能或错误修正后,应自动触发在 CI 服务器(例如 Jenkins )上运行的管道,该管道:

  • 运行测试
  • 打包应用程序
  • 构建 Docker 镜像
  • 将 Docker Image 推送到工件存储库,最后
  • 将新版本部署到服务器(可以是开发,测试或生产服务器)

因此,你需要在此处学习技能:

  • 设置 CI/CD 服务器
  • 构建工具和程序包管理器工具以执行测试并打包应用程序
  • 配置工件存储库(例如 Nexus,Artifactory)

当然,可以集成更多的步骤,但是此流程代表 CI/CD 管道的核心,并且是 DevOps 任务和职责的核心。

学习哪个工具?Jenkins 是最受欢迎的人之一。其他:Bamboo,Gitlab,TeamCity,CircleCI,TravisCI。

6)云提供商

如今,许多公司正在使用云上的虚拟基础架构,而不是管理自己的基础架构。这些是基础架构即服务(IaaS)平台,可提供一系列服务,例如备份,安全性,负载平衡等。

因此,你需要学习云平台的服务。例如。对于 AWS,你应该了解以下基本知识:

  • IAM 服务-管理用户和权限
  • VPC 服务-你的专用网络
  • EC2 服务-虚拟服务器
  • AWS 提供了更多的服务,但是你只需要了解你实际需要的服务即可。例如,当 K8s 集群在 AWS 上运行时,你还需要学习 EKS 服务。

AWS 是功能最强大,使用最广泛的一种,但也是最困难的一种。

学习哪个工具?AWS 是最受欢迎的一种。其他热门:Azure,Google Cloud,阿里云,腾讯云。

7)容器编排

如前所述,容器已被广泛使用,在大公司中,成百上千个容器正在多台服务器上运行,这意味着需要以某种方式管理这些容器。

为此目的,有一些容器编排工具,而最受欢迎的是 Kubernetes。因此,你需要学习:

  • Kubernetes 如何工作
  • 管理和管理 Kubernetes 集群
  • 并在其中部署应用程序

学习哪个工具?Kubernetes - 最受欢迎,没有之一。

8)监视和日志管理

软件投入生产后,对其进行监视以跟踪性能,发现基础结构以及应用程序中的问题非常重要。因此,作为 DevOps 工程师的职责之一是:

  • 设置软件监控
  • 设置基础架构监控,例如用于你的 Kubernetes 集群和底层服务器。

学习哪个工具?Prometheus, Grafana…

9)基础设施即代码

手动创建和维护基础架构非常耗时且容易出错,尤其是当你需要复制基础架构时,例如用于开发,测试和生产环境。

在 DevOps 中,希望尽可能地自动化,那就是将“基础结构即代码(Infrastructure as Configuration)”引入其中。因此使用 IaC ,我们将使用代码来创建和配置基础结构,你需要了解两种 IaC 方式:

  • 基础设施配置
  • 配置管理

使用这些工具,可以轻松地复制和恢复基础结构。因此,你应该在每个类别中都知道一种工具,以使自己的工作更有效率,并改善与同事的协作。

学习哪个工具?

基础架构设置:Terraform 是最受欢迎的一种。
配置管理:Ansible,Puppet,Chef。

10)脚本语言

作为 DevOps 工程师就常见的工作就是编写脚本和小型的应用程序以自动化任务。为了能够做到这一点,你需要了解一种脚本或编程语言。

这可能是特定于操作系统的脚本语言,例如 bash 或 Powershell。

还需要掌握一种独立于操作系统的语言,例如 Python 或 Go。这些语言功能更强大,更灵活。如果你善于使用其中之一,它将使你在就业市场上更具价值。

学习哪个工具?Python:目前是最需要的一个,它易于学习,易于阅读并且具有许多可用的库。其他:Go,NodeJS,Ruby。

11)版本控制

上述所有这些自动化逻辑都作为代码编写,使用版本控制工具(例如Git)来管理这些代码和配置文件。

学习哪个工具?Git - 最受欢迎和广泛使用,没有之一。

DevOps Roadmap [2021] - How to become a DevOps Engineer

预测 2021 年的 DevOps 趋势

DevOps 已经走了很长一段路,毫无疑问,它将在今年继续发光。由于许多公司都在寻求有关数字化转型的最佳实践,因此重要的是要了解领导者认为行业发展的方向。从这个意义上讲,以下文章是 DevOps 领导者对 DevOps 趋势的回应的集合,需要在 2021 年关注。

让我们看看他们每个人对来年的 DevOps 有何评价。

  1. 迁移到微服务将成为必须 —— Wipro Limited 首席 DevOps 工程师

“从整体迁移到微服务和容器化架构对于所有公司的数字化转型之旅都是必不可少的,它不再是一个选择或选项。这就是Kubernetes 的采用率将上升的地方,当组织迁移到多重云时,Terraform 将成为实现基础架构自动化的最终选择。”

  1. Hybrid将成为部署规范 —— JFrog 开发人员关系 VP

“2020年将加速远程工作,加快向云的迁移,并将 DevOps 从最佳实践转变为每个业务的重要组成部分。随着我们进入2021年,该行业将在多个方面拥抱Hybrid。首先,企业将完全采用混合型劳动力,将远程工作和现场团队协作的优势相结合。 其次,商业模式将变得混合,例如将虚拟规模与本地网络合并的会议。最终,随着公司对堆栈进行现代化以利用云原生技术的优势,混合将成为部署规范,但要意识到并非所有事物都可以迁移到外部。2021年的赢家将是拥抱业务,模型和产品混合的公司。”

  1. DataOps将蓬勃发展 - 乐天高级 DevOps 工程师

“DataOps 肯定会在 2021 年蓬勃发展,COVID 可能会在其中发挥作用。由于 COVID 和 WFH 的情况,数字内容的消费量猛增,这要求自动缩放和自我修复系统的自动化达到新水平,以满足增长和需求。

到目前为止,DevOps 设置的系统仅用于日志记录,监视和警报(ELK/EFK 堆栈,Prometheus/Grafana/Alertmanager等)。现在,DevOps 现在应该加强并使用可用数据和指标来 产生有价值的见解,学习并应用机器学习模型来预测事件或中断,开发从数据中学习自身并预测能力的自动化以改进预算计划。许多人已经开始对此部分调用 MLOps/AIOps。”

  1. 弹性测试将成为主流 —— Neotys 产品负责人

从我的角度来看,可观察性,性能测试和弹性测试之间的交叉点将成为主流。 随着 AWS 和 Google 等 WW 领导者最近发布的 Ops 问题,以及各个领域的数字化转型都在加速发展,市场将逐渐意识到,公共或私有云形式提供的无限可扩展性是不够的。” - Neotys 产品负责人 Patrick Wolf

  1. GitOps 将成为常态 —— 梅西百货的首席架构师

“一个“构建,拥有,拥有”的开发过程需要开发人员知道和理解的工具。GitOps 是 DevOps 如何使用开发人员工具来驱动操作的名称。

GitOps 是一种进行持续交付的方法。 更具体地说,它是用于构建统一部署,监视和管理的 Cloud Native 应用程序的操作模型。 它通过将 Git 用作声明性基础结构和应用程序的真实来源来工作。 当在 Git 中推送和批准提交时,自动化的 CI/CD 管道将对你的基础架构进行更改。它还利用差异工具将实际生产状态与源代码控制下的生产状态进行比较,并在出现差异时提醒你。GitOps 的最终目标是加快开发速度,以便你的团队可以安全可靠地对 Kubernetes 中运行的复杂应用程序进行更改和更新。” -梅西百货(Macy’s)首席建筑师 Soumen Sarkar

  1. 将会有更多的迁移到无服务器 —— ADP Lifion 的站点 SRE 经理

“2021 年将是注视更多迁移到无服务器的一年。如果容器和业务流程是 Z 代.. 那么无服务器的实时负载将是 Gen+ .. 仅在你使用时使用和付款可能看起来是一样的.. 但请考虑运行基于 k8s pod 的微服务,以便在需要时在无服务器上运行相同的服务。” - ADP Lifion 网站可靠性工程经理 Shivaramakrishnan G

  1. NoOps 出现 —— ClickIT Smart Technologies 的 CEO

“我希望出现更多托管服务,并减少我们的 DevOps 运营并减少客户的运营支出。更多无服务器应用程序,更多无服务器服务,例如 Aurora 无服务器,Fargate,Amazon S3 和无服务器静态网站。数据中心中的 Amazon ECS/EKS(新版本 re:invent 2020)以及云管理服务,可让你减少数据中心的维护和开发。同样,将更多云原生的原理和功能移植到数据中心,例如。亲戚。” - ClickIT Smart Technologies 首席执行官 Alfonso Valdes

  1. BizDevOps 将大放异彩 —— Petco 的 DevOps 经理

“在架构和公司层次结构方面朝着成本优化的方向发展-随着业务的发展,DevOps 的价值不断提高。

专注于灵活的,云原生的架构和工具,这些功能一旦具备了“大佬”的能力,就可以打包成小型企业使用的包装(Snowflake 或 Hazelcast 与 Oracle/Teradata)

FaaS 才刚刚起步(无服务器,Lambda 等)- 运营问题正在得到解决,人们正在意识到潜力。”

  1. 基础设施即代码(IaC)的地位将更高 —— 沃尔沃高级解决方案架构师

“基础架构即代码(IaC):云中 DevOps 的核心原则。你的基础架构本地或云中的服务器,网络和存储设备(定义为代码)。这使公司可以自动化并简化其基础架构。 IaC 还提供了一个简单的基础结构版本控制系统,该系统可让团队在发生灾难性故障时回退到“有效的最后配置”。这意味着可以快速恢复并减少停机时间。”

  1. 自动化和混乱工程变得非常重要 —— 直布罗陀印度开发中心的集团开发经理

“一切都是自动化的-构建,部署,测试,基础架构和发布。

具有所需质量门的生产线。更快,可重复,可自定义和可靠的自动化是任何项目成功的关键。混沌工程-在当今混合基础设施世界中非常关键的方面。系统行为和客户体验紧密结合在一起,你越早对其进行测试,就越能为客户提供更好的体验。”

  1. 云原生方法将被标准化 —— Ben Sapp

“由于云空间已经真正地发展起来(最近十年左右),并且容器化已成为规范,所以一切都非常标准化,几乎就像大型机时代一样。

当然,会有趋势和赚钱的机会。但是我不知道下一个大破坏者是什么。现在的一切基本上都与五年前的最佳做法相同,但更加可靠。我想越来越多的人将继续从宠物转移到牛身上,剩下诸如 Ansible 和 puppet 之类的工具仅用于打包程序和云 init 来构建容器主机。

imo 是软件开发的黄金时代。 DevOps 和云原生方法已经实现了许多目标。管道,托管,存储,负载平衡……这些都在 5 分钟之内解决了。”

  1. 安全将成为重中之重 —— CloudSkiff

“从 DevSecOps 角度绝对跟踪基础设施中不受控制的变化。作为代码的基础架构很棒,但是有太多可移动的部分:代码库,状态文件,实际云状态。事情倾向于漂移。这些更改可能有多种原因:从开发人员通过 Web 控制台创建或更新基础架构而不告知任何人,到云提供商方面不受控制的更新。处理基础架构漂移与代码库之间的挑战可能会充满挑战。” - CloudSkiff

  1. Chaos Engineering 将变得越来越重要 —— International Technology Ventures 的 CTO

“在更多组织中的 DevOps 规划讨论中,混沌工程将变得越来越重要(且更常见)。大多数组织通常不执行混沌工程学(Chaos Engineering),即在生产中对软件系统进行实验以建立对系统抵御动荡和意外情况能力的信心。

如果我们在传统的五个成熟度模型框架内考虑 DevOps,那么 Chaos Engineering 将是第 4 或第 5 级学科,将包含在 DevOps 实践的保护范围内。正如将单独的测试/质量保证小组的传统角色纳入 DevOops 的学科一样,Chaos Engineering 也应如此。”

  1. 更关注即时日志以快速验证成功或失败 —— ADESA 平台稳定性总监

“在后期部署中使用日志来验证发布是否成功,或存在严重错误。人们需要建立的最大联系是定义手动流程,然后实现自动化的巨大飞跃。一键部署,即时日志可快速验证成功或失败,然后触发回滚。随之而来的是复杂性以及跨服务依赖性,是否可以回滚某些内容,或者是否需要对其他服务进行进一步测试。想象一下 100 种微服务(又称管道,甚至还有 100 个容器)。

作为一项,我总是庆祝成功的回滚,因为它不会对服务产生影响,而且是成功的。” -ADESA平台稳定性总监Craig Schultz

  1. DevSecOps 将成为 DevOps 的默认部分 —— JFrog 的 DevOps 架构师

DevSecOps 的 “Sec” 部分将越来越成为软件开发生命周期中不可或缺的一部分,真正的安全性 “向左移动” 方法将成为新的规范,CI/CD 管道中的专用安全性步骤将更少从开发人员的 IDE 到依赖关系和静态代码分析,安全和自动识别和采取措施将是所有流程步骤的一部分。在没有适当(自动?)解决这些问题的情况下,不会发布软件组件。真正的安全问题是免费软件。”

希望你喜欢我们对 DevOps 趋势的专家综述,并在 2021 年关注。如果你认为这里缺少应考虑的内容,请在评论中分享你的观点。

原文 15 DevOps Trends to Expect in 2021 的翻译。

What's the difference between result and currentResult in Jenkins?

This is just a note to myself about the difference between Jenkins result and currentResult.

Declarative Pipeline

Here is a test code from this ticket JENKINS-46325

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
pipeline {
agent any
stages {
stage ('Init') {
steps {
echo "Init result: ${currentBuild.result}"
echo "Init currentResult: ${currentBuild.currentResult}"
}
post {
always {
echo "Post-Init result: ${currentBuild.result}"
echo "Post-Init currentResult: ${currentBuild.currentResult}"
}
}
}
stage ('Build') {
steps {
echo "During Build result: ${currentBuild.result}"
echo "During Build currentResult: ${currentBuild.currentResult}"
sh 'exit 1'
}
post {
always {
echo "Post-Build result: ${currentBuild.result}"
echo "Post-Build currentResult: ${currentBuild.currentResult}"
}
}
}
}
post {
always {
echo "Pipeline result: ${currentBuild.result}"
echo "Pipeline currentResult: ${currentBuild.currentResult}"
}
}
}

Output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Init result: null
Init currentResult: SUCCESS
Post-Init result: null
Post-Init currentResult: SUCCESS
During Build result: null
During Build currentResult: SUCCESS
[test-pipeline] Running shell script
+ exit 1
Post-Build result: FAILURE
Post-Build currentResult: FAILURE
Pipeline result: FAILURE
Pipeline currentResult: FAILURE
ERROR: script returned exit code 1
Finished: FAILURE

Scripted Pipeline

Here is a test code from cloudbees support case

Example that forces a failure then prints result:

1
2
3
4
5
6
7
8
9
10
node {
try {
// do something that fails
sh "exit 1"
currentBuild.result = 'SUCCESS'
} catch (Exception err) {
currentBuild.result = 'FAILURE'
}
echo "RESULT: ${currentBuild.result}"
}

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
Started by user anonymous
[Pipeline] Allocate node : Start
Running on master in /tmp/example/workspace/test
[Pipeline] node {
[Pipeline] sh
[test] Running shell script
+ exit 1
[Pipeline] echo
RESULT: FAILURE
[Pipeline] } //node
[Pipeline] Allocate node : End
[Pipeline] End of Pipeline
Finished: FAILURE

Example that doesn’t fail then prints result:

1
2
3
4
5
6
7
8
9
10
node {
try {
// do something that does not fail
echo "Im not going to fail"
currentBuild.result = 'SUCCESS'
} catch (Exception err) {
currentBuild.result = 'FAILURE'
}
echo "RESULT: ${currentBuild.result}"
}

Output:

1
2
3
4
5
6
7
8
9
10
11
12
Started by user anonymous
[Pipeline] Allocate node : Start
Running on master in /tmp/example/workspace/test
[Pipeline] node {
[Pipeline] echo
Im not going to fail
[Pipeline] echo
RESULT: SUCCESS
[Pipeline] } //node
[Pipeline] Allocate node : End
[Pipeline] End of Pipeline
Finished: SUCCESS

These settings in Bitbucket/GitHub recommends enable

As I have management our team’s git repositories for more than two years, and as my daily work using Bitbucket, so I’ll take it as an example.

Here are some settings recommend you to enable.

  1. Set Reject Force Push
  2. Set Branch Prevent deletion
  3. Set tags for each hotfix/GA releases
  4. Merge Check -> Minimum approvals (1)
  5. Yet Another Commit Checker

Reject Force Push

This is the first setting I highly recommend you/your team to open it. if not, when someone using the git push -f command to the git repository, you may lost commits if his local code is old then remote repository.

you have to recover the lost commits manually, I have heard 3 times around me. so enable the hook: Reject Force Push ASAP!

Set Branch Prevent deletion

If some branch is very important, you don’t want to lost it, set Branch Prevent deletion ASAP!

Set tags for each hotfix/GA releases

For each hotfix/GA release, highly recommend create tags after release.

Merge Check

Pull Request is a very good workflow process for each team. in case of commits were merged directly without review, we enable Minimum approvals (1).

So, every branch wants to be merged to the main branch MUST add a reviewer (not allow yourself) and the review must click the Approve button otherwise the merge button is disabled.

Yet Another Commit Checker

This is a very powerful feature. it helps to standardize commit messages and create a branch.

More details about this tool you can refer to this introduction

I have a Chinese article to describe how to use Yet Another Commit Checker implement. if you interest it, you can see the post here

How to open port 22 and make it listening

Recently our Bamboo server has an error when connecting to the Windows build system.

Some errors like: Can not connect to the host XXXX 22 port.

I log into the build machine find port 22 with the below command

1
$ netstat -aon|findstr "22"

but not found port 22 is inbound.

inbound port 22

There’s a lot of articles will tell you how to open ports on Windows. see this one

https://www.windowscentral.com/how-open-port-windows-firewall

But still not works for me

My problem is when I inbound port 22, execute the above command still can’t see the port 22 is listening.

So I install the Win32-OpenSSH, this will lanch two services, then port 22 is listening.

Here are the wiki page about download and installation https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH