了解分支
构建 Bicep 模板并在 Git 存储库中工作时,团队所做的所有更改最终都会合并到存储库的主分支中。 保护主分支非常重要,以便不会在生产环境中部署不必要的更改。 然而,你也希望你的参与者能够灵活地工作,与你的团队协作,并且能够轻松地尝试各种想法。
在本单元中,你将了解分支策略以及如何保护主分支。 你还将了解如何为分支设置审核过程。
为什么要保护主分支?
主分支是部署到 Azure 环境的事实来源。 对于许多解决方案,你将拥有多种环境,例如开发、质量保证 (QA) 和生产。 在其他情况下,你可能只有一个生产环境。 无论你使用多少个环境,主分支都是你的团队成员所参与的分支。 所做的更改最终都会反馈到主分支上。
一个典型的过程可能如下:
- 团队成员克隆共享存储库。
- 他们在自己的存储库本地副本中的分支上进行本地更改。
- 完成更改后,他们会在其本地存储库的主分支中合并这些更改。
- 他们将这些更改推送到远程存储库的主分支。
- 在某些情况下,远程存储库的推送会触发自动化管道来验证、测试和部署代码。 你将在其他 Microsoft Learn 模块中了解有关管道的详细信息。
以下关系图演示了此过程:
假设团队成员所做的更改引入了一个不明显的 bug。 运行完整个过程后,bug 现在位于项目的主分支中并部署到生产环境。 你可能不会发现它,直到你尝试部署它并得到一个错误。 或者,对于其他类型的 bug,部署可能会成功,但稍后会导致细微的问题。
在另一个场景中,假设某个团队成员正在处理某个功能,并将该功能的一半完成工作推送到共享存储库的主分支。 你现在在主分支上就有了尚未完成或测试的更改。 这些更改可能不会部署到生产环境。 在完成该功能之前,可能需要阻止部署到生产环境。 如果主分支中有新完成的功能,你可能无法将这些功能部署到客户。
提示
这些问题对于大型团队而言尤其困难,因为在大型团队中可能会有多人参与编辑同一代码,但本模块中的指南会在你与多人协作时很有价值。 即使只有你自己在处理一个项目,但同时在处理多个功能,指导也是有价值的。
一种更好的工作方式是在处理更改时将更改分开。 然后,可以让其他团队成员在将任何更改合并到团队共享存储库的主分支之前,对更改进行审核。 这个过程可以帮助你的团队在你批准合并更改之前,对更改做出明智的决策。
功能分支
功能分支表示你正在开始的一项新工作。 此工作可能是对 Bicep 文件中定义的资源的配置更改,或者是需要部署的一组新资源。 每次开始新的工作时,都将创建一个新的功能分支。
从主分支创建功能分支。 创建分支时,可确保从 Azure 环境的当前状态开始。 然后,你需要进行所有必要的更改。
由于所有代码更改都将提交到功能分支,因此它们不会影响存储库的主分支。 如果团队中的其他人需要对主分支进行紧急更改,他们可以在独立于你的功能分支的另一个功能分支上执行此操作。
你也可以在功能分支上进行协作。 通过发布你的功能分支并将其推送到共享存储库,你和你的团队成员可以协作处理更改。 你也可以在度假时将某个功能交给其他人来完成。
更新功能分支
当正在处理功能分支时,其他功能可能会合并到存储库的主分支中。 因此,你的功能分支和项目的主分支将彼此分开。 这两个分支偏离得越远,以后再合并这两个分支就越困难,并且可能会遇到更多合并冲突。
你应定期更新功能分支,这样就可以合并对存储库主分支所做的任何更改。 在开始将功能分支合并回主分支之前先更新功能分支也是一个好主意。 这样一来,你就可以确保新更改可以很容易地被合并到主分支中。
提示
经常将主分支合并到功能分支中。
使用小的、生存期较短的分支
以生存期较短的功能分支为目标。 此方法可减少分支可能不同步的时间,从而帮助你避免合并冲突。此方法还能使同事更轻松地了解你所做的更改,这在需要有人审查你所做的更改时非常有用。
将大块工作拆分成较小的部分,并为每部分创建一个功能分支。 功能的规模越大,需要的处理时间就越长,功能分支的生存时间也就越长。 你可以在合并每个功能分支时将较小的更改部署到生产环境中,并逐步构建更广泛的功能。
想象一下,你正在对一组 Bicep 代码进行一些更改。 你要将一些资源定义移动到模块中。 还需要向 Bicep 文件中添加一些新资源。 最好先在自己的分支上执行所有模块重构。 合并模块后,可以开始处理 Bicep 文件的添加内容。 通过分隔你所做的更改,可以使每个更改及其分支的大小保持较小且易于理解。
以这种方式工作时,最好使用 if
关键字来禁止部署资源,直到资源准备就绪。 下面的示例代码展示了如何使用 if
关键字来创建一个 Bicep 文件以定义存储帐户,但在完成所有更改之前禁用存储帐户的部署。
@description('Specifies whether the storage account is ready to be deployed.')
param storageAccountReady bool = false
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = if (storageAccountReady) {
name: storageAccountName
location: location
kind: 'StorageV2'
sku: {
name: 'Premium_LRS'
}
}
可以使用参数在不同的环境中为 storageAccountReady
变量指定不同的值。 例如,你可以将测试环境的参数值设置为 true
,将生产环境的参数值设置为 false
。 这样,就可以在测试环境中试用新的存储帐户了。
注意
当需要在生产环境中启用该功能时,请记住需要执行以下两个步骤才能使更改生效:
- 更改参数值。
- 重新部署 Bicep 文件。
合并功能分支
完成功能分支的工作后,需要将其合并到存储库的主分支中。 最好在合并前审查在功能分支上所做的更改。 使用拉取请求可以查看代码。 本模块稍后会详细介绍拉取请求。
分支保护
在 GitHub 中,你可以为共享存储库的主分支配置分支保护。 分支保护强制执行如下规则:
- 除非通过拉取请求,否则不能将更改合并到主分支。
- 更改至少需要另外两个人进行审查。
如果有人试图将提交直接推送到受保护的分支,则推送会失败。 你将在下一个单元中了解如何应用分支保护。
分支策略
在 Azure DevOps 中,你可以为共享存储库的主分支配置分支策略。 分支策略强制执行如下规则:
- 除非通过拉取请求,否则不能将更改合并到主分支。
- 更改至少需要另外两个人进行审查。
如果有人试图将提交直接推送到受保护的分支,则推送会失败。 你将在下一个单元中了解如何应用分支策略。
其他分支策略
当你在 Bicep 代码上进行协作时,可以使用各种分支策略。 每个分支策略都有优点和缺点。
到目前为止,你所了解的过程是基于分支的开发策略的一个版本。 在这种分支策略中,工作是在生存期较短的功能分支上完成的,然后合并到一个主分支。 你可以在每次合并更改时自动将共享存储库主分支的内容部署到生产环境,也可以按计划(例如每周)批量处理更改并进行发布。 基于分支的开发易于理解,并且无需很多开销即可实现协作。
有些团队将他们已经完成的工作与部署到生产环境中的工作分开。 他们使用一个较长生存期的开发分支作为合并其功能分支的目标。 他们在将更改发布到生产环境时,将开发分支合并到其主分支中。
其他一些分支策略要求你创建发布分支。 当你有一组可以部署到生产环境的更改时,你可以创建一个发布分支,其中包含要部署的更改。 当你定期部署 Azure 基础结构时,或者当你与许多其他团队集成更改时,这些策略可能会很有帮助。
其他分支策略包括 Gitflow、GitHub Flow 和 GitLab Flow。 一些团队使用 GitHub Flow 或 GitLab Flow,因为它允许不同的团队分离工作,也可以将紧急 bug 修复与其他更改分开。 通过这些过程还可以将提交分离到解决方案的不同版本中,这称为挑拣。 但是,它们需要更多的管理来确保更改彼此兼容。 本模块的“摘要”部分提供了可用于详细了解这些分支实现策略的链接。
适合你团队的分支实现策略取决于团队工作、协作和发布更改的方式。 从一个简单的过程(例如基于分支的开发)开始是个好主意。 如果发现团队无法使用此过程有效工作,请逐步引入其他分支实现层或采用分支实现策略;但请注意,添加更多分支时,管理存储库会变得更加复杂。
提示
无论使用哪种分支实现策略,最好使用分支策略来保护主分支,并使用拉取请求来审查所做更改。 其他分支策略还引入了应保护的重要分支。
在本模块中,我们使用基于分支的开发和功能分支,因为它易于使用。