我在采用持续交付的组织中和开发团队工作一起工作,发现很多开发者认为的正确的敏捷团队的工作方式,在这里跑得不是很顺畅。我认为传统敏捷与持续交付的矛盾的根本在于,二者是采用不同的方式把软件变得“可以发布“(ready to release)的。

  软件交付的演进

  使软件变得可以发布的过程一直在不停进化,下面是一个简要的介绍:

  瀑布模型

  瀑布模型认为,当一个软件所有的功能都发开完毕的时候(也是功能完整的时候),才可以发布。

  敏捷:

  敏捷引入的思想是,在整个开发过程中,软件都应该“可以发布”。许多敏捷的版本(在这篇文章里被称为传统敏捷)都认为,“可以发布”应该在固定周期的间隔点上完成。

  持续交付:

  持续交付是敏捷的一个子集,在持续交付中团队会保持软件在开发过程的所有时间内都可以发布。它和传统敏捷不同之处在于,持续交付在开发过程中不会有停下来然后创建发布版本的过程。

  持续性交付不是指更短的周期

  从传统的敏捷开发流程变成可持续性交付,不是指把软件发布的周期变短。每天晚上做发布版本仍然不是可持续性交付。可持续性交付是说要把”做可以发布的软件”这个动作本身从开发过程中去掉,取而代之的是保持软件在开发的过程中始终是可以发布的。

  可以发布不是意味着真正的发布

  有一个普遍的误解是可持续性交付是非常频繁地发布出产品。而当一些组织把每天数次发布软件当作是持续交付的标杆时,更加深了这一误解。可持续性交付不是一定要频繁的发布,它只是要求在开发过程中的任何一个点上,用非常少的工作,软件能够发布(可参考Jez Humble的文章,可持续性交付VS可持续性部署)。尽管具备这一能力为更加频繁的发布敞开了大门,但是许多团队还是从持续交付的实践中,找到了压倒性的证据,来证明即便发布不是很频繁时,持续交付也是有用的。

  持续交付和传统敏捷的冲突点

  我前面讲过,有时候持续交付和开发团队所认为是“正确”的敏捷实践流程有一些矛盾。

  冲突点:当有工作没有完成时,软件依然是可发布的

  其中一个冲突点是,一个迭代结束时,代码库中是否可以包含未完成的用户故事(user stories)或者bug修复。我在上一篇关于迭代的帖子中做了探讨。这个问题主要是源于,传统敏捷认为在迭代结束时,team停止开发,并且来做准备软件发布的一些额外工作,但是,如果团队采用持续交付,让软件可发布没什么额外的工作需要做。

  更有甚者,持续交付团队甚至认为,通过使用功能切换等技术,他们的代码即使在还有功能没有完成也可以发布成产品。这也从另外一个方面说明,团队在迭代结束时能够达到可以发布的要求,即使有未完成的用户故事。

  这可能稍微有点难理解,团队肯定还是可以要求在迭代结束点上所有的工作都必须完成,但是这容易让人感觉是团队原有的正常开发的节奏被随便打断了。持续交付不是要求没有时间盒的迭代,这两种实践其实是互补的。

  冲突点:snapshot(软件快照)/发布版本(release build)

  许多开发团队把软件的版本分为“snapshot”版本和“release”版本。这个并不是敏捷所特有的,而是随着Maven的兴起,被深深植入了Java开发中,因为Maven把snapshot的概念放入了它的设计核心中。这种方案把开发周期划分成两个阶段,在软件开发过程中使用snapshot,当软件成为可以发布状态时才创建release版本。

  很明显,这种发布周期的划分和持续交付的“软件应该总是可以发布”的理念是相冲突的。持续交付通常采用的方式是只在开始创建一次版本,然后通过不同阶段的测试验证等一系列串行工作来对版本进行改进,如果使用Maven,要用两种方式创建版本,这种方式不行了。