Salesforce 开发的 Git 分支策略

Posted by Peter Dong on January 19, 2025

在 Salesforce 开发过程中,制定一套合适的 Git 分支策略对于管理开发流程、快速修复缺陷以及跨环境部署至关重要。一个良好的分支策略不仅支持持续的功能开发,也允许支持团队独立处理紧急问题修复,从而确保生产环境的稳定性和可靠性。本文将介绍一套经过实践检验的 Git 分支策略,该策略能够在保障生产稳定的前提下,实现开发与运维的高效协同。

为什么需要分支策略?

  • 版本控制:有效管理不同版本的代码和元数据配置,确保各环境代码基线清晰可追踪
  • 并行开发:允许多个团队或开发人员同时开发不同功能,互不干扰,提高协作效率
  • 风险控制:通过隔离开发分支和环境,将潜在风险限制在非生产环境,保护生产环境的稳定
  • 发布管理:控制代码部署的节奏和质量,在明确的节奏下发布功能,减少发布风险
  • 变更追踪:清晰记录每次变更,方便审计和问题追溯,快速定位引入问题的版本

下图直观地展示了该 Git 分支策略的流程以及 Salesforce 各环境(Development、QA、UAT、Production)之间的关系:

Feature 开发流程实践

在日常功能开发中,我们可以采用如下分支流程来确保新功能的开发和测试有序进行:

1. Development 分支同步(与 Master 对齐)

在开始新的功能开发之前,首先需要确保本地 development 分支与生产环境主分支(master/main)的代码保持同步。这一步骤确保所有后续开发都基于最新的生产代码进行,避免因代码偏离主干而导致合并冲突或功能回归。

1
2
3
4
# 同步 development 分支
git checkout development
git fetch origin
git rebase origin/master   # 如果主分支名称为 main,则使用 origin/main

注意: 建议养成定期对 development 分支执行 git rebase 的习惯,将 master(或 main)分支的最新更改及时整合进来。换句话说,每当有新代码合并到主分支时,都应尽快在开发分支上执行 rebase,以确保开发分支不落后于生产代码。

2. 创建 Feature 分支

接下来,为即将开发的新功能从 development 分支创建一个独立的功能分支。这样可以将不同功能的开发工作彼此隔离,互不影响。

1
2
3
# 基于 development 分支创建功能分支
git checkout development
git checkout -b feature/CRM-007-implement-batch-process

命名规范: 功能分支命名应清晰且有助于追踪。通常使用 feature/ 作为前缀,后接相关的 JIRA 或工单编号,并简要描述功能内容。名称中使用小写字母和连字符,例如 feature/crm-007-batch-process。一致的命名规范使团队成员一目了然分支所对应的需求或任务。

3. 本地开发与自测

在新建的功能分支上进行开发时,应严格遵循 Salesforce 开发的最佳实践,并在本地做好充分的自测,确保代码质量。以下是一个开发自查清单,可帮助开发人员在提交代码前进行检查:

  • 代码规范:确保 Apex 代码遵循编码规范和风格指南,逻辑清晰可维护
  • 注释完善:为关键逻辑添加必要的注释,方便日后维护和代码审查
  • 单元测试:编写对应的单元测试类,覆盖新功能的主要路径和边界情况
  • 测试覆盖率:确保测试覆盖率达到规定标准(例如 ≥ 75%,建议尽可能达到 85% 或以上)
  • SOQL 优化:检查 SOQL 查询是否进行了有效的过滤和选择,避免不必要的全表扫描
  • 触发器验证:验证触发器的触发时机和逻辑是否正确,避免出现递归或顺序错误
  • 权限检查:审查自定义对象和字段的权限,确保功能在不同安全设置下都能正常运行

通过上述自查清单,可以最大程度降低代码缺陷,确保功能在后续阶段顺利通过测试。

4. 合并回 Development 分支

完成功能分支上的开发和自测后,下一步将功能分支合并回 development 分支,以整合新功能代码。合并时建议使用 --no-ff 参数创建合并提交,这样可以保留完整的分支合并记录,方便日后追踪每个功能的开发过程。

1
2
git checkout development
git merge --no-ff feature/CRM-007-implement-batch-process

合并前请确保以下事项已经完成:

  • 代码审查:至少一位团队成员已对代码进行评审,所有反馈问题都已解决
  • 自动测试:本地所有单元测试均通过,且关键功能已进行手动验证
  • 文档更新:如有需要,相关的技术文档或用户文档已经更新
  • 合并冲突:提前处理并解决与 development 分支的任何合并冲突,确保合并过程顺畅

只有在上述检查项都满足后,再将功能分支合并,以保证 development 分支的代码质量和可用性。

5. 部署到 QA 环境并测试

功能代码合并到 development 分支后,该分支的最新代码将部署到 QA(质量保证)环境 进行集成测试。QA 环境的部署可以通过 CI 流水线自动完成,也可以使用 Salesforce 的部署工具来手动执行。在 QA 环境中,测试人员会针对新功能进行全面的测试,重点关注功能逻辑和系统集成方面的问题。

QA 测试关注点:

  • 功能验证:检查新功能是否完整实现,满足需求描述,并在各种使用场景下都能正确运行
  • 集成测试:验证新功能与现有系统模块以及外部系统的集成是否正常,确保没有破坏其他现有功能
  • 性能测试:针对关键操作进行性能评估,确保新代码未引入明显的性能问题(例如 SOQL 查询的效率、批处理执行时间等)
  • 用户界面测试:如果涉及页面或组件变更,核实界面显示和交互符合预期,用户体验良好
  • 自动化回归:运行自动化测试套件,确保旧有功能没有被本次改动意外影响

通过在 QA 环境的严格测试,我们可以及早发现并修复集成阶段的问题,为后续的发布打下基础。

6. 创建 Release 分支

当 QA 环境的测试通过且新功能基本稳定后,从 development 分支创建一个 Release(发布)分支,用于 UAT 测试和发布前的最后调整。

1
2
git checkout development
git checkout -b release/v1.1.0

Release 分支规范: Release 分支通常以版本号命名,例如 release/v1.1.0。版本号可以采用语义化版本控制(Major.Minor.Patch)的方式。进入 Release 分支后,应严格控制变更范围——只允许进行 BUG 修复细节调整文档完善不再引入新的功能。这一阶段也应维护更新变更日志,清晰记录版本的新增功能和修复列表,方便发布说明和后续追踪。

通过创建 Release 分支,我们将已经过测试的新功能与后续正在开发的功能隔离开来,为最终的生产发布做好准备。

7. 部署到 UAT 环境并用户验收测试

使用 Release 分支的代码包部署到 UAT(用户验收测试)环境,让业务用户进行最终的验收测试。可以使用 SFDX CLI 或 CI 工具将元数据部署到 UAT Sandbox,例如:

1
2
3
# 转换源码为 MDAPI 部署格式并部署到 UAT Sandbox,运行本地测试
sfdx force:source:convert -d deploy_package
sfdx force:mdapi:deploy -d deploy_package -u UATSandbox -l RunLocalTests

UAT 测试清单:

  • 业务流程验证:由业务团队或产品经理验证新功能是否满足业务流程需求,在实际使用场景中表现良好
  • 用户体验评估:收集最终用户对于界面和操作的反馈,确保新功能的用户体验达标
  • 性能验收:在接近生产的数据量和用户操作下进行性能测试,确保系统响应时间和资源消耗在可接受范围内
  • 数据迁移测试:如果发布涉及数据迁移或批量数据处理,在 UAT 环境验证数据迁移的正确性和完整性
  • 集成系统测试:再次验证与外围系统或第三方服务的集成,在仿真的生产环境配置下确保交互正常

通过用户验收测试,可以让最终用户提早体验新功能并确认其符合预期。在此阶段发现的问题应及时在 Release 分支上修复并重新部署进行验证,直至用户认可准备发布。

8. 合并到 Master 并部署生产

当 UAT 测试通过、相关方验收认可后,即可将 Release 分支的代码合并回主分支(master/main),并准备部署到生产环境。

1
2
3
4
5
# 合并 Release 分支到主分支并打标签
git checkout master
git merge --no-ff release/v1.1.0
git tag -a v1.1.0 -m "Release version 1.1.0"
git push origin master --tags   # 推送代码及标签

合并完成后,master/main 分支即代表即将发布的 v1.1.0 版本代码。接下来就可以按照既定的发布流程,将这版代码部署到 Production(生产环境)。部署可以通过 Change Set、CI/CD 流水线或 SFDX 命令来完成。在部署生产时需要注意选择合适的时间窗口,并提前通知相关用户。部署完成后,务必在生产环境再次验证关键功能是否正常运行。

部署提示: 选择业务低峰期进行生产部署,并准备好回滚方案(例如紧急回滚脚本或备份),以防出现不可预见的问题。

至此,完整的功能开发流程结束,新功能已经安全地发布到生产环境。下面介绍当生产环境出现紧急问题时,如何通过 Hotfix 流程进行快速修复。

Hotfix 开发流程实践

即使有完善的预防措施,生产环境难免会出现紧急问题(如严重漏洞或重大功能异常)需要立即修复。为了快速、高效地解决这些生产问题,我们采用与功能开发并行但独立的 Hotfix 分支流程。

为什么需要独立的 Hotfix 流程?

生产环境的问题修复通常具有以下特点:

  • 时效性:必须快速响应和修复,尽量减少对最终用户的影响
  • 隔离性:修复过程不能干扰正在进行的功能开发工作,新功能尚未发布的代码不应混入紧急修复
  • 准确性:聚焦于问题本身,确保修复改动精准,不引入额外风险
  • 质量保障:即使是紧急修复,也需要经过完整的测试验证,保证不会产生新的问题
  • 同步性:生产修复完成后,需要将修复内容同步到其他分支和环境,防止下次发布时问题死灰复燃

基于以上特点,我们将 Hotfix 流程与日常开发分离开来,确保紧急修复既快速又不影响后续正常开发。以下是 Hotfix 流程的具体实践步骤:

1. 准备阶段:Hotfix 分支对齐主分支

首先,确保本地的 hotfix 分支与生产环境当前的主分支代码保持一致。这可以避免修复基于过期代码,从而减少合并冲突和意外问题。

1
2
3
4
# 切换到 Hotfix 分支并同步主分支最新代码
git checkout hotfix
git fetch origin
git rebase origin/master   # 如果主分支名称为 main,则使用 origin/main

Salesforce 特别注意: 在进行 Hotfix 之前,务必要确认生产组织当前的实际代码状态与代码库主分支一致。例如,检查最近一次部署的变更是否都已提交到版本库;了解待修复问题相关组件的元数据最新版本;同时留意生产组织中的自定义设置或配置,这些因素都可能影响修复方案。

2. 创建修复分支

hotfix 分支创建一个专门的 Bugfix 分支 来解决特定的生产问题。这样做可以使每个问题的修复都在独立的分支上进行,彼此互不影响,也方便回溯。

1
2
3
# 基于 hotfix 分支创建问题修复分支
git checkout hotfix
git checkout -b bugfix/CRM-567-resolve-duplicate-contacts

命名规范: 修复分支一般使用 bugfix/hotfix/ 作为前缀。我们常用 bugfix/ 来表示一般缺陷修复,hotfix/ 来表示紧急的线上问题。随后加上对应的工单编号(例如 CRM-567)和简短的问题描述。清晰的命名有助于快速了解修复分支的目的,例如 bugfix/crm-567-duplicate-contacts

3. 开发和本地测试

在修复分支上进行代码修改,修复生产问题。由于生产修复需要极高的准确性,开发者应进行充分的本地测试,确保补丁有效且不会引入新的问题。

测试要求:

  • 单元测试覆盖:新增或修改的代码应编写相应的单元测试,确保覆盖率不低于 85%(Salesforce 部署要求最低 75%,紧急修复更需保证质量)
  • 正反向场景:测试用例需涵盖问题场景的正向(正常情况修复后功能正常)和反向(异常或错误输入情形)两方面,验证修复在各种情况下均有效
  • 边界条件:考虑与问题相关的数据边界或极端情况(例如字段最大长度、空值、多币种等),确保修复代码在边界条件下也能正确处理
  • 回归影响:仔细回归测试与此次修复相关的功能点,确认本次改动未对现有其他功能行为产生副作用

通过严谨的本地测试,可以大幅提升紧急修复的成功率,避免在仓促中引入新的生产问题。

4. 合并回 Hotfix 分支

当确认修复方案有效且通过了充分的本地测试后,将 bugfix 修复分支合并回 hotfix 分支,以整合所有待发布的修复代码。

1
2
git checkout hotfix
git merge --no-ff bugfix/CRM-567-resolve-duplicate-contacts

合并完成后,hotfix 分支将包含最新的修复,并准备进入测试和发布流程。

5. 部署到 UAT 环境验证

尽管是紧急修复,也必须经过严格的测试验证。将 hotfix 分支部署到 UAT 或一个专门的测试环境,重复执行完整的测试流程,确保修复在类生产环境下正常工作。可以使用 SFDX CLI 部署修复包并运行所有测试:

1
2
3
# 将修复分支转换为部署包并部署到 UAT 环境
sfdx force:source:convert -d deploy_package
sfdx force:mdapi:deploy -d deploy_package -u UATSandbox -l RunLocalTests

验证清单:

  • 自动化测试:确认所有本地单元测试和集成测试在 UAT 环境下均通过,特别关注与此次修复相关的测试用例
  • 问题复现验证:在修复部署前可以在 UAT 重现该问题,部署修复后再次操作确认问题已消失,验证修复真正奏效
  • 回归检查:快速回归与此问题相关的功能区域,确保修复未引入新的错误或影响其他模块
  • 性能监控:如果修复涉及性能优化或可能影响系统性能,关注执行时间、CPU 时间等指标,确保一切正常
  • 用户流程验证:从用户角度出发,在 UAT 模拟实际使用场景,确保修复后的流程符合预期,没有遗漏业务上的特殊情况

通过在 UAT 环境的全面验证,我们可以有信心保证该紧急修复在部署到生产时不会出现意外。

6. 合并到主分支

当修复在 UAT 环境中验证通过后,就可以将 hotfix 分支合并回主分支(master/main),使修复成为生产代码库的一部分:

1
2
3
4
git checkout master
git merge --no-ff hotfix
git tag -a v1.2.1 -m "Hotfix: Resolve Duplicate Contacts issue"
git push origin master --tags

此时,主分支上的标签 v1.2.1(假设此次修复版本号为 1.2.1)代表了包含紧急修复的生产就绪版本。接下来将进入正式的生产部署流程。

7. 部署到生产环境

将主分支合并后的代码部署到生产环境。根据团队习惯,可以使用变更集(Change Set)、CI/CD 工具或 SFDX 部署命令来完成。由于生产部署存在风险,需要做好充分准备:

  • 部署窗口:选择一个对业务影响最小的时间段执行部署(例如非高峰业务时段或预定的维护窗口)
  • 备份与回滚:在部署前备份关键数据或元数据,并准备好应急回滚方案,以便在发现严重问题时能够快速恢复旧版本
  • 过程监控:严密监控部署过程的日志和结果,留意是否有测试未通过或部署冲突。如有异常及时停止部署并处理
  • 通知沟通:提前通知相关业务方和支持人员部署计划及内容,部署完成后及时告知用户修复已经生效,并密切关注用户反馈

通过严谨的生产部署流程,可以最大程度降低紧急修复发布的风险,确保生产环境平稳渡过此次变更。

8. 修复同步到开发分支

最后,不要忘记将此次 Hotfix 修复的改动同步回日常开发的 development 分支。这样可以确保后续开发基线中已经包含了该修复,防止旧的代码再次引入同样的问题。

1
2
git checkout development
git merge --no-ff hotfix

完成合并后,建议删除临时的 bugfix 分支(以及视情况删除或重置 hotfix 分支),以保持仓库整洁。至此,Hotfix 流程的工作全部完成,团队可以回到正常的功能开发工作中。

总结

以上这套 Git 分支策略结合了 Git Flow 的经典模型和 Salesforce 平台的特殊需求。在保证生产环境稳定性的同时,实现了功能开发与问题修复的并行、高效进行。通过明确划分 featurereleasehotfix 等不同类型分支,团队各司其职:

  • 开发团队可以在独立的功能分支上安心开发新功能,不必担心影响生产或他人的工作。
  • 支持团队能够快速地在 Hotfix 流程中定位并修复紧急缺陷,修复后的代码又会完整地合并回主线和开发线,确保代码库一致。
  • QA 和业务测试团队则在各自的环境中充分验证代码质量,为每一次发布把好最后的关卡。

通过这套分支策略,Salesforce 开发团队可以高效地开发新功能、快速响应生产问题,并始终保持代码库的稳定可靠。这不仅提高了团队协作效率,也为持续交付和 DevOps 实践打下了坚实基础。


Buy Me a Coffee