版本控制
版本控制是包罗万象的阶段,从最初完成的代码一直到几年后的最终产品补丁,版本控制贯穿始终。即使是大多数新手开发人员也很快开始认识到,对于现代开发来说,版本控制不可或缺。版本控制将跟踪、开发管理、竞赛条件管理以及许多其他功能都变成了代码。
如今,GitHub、GitLab和BitBucket之类的版本控制系统已成为大多数软件生产管道的中枢神经系统,提供集成的持续集成(CI)、文档生成、部署等功能。
将软件生产的不同元素代码化的最大原因之一在于,我们可以将代码放入版本控制,智能地管理。许多组织发现版本控制非常实用,以至于他们经常将版本控制扩展到应有的范围之外。
开发
这个阶段从第一次代码提交到版本控制开始,一直持续到软件步入维护。请注意,计划-开发-部署-收集反馈的周期可能非常迅速(通常理应如此),因此这个阶段的涵盖面非常广,大到整个项目的创建,小到一行代码的变更。
自动化测试
测试是大多数开发工作流程中的关键部分,而测试框架的需求在编程历史的早期就凸显出来了。尽管并非所有类型的测试都需要自动化,而且你也不想为每种可能出现的UI用户流程编写测试,但无疑几乎每个开发团队都采用了自动测试。
通常,单元测试都是由开发团队编写,而且还名列自动化测试的榜单。在代码提交后,集成测试和UI测试通常会与单元测试打包一起运行。有些测试需要在构建之前运行,而有些则在构建之后运行。测试框架提供的自动检查、错误捕获以及代码审查功能在现代软件开发中是必不可少的。
每种编程语言生态系统都有一些自己的测试框架,其中有些利用语言本身来实现“测试即代码”,而有些则使用特定的语法。
流行的Java测试框架包括Jest和Mocha
流行的Java测试框架包括JUnit和Spock
流行的Ruby测试框架包括RSpec和Minitest
流行的浏览器自动测试框架包括Selenium和Cypress
自动化构建与依赖管理
自动化构建的发展已有很长一段历史了,其基本思路是方便开发人员快速掌握构建,并从构建项目版本时面临的一系列繁杂的手动工作中解脱出来,开发人员可以利用工具运行代码编写的检查列表,并自动化构建过程,且不会造成意外遗漏。
在需要构建涉及以下工作的复杂环境时,自动化构建非常具有帮助性:
代码生成
汇编
打包
元数据定制
以及其他
在Java环境中,这可能意味着根据你的配置创建DAO,或生成类映射代码(如JAXB)。
自动化构建还有助于弥补不同环境下的差异——即使通过本地传递,仍然有可能因为缺少依赖项或由于其他原因而导致在生产环境中运行失败。这些自动化构建工具会整理好所有的库以及其他构建部分,提供另一种形式的依赖管理。
开发人员只需运行一个命令,或单击一个按钮即可完成自动构建。在有些情况下,自动化构建甚至会建立一个自动的事件链,开发人员无需执行任何操作,只需提交代码,构建管理器就会自动运行。
大多数主流编程语言都有社区推荐的自动化构建工具:
Java:Node.js + npm + Webpack
Java:Gradle和Maven
Ruby:Rake
C#:MSBuild
C:Make
持续集成/持续交付(CI/CD)
通常,我们用CI/CD来描述包罗万象的工具和实践,随着代码合并到生产的频率越来越高,这些工具和实践将构建、测试和部署自动化的实践整合到一起,每天都要执行很多次。
持续集成是利用CI专用服务器将代码分支频繁合并到应用程序源代码主线版本的实践,如果在合并时发生错误则标记相应的代码。持续交付的概念是指通过一套自动化,将新提交的代码反映到应用程序最新部署的版本中。这种部署工具会自动运行自动化测试、CI、自动化构建以及为应用程序构建新容器等其他部署工作。
如今大多数的CI工具在功能上都超越了CI的范围。开发或发布工程团队可以将构建步骤代码化,甚至将构建的输出作为代码。然后,利用CI/CD配置,针对应用程序的代码进行版本控制和监视。目前最流行的CI平台是Jenkins,Jenkinsfile是它的代码。YAML是这类CI平台上常见的配置语言,虽然有人并不怎么待见它。
最流行的四大CI引擎包括:Jenkins、TravisCI、CircleCI和TeamCity。
运营
在软件生产的各个阶段中,运营阶段是由另一部分人负责的(尽管在小组织中并非如此),而通常这些人具备的技术力与开发人员有所不同。从事运营工作的人员包括系统管理员、运营工程师、开发运维工程师以及其他职位。
这个阶段的工作包括管理和提供运行应用程序所需的物理和虚拟硬件。现如今,许多专业操作人员只需要处理物理计算机之上的抽象。
配置管理
这个类别的工作听起来很宽泛,但是在大多数软件工程界中,配置管理指的是编写各个机器定义的工具。这些工具负责在现有服务器上安装和管理操作系统配置。
主流的四大配置管理工具包括Chef、Puppet、Ansible和Salt。它们是制定IT基础架构管理的首要工具(就像开发人员编写测试、构建、CI实践以及版本控制范围内的那些文件),它们构成了“基础架构即代码”和开发运维运动的首要推动力。
它们的优点在于能够创建不可变的基础架构:这意味着操作人员无需不断更新现有的计算机配置,而是每次只需停止现有的计算机,然后启动新的计算机,并将更新后的模板从配置管理工具移植到新启动的计算机上,因此每次变更都需要重启。这听起来很极端,但是在复杂的IT运营环境中,在添加或更新信息的时候消除潜在的出错可能,这才是更为稳妥的做法。