Release Early, Release Often

Frequent release to stakeholders (e.g. hourly to the team, daily to the company, weekly to customers) provides immediate valuable feedback. Were the assumptions regarding value and requirements correct? If we finish the stories as written, is this project going to succeed or fail? How recently did these new bugs get introduced? What is the most valuable thing to work on next?

Continuous Integration

[Continuous integration] keeps everybody’s code integrated and builds release infrastructure along with the rest of the application. … The point is to be technologically ready to release even if you’re not functionally ready to release.

Source: The Art of Agile Development, Chapter 7: Releasing (Page 183)

Frequent release is only possible with continuous integration. Continuous integration is the process of frequently releasing to the team. If you are able to easily release to the team every few hours, the process behind releasing to stakeholders every few days, or to customers every few weeks should be nearly identical.

Continuous integration provides risk management and project visibility. It also enables incremental design and decision at the last responsible moment.

Unit Tests

Continuous integration only works with a rich set of unit tests. Unit tests allow you to understand whether your code is really ready for release or not. The most efficient way to generate a rich set of unit tests is to write the tests as you write the code. Practice test-driven-development and write the tests before you write the code. The time when you’re working on a story is the time when you have the best context for writing the unit tests. If you write the unit tests much later, you’ve wasted the opportunity to derive immediate value from them (but they cost even more to write later than now, thus their priority diminishes the longer you don’t write them). If you write the tests later, you’ll probably replicate bugs from the code in the tests because you’ll assume the code is correct.

Fix It Now

Continuous integration will undoubtedly uncover some unexpected defects. The more often the code is released and tested, the shorter the time window between introduction and detection of the defect. There is no better time to fix a defect than immediately after it has been introduced, as this is the time when you most likely possess the best context for understanding the root cause of the problem.
If you aren’t going to fix it now, when will you?