Is an excellent book by Jez Humble and Dave Farley.
As usual I'm going to quote from a few pages...
Software delivers no value until it is in the hands of its users.
The pattern
that is central to this book is the deployment pipeline.
It should not be possible to make manual
changes to
testing, staging, and production environments.
If releases are frequent,
the delta between releases will be small. This significantly reduces the risk associated
with releasing and makes it much easier to to roll back.
Branching should, in most circumstances, be avoided.
Dashboards should be ubiquitous, and certainly at least one should be
present in each team room.
One of the key principles of the deployment pipeline is that it is a pull
system.
A corollary of having every version of every file in version control is that
it allows you to be aggressive about deleting things that you don't think
you need... The ability to weed out old ideas and implementations frees the
team
to try new things and to
improve the code.
It should always be cheaper to create a new environment than to repair an old one.
The goal of continuous integration is that the software is in a working state all the
time...
Continuous is a practice not a tool...
Continuously is more often than you think.
The most important practice
for continuous integration to work properly is frequent check-ins to trunk or mainline.
Ideally, the compile and test process that you run prior to check-in and on
your CI server should take no more than a few minutes. We think that ten
minutes is about the limit, five minutes is better, and about 90 seconds is
ideal.
Enabling developers to run smoke tests against a working system on a developer
machine prior to each check-in can make a huge difference to the quality of
your application.
Build breakages are a normal and expected part of the process. Our aim is to find
errors and eliminate them as quickly as possible, without expecting perfection and
zero errors.
Having a comprehensive test
suite is essential to continuous integration.
You should also consider refactoring as a cornerstone of effective software
development.